Code completion invoked at some positions only


I've noticed that the code completion for my plugin doesn't work for some positions.

For example, where the | denotes the cursor, at this position

MOV @symbol,@|

represented by this Psi tree

code completion works fine.  But at this position

MOV @|

with this tree

my Reference.getVariants() method isn't even called, and no suggestions is shown.

What is so fundamentally different in the second case?  Both completions are right after an error due to an incomplete instruction.  ARGS_I is missing in the second case, but in the first case ARGS_I is also incomplete, and in both cases the OP_AT occurs at the top level of the tree.

I guess that IDEA cannot figure out the correct type of the completion and thus doesn't call getVariants().  But what is the crucial difference between the cases? 

Comment actions Permalink

Follow-up question:  While typing a line, the still incomplete line is often flagged as being erroneous. 

Is there a solution, e.g., a grammar pattern, to avoid this behavior?

Comment actions Permalink

Hi Ralph,

  1. Regarding not called getVariants(), the reason might be no existing reference at the cursor position. Make sure it is created when completion is invoked. If it's not the case, then I suggest debugging why getVariants() method is not called in the context of LegacyCompletionContributor. You can see the call stack of getVariants() by invoking the Call Hierarchy action on PsiReference.getVariants() method:
  2. As far as I understand all images present incorrect code fragments, so the error seems reasonable and this is standard behavior in all languages I know. Why would you like to hide errors? If I misunderstood you, please clarify.
Comment actions Permalink

Thanks for your suggestion about LegacyCompletionContributor.

Regarding the code completion, I streamlined the Psi tree in my grammar, but it still doesn't work.  Debugging into LegacyCompletionContributor, the problem seems to be that for the working code completion, findReferenceAt starts at TokenType.IDENT and then walks up the parents, hitting OpLabel next, which does have a reference and a completion.

In the non-working case, findReferenceAt starts at TokenType.IDENT but hits Xas99File immediately, yielding no references.

There not even INSTRUCTION in the Psi tree.

I don't really understand where that OpLabel parent comes from in the first case, as <simple expressions> could be a lot of things.

Pondering the differences between the two cases, I wonder if this grammar rule plays a role,

in particular the pinning, as after the comma, the tree is correct and completion works.  On the other hand, we have this rule

which I believe should apply to the non-working case, but doesn't?!

Am I totally wrong, or should I pin differently?

Regarding the second question: I noticed that Java shows the same behavior as my plugin, so this question is answered.

Comment actions Permalink

Hi Ralph,

Sorry, but I'm a bit lost in the description. You mention OpLabel as an important element in this issue, but I can't see it in any tree screenshot and grammar snippets. Please provide trees screenshots with the corresponding code and more grammar snippets. Try to catch as much of the tree as possible. It'll be much easier to understand what's happening.

Also, a side note that may help you with resolving the issue - please consider using Contributor-Based Completion, which gives more control over the places where completion is invoked. 

Comment actions Permalink

Sorry for the confusion, I rewrote my answer a couple of times as I got new information, and the result is not really clear.

Thanks for the hint about the CompletionContributor, I could make completion work with it.

I think that the Reference contributor didn't work because in the bad case, the Psi tree for that source line lacked its top node, but I couldn't fix the tree in the grammar.


Please sign in to leave a comment.