7 comments

Yann Cebron
Thank you for the reference. I was able to implement the Annotator and it does get hooked, however I'm stuck now with specific logic.

Let's say I have a literal in java code:

"I want 45 to be BLUE and 'text' to be YELLOW"

Given my super simple implementation without any logic:

@Override
public void annotate(@NotNull PsiElement psiElement, @NotNull AnnotationHolder annotationHolder) {
if (psiElement instanceof PsiLiteralExpression) {
annotationHolder.newSilentAnnotation(HighlightSeverity.INFORMATION).textAttributes(NUMBER).create();
}
}

bold is changed color text:

Actual result: "I want 45 to be BLUE and 'text' to be YELLOW" -> whole literal gets colored including double quotes.
Expected result: "I want 45 to be BLUE and 'text' to be YELLOW" -> only number is colored excluding double quotes as well.

I tried to search how can I split PsiLiteralExpression element into expressions by SPACE and exclude double quotes but this doesn't seem possible. Even if it is, the annotate(...) method provides annotation holder for given element and if I get string splitted I need to get annotation holders for each to process separately - how? :)

So the question is, how inside a method I can annotate different parts of a literal excluding quotes?

0

Specify explicit range via com.intellij.lang.annotation.AnnotationBuilder#range(com.intellij.openapi.util.TextRange).

0

Yann Cebron Done, thanks.

now I get almost the desired result but its very bad implemented:

@Override
public void annotate(@NotNull PsiElement psiElement, @NotNull AnnotationHolder annotationHolder) {
if (!(psiElement instanceof PsiLiteralExpression)) {
return;
}
PsiLiteralExpression psiLiteral = (PsiLiteralExpression) psiElement;
try {
PsiMethodCallExpression methodCall = PsiTreeUtil.getParentOfType(psiElement, PsiMethodCallExpression.class);
if (methodCall != null) {
PsiReferenceExpression reference = methodCall.getMethodExpression();
PsiIdentifier identifier = (PsiIdentifier) reference.getLastChild();
if (identifier.getText().equals("translate")) {
PsiMethod method = PsiTreeUtil.getParentOfType(reference, PsiMethod.class);
if (method != null) {
if (method.getName().equals("steps")) {
PsiClass psiClass = method.getContainingClass();
if (psiClass != null) {
if (Arrays.stream(psiClass.getExtendsListTypes()).anyMatch(c -> c.resolve().getQualifiedName().equals("org.testeasy.reflect.SingleScenario"))) {
// do the highlighting
}
}
}
}
}
}
} catch (Exception ignored) {}
}

As you can see I go up by the tree to match my condition. This looks completely rubbish ;(

I just want to apply my highlighting on a literal being a parameter of specific method.

I have Step class with method translate(String literal) and this is the only place for processing.

Is there any easier way to do so?

0

Yann Cebron
Yeah, I looked at this, however it seems to be difficult.
I'd be very grateful if you can help me with writing my "finder"

Conditions:
PsiLiteralExpression should be a parameter of translate(java.lang.String) method call of class org.self.Step anywhere in the project.

0

Done, improved the code, however without pattern matching.

0

Please sign in to leave a comment.