From 1807d294d7164448414f0dda72f89e28da2c9aad Mon Sep 17 00:00:00 2001 From: peter Date: Tue, 21 Oct 2014 19:16:15 +0200 Subject: [PATCH] psi->document sync when doc is gc-ed (IDEA-131067) --- .../testSrc/com/intellij/psi/MiscPsiTest.java | 20 +++++++++++++++++++ .../intellij/pom/core/impl/PomModelImpl.java | 7 +++++-- .../psi/impl/PsiToDocumentSynchronizer.java | 4 +--- 3 files changed, 26 insertions(+), 5 deletions(-) diff --git a/java/java-tests/testSrc/com/intellij/psi/MiscPsiTest.java b/java/java-tests/testSrc/com/intellij/psi/MiscPsiTest.java index 2ed8233e99fe..7c078165d31b 100644 --- a/java/java-tests/testSrc/com/intellij/psi/MiscPsiTest.java +++ b/java/java-tests/testSrc/com/intellij/psi/MiscPsiTest.java @@ -23,6 +23,7 @@ import com.intellij.openapi.roots.LanguageLevelProjectExtension; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.pom.java.LanguageLevel; +import com.intellij.psi.impl.source.PostprocessReformattingAspect; import com.intellij.psi.impl.source.tree.LazyParseableElement; import com.intellij.testFramework.PlatformTestUtil; import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase; @@ -297,4 +298,23 @@ public class MiscPsiTest extends LightCodeInsightFixtureTestCase { assertFalse(leaf.isValid()); assertNotSame(leaf, file.findElementAt(5)); } + + public void testPsiModificationsWithNoDocumentDocument() { + final PsiJavaFile file = (PsiJavaFile)myFixture.addFileToProject("a.java", "class A{}"); + + PsiClass aClass = file.getClasses()[0]; + aClass.getNode(); + assertNotNull(PsiDocumentManager.getInstance(getProject()).getCachedDocument(file)); + + PlatformTestUtil.tryGcSoftlyReachableObjects(); + assertNull(PsiDocumentManager.getInstance(getProject()).getCachedDocument(file)); + + aClass.add(JavaPsiFacade.getElementFactory(getProject()).createMethodFromText("void foo(){}", null)); + assertNotNull(PsiDocumentManager.getInstance(getProject()).getCachedDocument(file)); + + PostprocessReformattingAspect.getInstance(getProject()).doPostponedFormatting(); + + assertTrue(file.getText(), file.getText().contains("foo() {\n")); + + } } diff --git a/platform/core-impl/src/com/intellij/pom/core/impl/PomModelImpl.java b/platform/core-impl/src/com/intellij/pom/core/impl/PomModelImpl.java index 727d0fe22a2e..2a17f7832a70 100644 --- a/platform/core-impl/src/com/intellij/pom/core/impl/PomModelImpl.java +++ b/platform/core-impl/src/com/intellij/pom/core/impl/PomModelImpl.java @@ -300,7 +300,8 @@ public class PomModelImpl extends UserDataHolderBase implements PomModel { LOG.assertTrue(changeScope != null); final PsiFile containingFileByTree = getContainingFileByTree(changeScope); - if (changeScope.isPhysical() && synchronizer.toProcessPsiEvent() && isDocumentUncommitted(containingFileByTree)) { + boolean physical = changeScope.isPhysical(); + if (physical && synchronizer.toProcessPsiEvent() && isDocumentUncommitted(containingFileByTree)) { // fail-fast to prevent any psi modifications that would cause psi/document text mismatch // PsiToDocumentSynchronizer assertions happen inside event processing and are logged by PsiManagerImpl.fireEvent instead of being rethrown // so it's important to throw something outside event processing @@ -308,7 +309,9 @@ public class PomModelImpl extends UserDataHolderBase implements PomModel { } BlockSupportImpl.sendBeforeChildrenChangeEvent((PsiManagerImpl)PsiManager.getInstance(myProject), changeScope, true); - Document document = containingFileByTree == null ? null : manager.getCachedDocument(containingFileByTree); + Document document = containingFileByTree == null ? null : + physical ? manager.getDocument(containingFileByTree) : + manager.getCachedDocument(containingFileByTree); if(document != null) { synchronizer.startTransaction(myProject, document, changeScope); } diff --git a/platform/core-impl/src/com/intellij/psi/impl/PsiToDocumentSynchronizer.java b/platform/core-impl/src/com/intellij/psi/impl/PsiToDocumentSynchronizer.java index 60bae75fbe23..560b6a78ab35 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/PsiToDocumentSynchronizer.java +++ b/platform/core-impl/src/com/intellij/psi/impl/PsiToDocumentSynchronizer.java @@ -74,9 +74,7 @@ public class PsiToDocumentSynchronizer extends PsiTreeChangeAdapter { final PsiFile psiFile = event.getFile(); if (psiFile == null || psiFile.getNode() == null) return; - boolean forceDocument = !psiFile.getViewProvider().isPhysical(); - final Document document = forceDocument ? myPsiDocumentManager.getDocument(psiFile) - : myPsiDocumentManager.getCachedDocument(psiFile); + final Document document = myPsiDocumentManager.getCachedDocument(psiFile); if (document != null && myPsiDocumentManager.isUncommited(document)) { throw new IllegalStateException("Attempt to modify PSI for non-committed Document!"); }