mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
diagnose invalid stub-based PsiAnchor (IDEA-100526, IDEA-100962)
This commit is contained in:
@@ -58,7 +58,7 @@ class AnchorElementInfo extends SelfElementInfo {
|
||||
if (stubId != -1) {
|
||||
PsiFile file = SelfElementInfo.restoreFileFromVirtual(getVirtualFile(), myProject);
|
||||
if (!(file instanceof PsiFileWithStubSupport)) return null;
|
||||
return PsiAnchor.restoreFromStubIndex((PsiFileWithStubSupport)file, stubId, myStubElementType);
|
||||
return PsiAnchor.restoreFromStubIndex((PsiFileWithStubSupport)file, stubId, myStubElementType, false);
|
||||
}
|
||||
if (!mySyncMarkerIsValid) return null;
|
||||
PsiFile file = SelfElementInfo.restoreFileFromVirtual(getVirtualFile(), myProject);
|
||||
|
||||
@@ -327,8 +327,11 @@ public abstract class PsiAnchor {
|
||||
@Nullable
|
||||
public static PsiElement restoreFromStubIndex(PsiFileWithStubSupport fileImpl,
|
||||
int index,
|
||||
@NotNull IStubElementType elementType) {
|
||||
if (fileImpl == null) return null;
|
||||
@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;
|
||||
@@ -338,26 +341,36 @@ public abstract class PsiAnchor {
|
||||
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()) return null;
|
||||
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) return null;
|
||||
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);
|
||||
return ast != null ? ast.getPsi() : null;
|
||||
}
|
||||
else {
|
||||
return stub.getPsi();
|
||||
if (ast != null) {
|
||||
return ast.getPsi();
|
||||
}
|
||||
|
||||
if (throwIfNull) throw new AssertionError("No AST for stub");
|
||||
return null;
|
||||
}
|
||||
return stub.getPsi();
|
||||
}
|
||||
|
||||
public static class StubIndexReference extends PsiAnchor {
|
||||
@@ -396,11 +409,26 @@ public abstract class PsiAnchor {
|
||||
return ApplicationManager.getApplication().runReadAction(new NullableComputable<PsiElement>() {
|
||||
@Override
|
||||
public PsiElement compute() {
|
||||
return restoreFromStubIndex((PsiFileWithStubSupport)getFile(), myIndex, myElementType);
|
||||
return restoreFromStubIndex((PsiFileWithStubSupport)getFile(), myIndex, myElementType, false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public String diagnoseNull() {
|
||||
try {
|
||||
PsiElement element = ApplicationManager.getApplication().runReadAction(new NullableComputable<PsiElement>() {
|
||||
@Override
|
||||
public PsiElement compute() {
|
||||
return restoreFromStubIndex((PsiFileWithStubSupport)getFile(), myIndex, myElementType, true);
|
||||
}
|
||||
});
|
||||
return "No diagnostics, element=" + element + "@" + (element == null ? 0 : System.identityHashCode(element));
|
||||
}
|
||||
catch (AssertionError e) {
|
||||
return e.getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (this == o) return true;
|
||||
|
||||
Reference in New Issue
Block a user