Search code examples
intellij-plugingrammar-kit

Method injection in GrammarKit plugin does not work


I am trying to override the getReference() method in some of my PsiElements by making methods in the PsiImplUtil class, but no methods get injected. Below is the element which needs the method (ValidNameExpr). I'm sure I'm just making a tiny mistake somewhere, but I don't see why this shouldn't work. I tried making the method non-static but that didn't help either. Could you please help if you know what might be wrong?

// This is a generated file. Not intended for manual editing.
package lang.psi.impl;

public class JMMValidNameExprImpl extends ASTWrapperPsiElement implements JMMValidNameExpr {

  public JMMValidNameExprImpl(@NotNull ASTNode node) {
    super(node);
  }

  public void accept(@NotNull JMMVisitor visitor) {
    visitor.visitValidNameExpr(this);
  }

  public void accept(@NotNull PsiElementVisitor visitor) {
    if (visitor instanceof JMMVisitor) accept((JMMVisitor)visitor);
    else super.accept(visitor);
  }

  @Override
  @NotNull
  public PsiElement getValidName() {
    return findNotNullChildByType(VALID_NAME);
  }

}

This is the util class with the implementation of the method

package lang.psi;

public class JMMPsiImplUtil {

    public static PsiReference getReference(IReference ref) {
        return RefUtil.makeRef(expr, expr.getTextRangeInParent());
    }
    //more stuff here... (there are no other methods named getReference, just in case that is a problem)

And this is my .BNF file

{
    ...

    psiImplUtilClass = "lang.psi.JMMPsiImplUtil"

    ...
}
...
validNameExpr ::= VALID_NAME {extends=expr implements="lang.psi.IReference" methods=[getReference]}

More stuff...

Solution

  • as far as I know, the first argument of an utility method MUST have a type of the PSI element you're going to add it for:

    public static PsiReference getReference(JMMValidNameExpr expr, IReference ref)

    and it will then be injected as

    PsiReference getReference(IReference ref) {
      return JMMPsiImplUtil.getReference(this, ref);
    }
    

    or something like that. this is because those methods are static, and you might want to use many such methods for different types, so the first argument is used to distinguish them. NB: I am not sure it will work for "over-riding" methods, however you might give it a try.