diff --git a/java/java-impl/src/com/intellij/psi/impl/smartPointers/AnchorElementInfo.java b/java/java-impl/src/com/intellij/psi/impl/smartPointers/AnchorElementInfo.java index b54a18f42467..1594b3b3674e 100644 --- a/java/java-impl/src/com/intellij/psi/impl/smartPointers/AnchorElementInfo.java +++ b/java/java-impl/src/com/intellij/psi/impl/smartPointers/AnchorElementInfo.java @@ -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); diff --git a/platform/lang-impl/src/com/intellij/psi/PsiAnchor.java b/platform/lang-impl/src/com/intellij/psi/PsiAnchor.java index c50727ee7fa2..f104591310b7 100644 --- a/platform/lang-impl/src/com/intellij/psi/PsiAnchor.java +++ b/platform/lang-impl/src/com/intellij/psi/PsiAnchor.java @@ -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> 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() { @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() { + @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;