How do I access INJECTION of a PsiField's initializer, which is a PsiLanguageInjectionHost?

What I have done:

  1. I defined my own language "MyLanguage"
  2. I need to inject this language to both annotations' values and fields' initializers, so I defined a com.intellij.lang.injection.MultiHostInjector for the language and I got all these fancy features, like, autocompletion, syntax highlighting, parser errors, etc. These features are available in both annotations' values and fields' initializers.
  3. I defined a com.intellij.codeInspection.LocalInspectionTool to be able to add some inspections to the language

What the problems are:

  1. When I open the PSI Viewer, I can only see the "INJECTION" node for annotations

    but no "INJECTION" node is presented for fields' initializers
  2. When I try to use PsiTreeUtil in my LocalInspectionTool to find a child of the PsiLanguageInjectionHost type it returns null for fields and a non-null value for annotations
    PsiTreeUtil.findChildOfType(annotation, PsiLanguageInjectionHost.class)

QUESTION:

Why can't I access the "INJECTION" node of a field even though IDEA seems to inject the language into its initializer (autocompletion, highlighting, error reporting work)?

My MultiHostInjector:

public void getLanguagesToInject(MultiHostRegistrar registrar, PsiElement context) {
if (annotationOfInterest(context)) {
PsiAnnotationMemberValue valueAttr = PsiTreeUtil.findChildOfType(context, PsiAnnotationMemberValue.class);

if (!(valueAttr instanceof PsiLiteralExpression)) return;

inject(registrar, (PsiLiteralExpression) valueAttr);
} else if (fieldOfInterest(context)) {
final PsiField psiField = (PsiField) context;
final PsiExpression initializer = psiField.getInitializer();

if (!(initializer instanceof PsiLiteralExpression)) return;

inject(registrar, (PsiLiteralExpression) initializer)
}
}

private void inject(MultiHostRegistrar registrar, PsiLiteralExpression valueAttr) {
registrar.startInjecting(MyLanguage.INSTANCE);
registrar.addPlace("", "", (PsiLanguageInjectionHost) valueAttr, new TextRange(1, valueAttr.getTextLength() - 1));
registrar.doneInjecting();
}
0
1 comment

I have come up with the following solution:

PsiExpression initializer = field.getInitializer(); 
PsiElement element = InjectedLanguageManager.getInstance(field.getProject()).findInjectedElementAt(field.getContainingFile(), initializer.getTextOffset() + 1);

but it feels like there has to be a unified way to handle injected languages regardless of the host element's type

0

Please sign in to leave a comment.