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
请先登录再写评论。
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.
Hi Dmitry,
I was referring to the java-doc of the PsiReferenceContributor here which says:
But I will happily switch back to returning the reference through getReference().
Thanks again
Patrick
These are instructions for users of getReferences(), not for the implementers.
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.
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....