diff --git a/platform/core-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java b/platform/core-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java index d36d802a8008..93faaab938dd 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java +++ b/platform/core-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java @@ -186,15 +186,32 @@ public abstract class PsiFileImpl extends ElementBase implements PsiFileEx, PsiF FileElement treeElement = createFileElement(viewProvider.getContents()); treeElement.setPsi(this); - final StubTree stub = derefStub(); - List> bindings = calcStubAstBindings(treeElement, cachedDocument, stub); + while (true) { + StubTree stub = derefStub(); + List> bindings = calcStubAstBindings(treeElement, cachedDocument, stub); + FileElement savedTree = ensureTreeElement(viewProvider, treeElement, stub, bindings); + if (savedTree != null) { + return savedTree; + } + } + } + + @Nullable + private FileElement ensureTreeElement(@NotNull FileViewProvider viewProvider, + @NotNull FileElement treeElement, + @Nullable StubTree stub, + @NotNull List> bindings) { synchronized (PsiLock.LOCK) { FileElement existing = derefTreeElement(); if (existing != null) { return existing; } + if (stub != derefStub()) { + return null; // stub has been just loaded by another thread, it needs to be bound to AST + } + if (stub != null) { treeElement.putUserData(STUB_TREE_IN_PARSED_TREE, new SoftReference(stub)); putUserData(ObjectStubTree.LAST_STUB_TREE_HASH, stub.hashCode());