@Override protected String stubTreeAndIndexDoNotMatch( StubTree stubTree, PsiFileWithStubSupport psiFile, List<StubElement<?>> plained, VirtualFile virtualFile, StubTree stubTreeFromIndex) { String details = "Please report the problem to JetBrains with the file attached"; details += "\npsiFile" + psiFile; details += "\npsiFile.class" + psiFile.getClass(); details += "\npsiFile.lang" + psiFile.getLanguage(); String fileText = psiFile instanceof PsiCompiledElement ? "compiled" : psiFile.getText(); return LogMessageEx.createEvent( "PSI and index do not match", details, new Attachment( virtualFile != null ? virtualFile.getPath() + "_file.txt" : "vFile.txt", fileText), new Attachment("stubTree.txt", ((PsiFileStubImpl) stubTree.getRoot()).printTree()), new Attachment( "stubTreeFromIndex.txt", stubTreeFromIndex == null ? "null" : ((PsiFileStubImpl) stubTreeFromIndex.getRoot()).printTree())) .toString(); }
@Nullable public static PsiElement restoreFromStubIndex( PsiFileWithStubSupport fileImpl, int index, @NotNull IStubElementType elementType, boolean throwIfNull) { if (fileImpl == null) { if (throwIfNull) throw new AssertionError("Null file"); return null; } StubTree tree = fileImpl.getStubTree(); boolean foreign = tree == null; if (foreign) { if (fileImpl instanceof PsiFileImpl) { // Note: as far as this is a realization of StubIndexReference // fileImpl#getContentElementType() must be instance of IStubFileElementType tree = ((PsiFileImpl) fileImpl).calcStubTree(); } else { if (throwIfNull) throw new AssertionError("Not PsiFileImpl: " + fileImpl.getClass()); return null; } } List<StubElement<?>> list = tree.getPlainList(); if (index >= list.size()) { if (throwIfNull) throw new AssertionError("Too large index: " + index + ">=" + list.size()); return null; } StubElement stub = list.get(index); if (stub.getStubType() != elementType) { if (throwIfNull) throw new AssertionError( "Element type mismatch: " + stub.getStubType() + "!=" + elementType); return null; } if (foreign) { final PsiElement cachedPsi = ((StubBase) stub).getCachedPsi(); if (cachedPsi != null) return cachedPsi; final ASTNode ast = fileImpl.findTreeForStub(tree, stub); if (ast != null) { return ast.getPsi(); } if (throwIfNull) throw new AssertionError("No AST for stub"); return null; } return stub.getPsi(); }
// will restore by stub index until file tree get loaded AnchorElementInfo( @NotNull PsiElement anchor, @NotNull PsiFileWithStubSupport containingFile, int stubId, @NotNull IStubElementType stubElementType) { super( containingFile.getProject(), new ProperTextRange(0, 0), anchor.getClass(), containingFile, containingFile.getLanguage()); myStubElementTypeAndId = pack(stubId, stubElementType); assert !(anchor instanceof PsiFile) : "FileElementInfo must be used for file: " + anchor; }