getVariants() is not called

For our Mathematica Plug-in (open-source on GitHub) we finally wanted to tackle reference resolving. We have only one class which can act as reference: the implementation of the Symbol interface.
I adapted the example of the SimpleLanguage tutorial and made Symbol an extension to PsiNameIdentifierOwner, created a SymbolPsiReference extending PsiReferenceBase<Symbol> and implementing PsiPolyVariantReference and registered this in the plugin.xml.
Currently, the getVariants() method does nothing more than collecting all Symbols in the sourcefile. The problem is, it is never called and I suspect it is because my understanding of the psi-tree is flawed. Simple example:

As you can see the Symbol node wraps another PsiElement(IDENTIFIER). I initially wanted to make Symbol to be a psi-leaf because this represents the situation better but I was unable to do so. When I now type code, then


is invoked but the CompletionParameters contain PsiElement(IDENTIFIER) as myPosition and not the Symbol node.

Is this the problem and if yes, how can I fix it.

Many thanks


Comment actions Permalink

Hi Patrick,

I'm not sure why your getVariants() is not called, your code looks good to me. The PSI structure you have is correct, I believe all tokens in the file get a LeafPsiElement and then your PSI elements are built on top of them. I just checked in my plugin and my symbols also appear with a leaf element under them in PsiViewer.


Comment actions Permalink

You have a range mismatch. The TextRange that is passed to PsiReferenceBase constructor is the range within the element. You're passing to it the value of PsiElement.getTextRange(), which is the range within the containing file.

Patrick Scheibe
Comment actions Permalink

Thanks Dmitry for pointing this out. Very odd was, that in com.intellij.codeInsight.completion.impl.CompletionServiceImpl#createResultSet the correct prefix to my variable was calculated, although I passed the absolute textrange.

@Dmitry, @Colin: Thanks again for looking over the code and pointing out that I haven't done something really messy. After another debugging session I found the error and it was completely unrelated. For the static list of keywords in Mathematica, I have created a CompletionContributor which worked nicely. Since all built-in function in Mathematica start with a capital letter, I wanted to make this completion stop when the identifier is lowercase. So what did I do in MathematicaFunctionCompletion? Instead of only returning I called

    if (Character.isLowerCase(parameters.getPosition().getText().charAt(0))) {

Unfortunately result.stopHere() means that the iteration over all completion contributors are stoped as can be seen in com.intellij.codeInsight.completion.CompletionService#getVariantsFromContributors:

for (int i = contributors.indexOf(from) + 1; i < contributors.size(); i++) {
      final CompletionContributor contributor = contributors.get(i);
      if (dumb && !DumbService.isDumbAware(contributor)) continue;

      final CompletionResultSet result = createResultSet(parameters, consumer, contributor);
      contributor.fillCompletionVariants(parameters, result);
      if (result.isStopped()) {


Please sign in to leave a comment.