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

@Override
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 {
  @Override
  public void registerReferenceProviders(PsiReferenceRegistrar registrar) {
    registrar.registerReferenceProvider(PlatformPatterns.psiElement(Symbol.class),
      new PsiReferenceProvider() {
        @NotNull
        @Override
        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.

Thanks
Patrick

0

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.

0
Avatar
Permanently deleted user

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
Patrick

0

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

0

The "Custom Language SupportTutorial" (https://www.jetbrains.org/intellij/sdk/docs/tutorials/custom_language_support/reference_contributor.html) speaks of the ReferenceContributor approach, which I have not been able to get to work. But the PsiElement.getReference() is at least being called when I just tried that out of desperation. I suggest that the Tutorial is updated.

1

I agree, it is very confusing.

At the beginning of step 9 it says:

1. "Custom languages provide code completion using one of two approaches: Contributor and Reference-based completion. The Simple Language plugin implements the less complex of the two methods, reference completion."

But then it goes ahead to implement both approaches, one at step 9 and the other at step 10. Or am I wrong?

 

2. Another source of confusion is the wording:

"two approaches:  Contributor and Reference-based completion.". It implies the terms:

Contributor completion vs Reference-based completion.  Yet the following 2 steps are titled

Completion Contributor vs Reference Contributor

 

3. The PsiElement.getReference() is not documented in the tutorial. Dmitry Jemenov gave the same suggestion that he gave to this thread to another thread as well (https://intellij-support.jetbrains.com/hc/en-us/community/posts/206110789-Issue-with-Reference-Contributor), but wouldnt it be nice to give us an example in the tutorial too? :) Please give it a look, I have to say that I dont know how to proceed....

 

 

0

请先登录再写评论。