mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
invalidate stub-based psi on stub replacement
This commit is contained in:
@@ -17,7 +17,9 @@ package com.intellij.psi
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.psi.impl.source.PsiFileImpl
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase
|
||||
import com.intellij.reference.SoftReference
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
@@ -30,13 +32,29 @@ class StubAstSwitchTest extends LightCodeInsightFixtureTestCase {
|
||||
def cls = ((PsiJavaFile)file).classes[0]
|
||||
assert file.stub
|
||||
|
||||
def oldCount = psiManager.modificationTracker.javaStructureModificationCount
|
||||
|
||||
ApplicationManager.application.runWriteAction { file.virtualFile.setBinaryContent(file.virtualFile.contentsToByteArray()) }
|
||||
assert file.stub
|
||||
|
||||
//todo
|
||||
//either: assert !cls.valid
|
||||
//or: assert cls == PsiTreeUtil.findElementOfClassAtOffset(file, 1, PsiClass, false)
|
||||
//assert !file.stub
|
||||
assert psiManager.modificationTracker.javaStructureModificationCount != oldCount
|
||||
|
||||
assert !cls.valid
|
||||
assert cls != PsiTreeUtil.findElementOfClassAtOffset(file, 1, PsiClass, false)
|
||||
assert !file.stub
|
||||
}
|
||||
|
||||
public void "test reachable psi classes remain valid when nothing changes"() {
|
||||
int count = 1000
|
||||
List<SoftReference<PsiClass>> classList = (0..<count).collect { new SoftReference(myFixture.addClass("class Foo$it {}")) }
|
||||
System.gc()
|
||||
System.gc()
|
||||
System.gc()
|
||||
assert classList.every {
|
||||
def cls = it.get()
|
||||
if (!cls || cls.valid) return true
|
||||
cls.text //load AST
|
||||
return cls.valid
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -154,11 +154,11 @@ public class StubBasedPsiElementBase<T extends StubElement> extends ASTDelegateP
|
||||
public boolean isValid() {
|
||||
T stub = myStub;
|
||||
if (stub != null) {
|
||||
if (stub instanceof PsiFileStub) {
|
||||
return stub.getPsi().isValid();
|
||||
PsiElement parentPsi = stub.getParentStub().getPsi();
|
||||
if (parentPsi instanceof PsiFileImpl) {
|
||||
return ((PsiFileImpl) parentPsi).isStubBasedChildValid(this);
|
||||
}
|
||||
|
||||
return stub.getParentStub().getPsi().isValid();
|
||||
return parentPsi.isValid();
|
||||
}
|
||||
|
||||
return super.isValid();
|
||||
|
||||
@@ -249,6 +249,20 @@ public abstract class PsiFileImpl extends ElementBase implements PsiFileEx, PsiF
|
||||
return findTreeForStub(ast, stubs, stub);
|
||||
}
|
||||
|
||||
public boolean isStubBasedChildValid(@NotNull StubBasedPsiElementBase psi) {
|
||||
StubElement fileStub = getStub();
|
||||
if (fileStub != null) {
|
||||
synchronized (myStubLock) {
|
||||
fileStub = getStub();
|
||||
StubElement childStub = psi.getStub();
|
||||
if (fileStub != null && childStub != null && fileStub != childStub.getParentStub()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return isValid();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static ASTNode findTreeForStub(ASTNode tree, final Iterator<StubElement<?>> stubs, final StubElement stub) {
|
||||
final IElementType type = tree.getElementType();
|
||||
|
||||
Reference in New Issue
Block a user