mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
PsiFileImpl: fix race condition between AST and stub loading, which resulted in stub elements being not bound to AST
This commit is contained in:
@@ -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<Pair<StubBasedPsiElementBase, CompositeElement>> bindings = calcStubAstBindings(treeElement, cachedDocument, stub);
|
||||
while (true) {
|
||||
StubTree stub = derefStub();
|
||||
List<Pair<StubBasedPsiElementBase, CompositeElement>> 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<Pair<StubBasedPsiElementBase, CompositeElement>> 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<StubTree>(stub));
|
||||
putUserData(ObjectStubTree.LAST_STUB_TREE_HASH, stub.hashCode());
|
||||
|
||||
Reference in New Issue
Block a user