"PSI and index do not match" after switching to another git branch

I am developing the propriatory plugin which provides support for Robot framework.
In IDEA CE 14.0.3 after switching to another git branch multiple "PSI and index do not match" errors occur when accessing stub indices. Restarting IDEA fixes the problem until next git switch. Index is being accessed in a smart mode (errors occur after reindexing). I disabled PsiListener and DocumentListener in my plugin to make sure that they won't cause these errors (however their handlers were read-only). Error information is below. Stub index in this particular case is quite simple (see the code below). I tried to insert forceRebuild call before index access but it didn't help. Any ideas on how to fix this or any information related to this problem would be helpful!


public class RobotTestCaseNormalizedNameIndex extends StringStubIndexExtension<RobotTestCase> {
    public static final StubIndexKey<String, RobotTestCase> KEY = StubIndexKey.createIndexKey("Robot.keyword.normalizedTestCaseName");

    @NotNull
    @Override
    public
StubIndexKey<String, RobotTestCase> getKey() {
        return KEY;
    }
}

public interface RobotTestCaseStub extends NamedStub<RobotTestCase> {
}

public class RobotTestCaseStubImpl extends StubBase<RobotTestCase> implements RobotTestCaseStub {
    private StringRef name;

    public RobotTestCaseStubImpl(final StubElement parent, final IStubElementType elementType, StringRef name) {
        super(parent, elementType);
        this.name = name;
    }

    @Nullable
    @Override
    public
String getName() {
        return name == null ? null : name.getString();
    }
}

public class RobotTestCaseElementType extends IStubElementType<RobotTestCaseStub, RobotTestCase> {
...
    @Override
    public void
indexStub(@NotNull RobotTestCaseStub stub, @NotNull IndexSink sink) {
    final String name = stub.getName();
    if (name != null) {
        final String normalizedName = RobotPsiUtil.normalizeKeywordForIndex(name);
        sink.occurrence(RobotTestCaseNormalizedNameIndex.KEY, normalizedName);
    }
}

}


PSI and index do not match
Please report the problem to JetBrains with the file attached
psiFileFILE
psiFile.classclass com.altisource.roboteditor.psi.impl.RobotPsiFile
psiFile.langLanguage: Robot
java.lang.Throwable
    at com.intellij.psi.impl.DebugUtil.currentStackTrace(DebugUtil.java:497)
    at com.intellij.psi.stubs.StubProcessingHelper.stubTreeAndIndexDoNotMatch(StubProcessingHelper.java:44)
    at com.intellij.psi.stubs.StubProcessingHelperBase.inconsistencyDetected(StubProcessingHelperBase.java:154)
    at com.intellij.psi.stubs.StubProcessingHelperBase.processStubsInFile(StubProcessingHelperBase.java:144)
    at com.intellij.psi.stubs.StubProcessingHelperBase.processStubsInFile(StubProcessingHelperBase.java:40)
    at com.intellij.psi.stubs.StubIndexImpl$2.perform(StubIndexImpl.java:273)
    at com.intellij.psi.stubs.StubIndexImpl$2.perform(StubIndexImpl.java:264)
    at com.intellij.util.indexing.ValueContainer.forEach(ValueContainer.java:81)
    at com.intellij.psi.stubs.StubIndexImpl.processElements(StubIndexImpl.java:264)
    at com.intellij.psi.stubs.StubIndexImpl.processElements(StubIndexImpl.java:237)
    at com.altisource.roboteditor.elements.search.RobotPsiUtil.countTestCases(RobotPsiUtil.java:153)
    at com.altisource.roboteditor.keyword_explorer.KeywordExplorerToolWindow$5.run(KeywordExplorerToolWindow.java:282)
    at com.intellij.openapi.project.DumbService$2.compute(DumbService.java:119)
    at com.intellij.openapi.project.DumbService$2.compute(DumbService.java:113)
    at com.intellij.openapi.application.impl.ApplicationImpl.runReadAction(ApplicationImpl.java:931)
    at com.intellij.openapi.project.DumbService.runReadActionInSmartMode(DumbService.java:113)
    at com.altisource.roboteditor.keyword_explorer.collector.AbstractKeywordsCollector$1.run(AbstractKeywordsCollector.java:221)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
    at java.util.concurrent.FutureTask.run(FutureTask.java:262)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)

Stub trees are in attachment. They are different.



Attachment(s):
stubTree.txt.zip
stubTreeFromIndex.txt.zip
0
4 comments

More info on this: The index mentioned in the previous post is accessed in the treeview selection handler. It contains names of robot testcases. I tried to create a very simple .robot file with one testcase. Then I modified it outside of the IDEA - removed this testcase. Index is OK. Then I added this testcase back, also outside of the IDEA. Now there is PsiInvalidElementAccessException:

      at com.intellij.psi.util.PsiUtilCore.ensureValid(PsiUtilCore.java:480)
      at com.intellij.psi.stubs.StubProcessingHelperBase.processStubsInFile(StubProcessingHelperBase.java:142)
      at com.intellij.psi.stubs.StubProcessingHelperBase.processStubsInFile(StubProcessingHelperBase.java:40)
      at com.intellij.psi.stubs.StubIndexImpl$2.perform(StubIndexImpl.java:273)
      at com.intellij.psi.stubs.StubIndexImpl$2.perform(StubIndexImpl.java:264)
      at com.intellij.util.indexing.ValueContainer.forEach(ValueContainer.java:81)
      at com.intellij.psi.stubs.StubIndexImpl.processElements(StubIndexImpl.java:264)
      at com.intellij.psi.stubs.StubIndexImpl.processElements(StubIndexImpl.java:237)
      at com.altisource.roboteditor.elements.search.RobotPsiUtil.countTestCases(RobotPsiUtil.java:152)
...

0

Forgot to mention. In the use case mentioned in previous posts index is queried with the scope narrowed down to one file:

fileScope((PsiFile) psiElement)


the code which access index looks like this:

final StubIndex STUB_INDEX = StubIndex.getInstance();
Collection<String> keys = STUB_INDEX.getAllKeys(RobotTestCaseNormalizedNameIndex.KEY, project);
for (String key : keys) {
    STUB_INDEX.processElements(RobotTestCaseNormalizedNameIndex.KEY, key, project,
            scope, RobotTestCase.class, processor);
}
0

More info. While debugging, I can see that in the following code

public StubTree calcStubTree() {
  FileElement fileElement = calcTreeElement();
  synchronized (myStubFromTreeLock) {
    SoftReference<StubTree> ref = fileElement.getUserData(STUB_TREE_IN_PARSED_TREE);
    StubTree tree = SoftReference.dereference(ref);

fileElement contains up-to-date data, but tree, which is obtained from

STUB_TREE_IN_PARSED_TREE)

has stale data. Why?

0

Ok, the problem is solved. There were multiple overridden subtreeChanged methods in PSI impl without

super.subtreeChanged();

calls. This is why stub tree was not cleared properly.

0

Please sign in to leave a comment.