StubIndex created, but not used

Answered

Hello,

I'm seeking help with StubIndex of Language plugin that I'm having troubles with.

Index is created and even filled:

I've registered a StubElement interface as 'stubClass' attribute inside bnf grammar, registered StringStubIndexExtension for it into plugin.xml and changed plugin's FileType to IStubFileElement.

As a result I can even see stored values inside index with IndexViewer plugin for GdClassNamingImpl:

This seems ok, problem is that I'm unable to get that Stub back.
I've prepared a method for getting ClassName() which should use value stored inside that index

fun getClassname(element: GdClassNaming?): String {
val stub = element?.stub;
if (stub != null) {
return stub.name();
}

return element?.classNameNm?.name.toString();
}


Method is registered inside bnf grammar as: {methods=[getClassname]}

Which is also ok and it gets called, but problem is that element.stub is always null and never filled.

 

Stub object is created using incoming PsiElement:

override fun createStub(psi: GdClassNaming, parentStub: StubElement<*>?): GdClassNamingStub {
return GdClassNamingStubImpl(parentStub, psi.classNameNm?.name)
}

Generated class implementation is also correctly extending StubBasedPsiElement as follows:

public class GdClassNamingImpl extends StubBasedPsiElementBase<GdClassNamingStub> implements GdClassNaming {}

Can someone help me with where to look why those stubs even though created are not actually paired with PsiElement and not used?

In case source code is:
https://gitlab.com/IceExplosive/gdscript/-/tree/master

Code for this StubIndex is all under kotlin folder.

Thank you for any help and your time,
David Horacek

5 comments
Comment actions Permalink

Please verify javadoc com.intellij.extapi.psi.StubBasedPsiElementBase#getStub . Does it apply in your use case?

1
Comment actions Permalink

Thank you, that wasn't called. I've had StubElement, but not StubBasedPsiElement so I've added extends StubBasedPsiElementBase to implementation and now StubBasedPsiElementBase#getStub() method is called.

Problem now is that this falls into

com.intellij.psi.impl.source.SubstrateRef#getStub()

where lies an implementation:

@Nullable
public Stub getStub() {
return null;
}

So calling element?.stub on the element still results in null.

Do I have to somehow override this method? Or am I still missing some extension?

0
Comment actions Permalink

No, you don't have to worry about that method.

From Javadoc I mentioned in com.intellij.extapi.psi.StubBasedPsiElementBase#getStub, please verify whether these conditions apply in your specific use-case and switch to use getGreenStub().

Note: for most clients (where the logic doesn't crucially differ for stub and AST cases), {@link #getGreenStub()} should be preferred.
* @return the stub that this element is built upon, or null if the element is currently AST-based. The latter can happen
* if the file text was loaded from the very beginning, or if it was loaded via {@link #getNode()} on this or any other element
* in the containing file.
0
Comment actions Permalink

I'm actually more confused by that doc.

From "null if the element is currently AST-based" I understand that I won't get a stub on an element on which the method was called from IDE (like a node on which I triggered CompletionContributor).

So I'd expect that Stub would be loaded when I list all project files and find Stubbed elements inside them, something like:

var vFiles = FileTypeIndex.getFiles(GdFileType.INSTANCE, GlobalSearchScope.allScope(project));
for (VirtualFile vf : virtualFiles) {
var myFile = (GdFile) PsiManager.getInstance(project).findFile(vf);
var prop = (GdClassNamingImpl) PsiTreeUtil.findChildOfType(myFile, GdClassNamingImpl.class);
}

But to me that seems to contradict the part: "returns null... if the file text was loaded from the very beginning"

 

Also getGreenStub only falls into getStub, which returns null:

public Stub getStub() {
return null;
}

public Stub getGreenStub() {
return getStub();
}
0
Comment actions Permalink

Seems I've finally found the last missing piece today:

Before calling

PsiTreeUtil.findChildOfType(file, ...)

to get desired elements I've had to first call

file.getStubTree()

Now I'm finally getting some stub elements instead of full AST nodes.

0

Please sign in to leave a comment.