PsiChangeHandler: don't track ranges forever for events outside pom transactions (e.g. reload on language level change) (EA-76926 - PIEAE: PsiUtilCore.ensureValid)

This commit is contained in:
peter
2016-04-21 21:38:09 +02:00
parent 6dc4502000
commit 7edaae6c76
2 changed files with 31 additions and 5 deletions
@@ -120,10 +120,7 @@ import com.intellij.testFramework.*;
import com.intellij.testFramework.fixtures.impl.CodeInsightTestFixtureImpl;
import com.intellij.ui.HintListener;
import com.intellij.ui.LightweightHint;
import com.intellij.util.ArrayUtil;
import com.intellij.util.ExceptionUtil;
import com.intellij.util.ReflectionUtil;
import com.intellij.util.TimeoutUtil;
import com.intellij.util.*;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.io.storage.HeavyProcessLatch;
import com.intellij.util.ui.UIUtil;
@@ -2280,5 +2277,27 @@ public class DaemonRespondToChangesTest extends DaemonAnalyzerTestCase {
EditorFactory.getInstance().releaseEditor(myEditor);
}
}
public void testFileReload() throws Exception {
VirtualFile file = createFile("a.java", "").getVirtualFile();
Document document = getDocument(file);
assertNotNull(document);
FileStatusMap fileStatusMap = myDaemonCodeAnalyzer.getFileStatusMap();
WriteCommandAction.runWriteCommandAction(getProject(), () -> {
PlatformTestUtil.tryGcSoftlyReachableObjects();
assertNull(PsiDocumentManager.getInstance(getProject()).getCachedPsiFile(document));
document.insertString(0, "class X { void foo() {}}");
assertEquals(TextRange.from(0, document.getTextLength()), fileStatusMap.getFileDirtyScope(document, Pass.UPDATE_ALL));
FileContentUtilCore.reparseFiles(file);
assertEquals(TextRange.from(0, document.getTextLength()), fileStatusMap.getFileDirtyScope(document, Pass.UPDATE_ALL));
findClass("X").getMethods()[0].delete();
assertEquals(TextRange.from(0, document.getTextLength()), fileStatusMap.getFileDirtyScope(document, Pass.UPDATE_ALL));
});
}
}
@@ -203,8 +203,15 @@ class PsiChangeHandler extends PsiTreeChangeAdapter implements Disposable {
}
if (!child.isValid()) return;
Document document = PsiDocumentManager.getInstance(myProject).getCachedDocument(file);
PsiDocumentManagerImpl pdm = (PsiDocumentManagerImpl)PsiDocumentManager.getInstance(myProject);
Document document = pdm.getCachedDocument(file);
if (document != null) {
if (pdm.getSynchronizer().getTransaction(document) == null) {
myFileStatusMap.markAllFilesDirty(child);
return;
}
List<Pair<PsiElement, Boolean>> toUpdate = changedElements.get(document);
if (toUpdate == null) {
toUpdate = new SmartList<>();