When using ANTLR (antlr4-intellij-adaptor) for grammar definition, how to define multi-level ElementPattern in CompletionContributor?

I’m using ANTLR (antlr4-intellij-adaptor) for syntax definition.

As shown in the figure below, this is the content of the file when “Ctrl - Space” is pressed. The two red colors are the error messages attached by Annotator, which will not affect the Psi structure.

As you can see, the immediate parent of Identifier is DTOQualifiedNamePart, the tertiary parent is DTOTypeRef, and the quaternary is DTOUserProp

I add breakpoints in fillCompletionVariants and test the ElementPattern in the ‘Alt - F8’ popup window

My problem is that only withSuperParent(1) seems to match my structure correctly, which is reflected in the above image (withParent = withSuperParent(1)), where the expression executes as true

Once any of the comments are released, the ElementPattern test fails, returning false, as shown below

But at the same time, the boolean expression I additionally executed returned ture, indicating that my actual structure is consistent with the ElementPattern

Why is this? There’s no way I can just rely on a single level of judgment to complete the code hint, it’s not realistic… Any solutions?

Still don’t know why, but I found the trouble spot, here:

At the first parent, the logic here is normal, it will go to if and then return element.getParent();, so the first hierarchy could return

But on the second parent, the logic at the pink box returns false, return element.getContext(); null, so the chain of ElementPatterns is broken

So for now, here’s the solution I found:

Inherit PsiElementPattern, implement my own net.fallingangel.jimmerdto.completion.pattern.LsiPattern#getParent, and then, at the point of use, replace net.fallingangel.jimmerdto.Completion.pattern.LsiPatternKt#lsiElement() instead of com.intellij.patterns.PlatformPatterns#psiElement.

But I’m still curious, (PsiFile) element should just fail the conversion with an exception, how come it’s just false?

@yann.cebron, hi there! Can you help me analyze why?

Know why. When using Antlr, the Psi element no longer inherits directly from ASTWrapperPsiElement, but from ANTLRPsiNode, which overrides getContext

And in org.antlr.intellij.adaptor.SymtabUtils#getContextFor, the parent is identified as ScopeNode

So in com.intellij.patterns.PsiElementPattern#getParent, element.getContext() returns null…

So I need to implement ScopeNode for all parent structures so that I don’t need to touch PsiElementPattern… This is also a solution