PsiElement.getReference() vs. PsiReferenceContributor

I read the comment in com.intellij.psi.PsiReferenceContributor which said that registering such a reference contributor should be preferred to returning the same through PsiElement.getReference().
Although the latter worked fine, I thought of switching to the newer scheme. What I had was

public PsiReference getReference() {
  return new SymbolPsiReference(this);

in my implementation class for Mathematica variables which is called SymbolImpl. My first try of implementing a ReferenceContributor looked like

public class MathematicaReferenceContributor extends PsiReferenceContributor {
  public void registerReferenceProviders(PsiReferenceRegistrar registrar) {
      new PsiReferenceProvider() {
        public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNull ProcessingContext context) {
          if (element instanceof Symbol) {
            return new PsiReference[]{new SymbolPsiReference((Symbol) element)};
          return new PsiReference[0];
        }}); }}

but I'm doing something wrong. I assume the pattern is not correct but I'm unable to understand why (btw Symbol is the interface to SymbolImpl). The contributor is registered in the plugin.xml as

<psi.referenceContributor language="Mathematica" implementation="de.halirutan.mathematica.MathematicaReferenceContributor"/>

Does someone see an obvious error? Are there serious advantages of registering a contributor instead of just returning the reference from getReference() because honestly, none of the other plugins I'm using to steal ideas is implementing a contributor.


Comment actions Permalink

Actually the comment in PsiReferenceContributor never says that. The actual situation is the opposite: PsiReferenceContributor is supposed to be used for injecting references into languages that you don't control (Java, XML etc.), or if you want other people to be able to inject references into your language. If you're developing a custom language plugin, implementing getReferences() directly is a more concise and more efficient approach.

Patrick Scheibe
Comment actions Permalink

Hi Dmitry,

I was referring to the java-doc of the PsiReferenceContributor here which says:

The contributed references may then be obtained via PsiReferenceService.getReferences(PsiElement, PsiReferenceService.Hints), which is the preferred way. Some elements return them from PsiElement.getReferences() directly though, but one should not rely on that behavior since it may be changed in the future. The alternative way to register PsiReferenceProvider is by using PsiReferenceProviderBean.

But I will happily switch back to returning the reference through getReference().

Thanks again

Comment actions Permalink

These are instructions for users of getReferences(), not for the implementers.


Please sign in to leave a comment.