mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
more diagnostics on stub-ast mismatch
This commit is contained in:
@@ -176,6 +176,7 @@ public class StubBasedPsiElementBase<T extends StubElement> extends ASTDelegateP
|
||||
if (psi != null) {
|
||||
return psi;
|
||||
}
|
||||
ApplicationManager.getApplication().assertReadAccessAllowed();
|
||||
synchronized (PsiLock.LOCK) {
|
||||
if (myStub != null) {
|
||||
throw new PsiInvalidElementAccessException(this, "no psi for file stub " + stub, null);
|
||||
|
||||
@@ -472,7 +472,7 @@ public class SingleRootFileViewProvider extends UserDataHolderBase implements Fi
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getClass().getSimpleName() + "{myVirtualFile=" + myVirtualFile + '}';
|
||||
return getClass().getSimpleName() + "{myVirtualFile=" + myVirtualFile + ", content=" + getContent() + '}';
|
||||
}
|
||||
|
||||
private interface Content {
|
||||
|
||||
@@ -35,7 +35,6 @@ import com.intellij.openapi.ui.Queryable;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.VirtualFileWithId;
|
||||
import com.intellij.psi.*;
|
||||
@@ -260,23 +259,15 @@ public abstract class PsiFileImpl extends ElementBase implements PsiFileEx, PsiF
|
||||
}
|
||||
|
||||
private List<Pair<StubBasedPsiElementBase, CompositeElement>> calcStubAstBindings(final ASTNode root) {
|
||||
StubTree stubTree = derefStub();
|
||||
final StubTree stubTree = derefStub();
|
||||
if (stubTree == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
final Iterator<StubElement<?>> stubs = stubTree.getPlainList().iterator();
|
||||
stubs.next(); // Skip file stub;
|
||||
final IElementType contentElementType = getContentElementType();
|
||||
if (!(contentElementType instanceof IStubFileElementType)) {
|
||||
final VirtualFile vFile = getVirtualFile();
|
||||
throw new AssertionError("A stub in a non-stub file '" + vFile + "'; isValid()=" + (vFile != null ? vFile.isValid() : "null") +
|
||||
" type: " + contentElementType + "; content:<<<\n" +
|
||||
StringUtil.first(getViewProvider().getContents(), 200, true) +
|
||||
"\n>>>; stubs=" + ContainerUtil.collect(stubs));
|
||||
}
|
||||
final List<Pair<StubBasedPsiElementBase, CompositeElement>> result = ContainerUtil.newArrayList();
|
||||
final StubBuilder builder = ((IStubFileElementType)contentElementType).getBuilder();
|
||||
final StubBuilder builder = ((IStubFileElementType)getContentElementType()).getBuilder();
|
||||
|
||||
((TreeElement)root).acceptTree(new RecursiveTreeElementWalkingVisitor() {
|
||||
@Override
|
||||
@@ -290,16 +281,13 @@ public abstract class PsiFileImpl extends ElementBase implements PsiFileEx, PsiF
|
||||
IElementType type = node.getElementType();
|
||||
if (type instanceof IStubElementType && ((IStubElementType)type).shouldCreateStub(node)) {
|
||||
if (!stubs.hasNext()) {
|
||||
rebuildStub();
|
||||
throw new AssertionError("Stub list in " + getName() + " has fewer elements than PSI. Last AST element: " +
|
||||
node.getElementType() + " " + node);
|
||||
reportStubAstMismatch("Stub list is less than AST, last AST element: " + node.getElementType() + " " + node, stubTree);
|
||||
}
|
||||
|
||||
final StubElement stub = stubs.next();
|
||||
if (stub.getStubType() != node.getElementType()) {
|
||||
rebuildStub();
|
||||
throw new AssertionError("Stub and PSI element type mismatch in " + getName() + ": stub " + stub + ", AST " +
|
||||
node.getElementType() + "; " + node);
|
||||
reportStubAstMismatch("Stub and PSI element type mismatch in " + getName() + ": stub " + stub + ", AST " +
|
||||
node.getElementType() + "; " + node, stubTree);
|
||||
}
|
||||
|
||||
PsiElement psi = stub.getPsi();
|
||||
@@ -310,9 +298,37 @@ public abstract class PsiFileImpl extends ElementBase implements PsiFileEx, PsiF
|
||||
super.visitNode(node);
|
||||
}
|
||||
});
|
||||
if (stubs.hasNext()) {
|
||||
reportStubAstMismatch("Stub list in " + getName() + " has more elements than PSI", stubTree);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private void reportStubAstMismatch(String message, StubTree stubTree) {
|
||||
rebuildStub();
|
||||
String msg = message;
|
||||
msg += "\n file=" + this;
|
||||
msg += "\n name=" + getName();
|
||||
msg += "\n stub debugInfo=" + stubTree.getDebugInfo();
|
||||
|
||||
FileViewProvider viewProvider = getViewProvider();
|
||||
msg += "\n viewProvider=" + viewProvider;
|
||||
msg += "\n viewProvider stamp: " + viewProvider.getModificationStamp();
|
||||
|
||||
VirtualFile file = viewProvider.getVirtualFile();
|
||||
msg += "; file stamp: " + file.getModificationStamp();
|
||||
msg += "; file modCount: " + file.getModificationCount();
|
||||
|
||||
Document document = FileDocumentManager.getInstance().getCachedDocument(file);
|
||||
if (document != null) {
|
||||
msg += "\n doc saved: " + !FileDocumentManager.getInstance().isDocumentUnsaved(document);
|
||||
msg += "; doc stamp: " + document.getModificationStamp();
|
||||
msg += "; committed: " + PsiDocumentManager.getInstance(getProject()).isCommitted(document);
|
||||
}
|
||||
|
||||
throw new AssertionError(msg);
|
||||
}
|
||||
|
||||
protected FileElement createFileElement(final CharSequence docText) {
|
||||
final FileElement treeElement;
|
||||
final TreeElement contentLeaf = createContentLeafElement(docText);
|
||||
@@ -649,6 +665,8 @@ public abstract class PsiFileImpl extends ElementBase implements PsiFileEx, PsiF
|
||||
if (derefd != null) return derefd;
|
||||
if (getTreeElement() != null) return null;
|
||||
|
||||
if (!(getContentElementType() instanceof IStubFileElementType)) return null;
|
||||
|
||||
final VirtualFile vFile = getVirtualFile();
|
||||
if (!(vFile instanceof VirtualFileWithId)) return null;
|
||||
|
||||
@@ -656,19 +674,6 @@ public abstract class PsiFileImpl extends ElementBase implements PsiFileEx, PsiF
|
||||
if (!(tree instanceof StubTree)) return null;
|
||||
StubTree stubHolder = (StubTree)tree;
|
||||
|
||||
final IElementType contentElementType = getContentElementType();
|
||||
if (!(contentElementType instanceof IStubFileElementType)) {
|
||||
final FileViewProvider viewProvider = getViewProvider();
|
||||
throw new AssertionError("A stub in a non-stub file '" + vFile +"'; isValid()=" + vFile.isValid() +
|
||||
"; IndexStamp="+ StubTreeLoader.getInstance().getStubTreeTimestamp(vFile) +
|
||||
"; Type: " + contentElementType + "; " +
|
||||
"Psi roots: " + viewProvider.getAllFiles() + "; " +
|
||||
" StubUpdatingIndex.canHaveStub(vFile)=" + StubTreeLoader.getInstance().canHaveStub(vFile) +
|
||||
" content:<<<\n"+
|
||||
StringUtil.first(viewProvider.getContents(),200,true)+
|
||||
"\n>>>; stubs=" + stubHolder.getPlainList());
|
||||
}
|
||||
|
||||
synchronized (PsiLock.LOCK) {
|
||||
if (getTreeElement() != null) return null;
|
||||
|
||||
@@ -965,6 +970,7 @@ public abstract class PsiFileImpl extends ElementBase implements PsiFileEx, PsiF
|
||||
|
||||
StubElement currentStubTree = ((IStubFileElementType)contentElementType).getBuilder().buildStubTree(this);
|
||||
tree = new StubTree((PsiFileStub)currentStubTree);
|
||||
tree.setDebugInfo("created in calcStubTree");
|
||||
try {
|
||||
TreeUtil.bindStubsToTree(this, tree);
|
||||
}
|
||||
|
||||
@@ -30,9 +30,9 @@ import java.util.Map;
|
||||
* Date: 8/3/12
|
||||
*/
|
||||
public class ObjectStubTree<T extends Stub> {
|
||||
|
||||
protected static final Key<ObjectStubTree> STUB_TO_TREE_REFERENCE = Key.create("stub to tree reference");
|
||||
private static final Key<ObjectStubTree> STUB_TO_TREE_REFERENCE = Key.create("stub to tree reference");
|
||||
protected final ObjectStubBase myRoot;
|
||||
private String myDebugInfo;
|
||||
protected final List<T> myPlainList = new ArrayList<T>();
|
||||
|
||||
public ObjectStubTree(@NotNull final ObjectStubBase root, final boolean withBackReference) {
|
||||
@@ -73,6 +73,19 @@ public class ObjectStubTree<T extends Stub> {
|
||||
}
|
||||
}
|
||||
|
||||
public void setDebugInfo(String info) {
|
||||
ObjectStubTree ref = myRoot.getUserData(STUB_TO_TREE_REFERENCE);
|
||||
if (ref != null) {
|
||||
assert ref == this;
|
||||
info += "; with backReference";
|
||||
}
|
||||
myDebugInfo = info;
|
||||
}
|
||||
|
||||
public String getDebugInfo() {
|
||||
return myDebugInfo;
|
||||
}
|
||||
|
||||
private static class StubIndexSink implements IndexSink, TObjectProcedure<Map<Object, int[]>>,TObjectObjectProcedure<Object,int[]> {
|
||||
private final THashMap<StubIndexKey, Map<Object, int[]>> myResult = new THashMap<StubIndexKey, Map<Object, int[]>>();
|
||||
private int myStubIdx;
|
||||
|
||||
@@ -437,7 +437,7 @@ public class StubIndexImpl extends StubIndex implements ApplicationComponent, Pe
|
||||
msg += "; file stamp: " + file.getModificationStamp();
|
||||
msg += "; file modCount: " + file.getModificationCount();
|
||||
|
||||
Document document = FileDocumentManager.getInstance().getDocument(file);
|
||||
Document document = FileDocumentManager.getInstance().getCachedDocument(file);
|
||||
if (document != null) {
|
||||
msg += "\nsaved: " + !FileDocumentManager.getInstance().isDocumentUnsaved(document);
|
||||
msg += "; doc stamp: " + document.getModificationStamp();
|
||||
|
||||
@@ -70,7 +70,9 @@ public class StubTreeLoaderImpl extends StubTreeLoader {
|
||||
}
|
||||
}
|
||||
if (element instanceof PsiFileStub) {
|
||||
return new StubTree((PsiFileStub)element);
|
||||
StubTree tree = new StubTree((PsiFileStub)element);
|
||||
tree.setDebugInfo("created from file content, timestamp=" + vFile.getTimeStamp());
|
||||
return tree;
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
@@ -104,7 +106,9 @@ public class StubTreeLoaderImpl extends StubTreeLoader {
|
||||
catch (SerializerNotFoundException e) {
|
||||
return processError(vFile, "No stub serializer: " + vFile.getPresentableUrl() + ": " + e.getMessage(), e);
|
||||
}
|
||||
return stub instanceof PsiFileStub ? new StubTree((PsiFileStub)stub) : new ObjectStubTree((ObjectStubBase)stub, true);
|
||||
ObjectStubTree tree = stub instanceof PsiFileStub ? new StubTree((PsiFileStub)stub) : new ObjectStubTree((ObjectStubBase)stub, true);
|
||||
tree.setDebugInfo("created from index, index creation stamp=" + IndexInfrastructure.getIndexCreationStamp(StubUpdatingIndex.INDEX_ID) + "; index stamp=" + IndexingStamp.getIndexStamp(vFile, StubUpdatingIndex.INDEX_ID));
|
||||
return tree;
|
||||
}
|
||||
else if (size != 0) {
|
||||
return processError(vFile, "Twin stubs: " + vFile.getPresentableUrl() + " has " + size + " stub versions. Should only have one. id=" + id,
|
||||
|
||||
Reference in New Issue
Block a user