From 2ff73e2b6e3f82fa29d696c20c4837e8b23a8b00 Mon Sep 17 00:00:00 2001 From: peter Date: Fri, 18 Jul 2014 15:38:28 +0200 Subject: [PATCH] don't recreate code fragment psi (IDEA-127039) --- .../com/intellij/psi/CodeFragmentsTest.java | 15 +++++++++++++++ .../psi/impl/file/impl/FileManagerImpl.java | 19 ++++++++++++++----- .../impl/FileDocumentManagerImpl.java | 8 ++++++-- .../psi/PsiDocumentManagerImplTest.java | 4 ++-- .../intellij/usages/impl/UsageViewTest.java | 10 +++++----- 5 files changed, 42 insertions(+), 14 deletions(-) diff --git a/java/java-tests/testSrc/com/intellij/psi/CodeFragmentsTest.java b/java/java-tests/testSrc/com/intellij/psi/CodeFragmentsTest.java index 8f6956808dea..dd0611f53175 100644 --- a/java/java-tests/testSrc/com/intellij/psi/CodeFragmentsTest.java +++ b/java/java-tests/testSrc/com/intellij/psi/CodeFragmentsTest.java @@ -1,6 +1,10 @@ package com.intellij.psi; import com.intellij.openapi.editor.Document; +import com.intellij.openapi.roots.ex.ProjectRootManagerEx; +import com.intellij.openapi.util.EmptyRunnable; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.testFramework.LightVirtualFile; import com.intellij.testFramework.PlatformTestCase; import com.intellij.testFramework.PlatformTestUtil; import com.intellij.testFramework.PsiTestCase; @@ -30,4 +34,15 @@ public class CodeFragmentsTest extends PsiTestCase{ PlatformTestUtil.tryGcSoftlyReachableObjects(); assertEquals("ab", PsiDocumentManager.getInstance(myProject).getDocument(fragment).getText()); } + + public void testDontRecreateFragmentPsi() { + PsiExpressionCodeFragment fragment = JavaCodeFragmentFactory.getInstance(myProject).createExpressionCodeFragment("a", null, null, true); + VirtualFile file = fragment.getViewProvider().getVirtualFile(); + assertInstanceOf(file, LightVirtualFile.class); + + ProjectRootManagerEx.getInstanceEx(getProject()).makeRootsChange(EmptyRunnable.getInstance(), false, true); + + assertSame(fragment, PsiManager.getInstance(myProject).findFile(file)); + assertTrue(fragment.isValid()); + } } diff --git a/platform/core-impl/src/com/intellij/psi/impl/file/impl/FileManagerImpl.java b/platform/core-impl/src/com/intellij/psi/impl/file/impl/FileManagerImpl.java index cadaf980f9cb..7b4e9ec210ac 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/file/impl/FileManagerImpl.java +++ b/platform/core-impl/src/com/intellij/psi/impl/file/impl/FileManagerImpl.java @@ -32,6 +32,7 @@ import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.FileIndexFacade; import com.intellij.openapi.util.Disposer; +import com.intellij.openapi.util.Key; import com.intellij.openapi.util.LowMemoryWatcher; import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.vfs.VfsUtilCore; @@ -57,6 +58,7 @@ import java.util.concurrent.ConcurrentMap; public class FileManagerImpl implements FileManager { private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.file.impl.FileManagerImpl"); + private final Key myPsiHardRefKey = Key.create("HARD_REFERENCE_TO_PSI"); //non-static! private final PsiManagerImpl myManager; private final FileIndexFacade myFileIndex; @@ -168,7 +170,7 @@ public class FileManagerImpl implements FileManager { @NotNull public FileViewProvider findViewProvider(@NotNull final VirtualFile file) { assert !file.isDirectory(); - FileViewProvider viewProvider = getFromInjected(file); + FileViewProvider viewProvider = findCachedViewProvider(file); if (viewProvider != null) return viewProvider; viewProvider = myVFileToViewProviderMap.get(file); if(viewProvider == null) { @@ -180,8 +182,9 @@ public class FileManagerImpl implements FileManager { @Override public FileViewProvider findCachedViewProvider(@NotNull final VirtualFile file) { FileViewProvider viewProvider = getFromInjected(file); - if (viewProvider != null) return viewProvider; - return myVFileToViewProviderMap.get(file); + if (viewProvider == null) viewProvider = myVFileToViewProviderMap.get(file); + if (viewProvider == null) viewProvider = file.getUserData(myPsiHardRefKey); + return viewProvider; } @Nullable @@ -216,9 +219,14 @@ public class FileManagerImpl implements FileManager { if (document != null) { PsiDocumentManagerBase.cachePsi(document, null); } + virtualFile.putUserData(myPsiHardRefKey, null); } else { - myVFileToViewProviderMap.put(virtualFile, fileViewProvider); + if (virtualFile instanceof LightVirtualFile) { + virtualFile.putUserData(myPsiHardRefKey, fileViewProvider); + } else { + myVFileToViewProviderMap.put(virtualFile, fileViewProvider); + } } } } @@ -437,7 +445,8 @@ public class FileManagerImpl implements FileManager { @Nullable PsiFile getCachedPsiFileInner(@NotNull VirtualFile file) { - final FileViewProvider fileViewProvider = myVFileToViewProviderMap.get(file); + FileViewProvider fileViewProvider = myVFileToViewProviderMap.get(file); + if (fileViewProvider == null) fileViewProvider = file.getUserData(myPsiHardRefKey); return fileViewProvider instanceof SingleRootFileViewProvider ? ((SingleRootFileViewProvider)fileViewProvider).getCachedPsi(fileViewProvider.getBaseLanguage()) : null; } diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileDocumentManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileDocumentManagerImpl.java index 5def1e1fc161..f396b1eed399 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileDocumentManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileDocumentManagerImpl.java @@ -173,8 +173,12 @@ public class FileDocumentManagerImpl extends FileDocumentManager implements Virt document.setModificationStamp(file.getModificationStamp()); final FileType fileType = file.getFileType(); document.setReadOnly(!file.isWritable() || fileType.isBinary()); - myDocuments.put(file, document); - document.putUserData(FILE_KEY, file); + if (file instanceof LightVirtualFile) { + registerDocument(document, file); + } else { + myDocuments.put(file, document); + document.putUserData(FILE_KEY, file); + } if (!(file instanceof LightVirtualFile || file.getFileSystem() instanceof DummyFileSystem)) { document.addDocumentListener( diff --git a/platform/platform-tests/testSrc/com/intellij/psi/PsiDocumentManagerImplTest.java b/platform/platform-tests/testSrc/com/intellij/psi/PsiDocumentManagerImplTest.java index 718ee8ebe5f7..2ab0446e86a4 100644 --- a/platform/platform-tests/testSrc/com/intellij/psi/PsiDocumentManagerImplTest.java +++ b/platform/platform-tests/testSrc/com/intellij/psi/PsiDocumentManagerImplTest.java @@ -75,7 +75,7 @@ public class PsiDocumentManagerImplTest extends PlatformLangTestCase { } public void testDocumentGced() throws Exception { - VirtualFile vFile = createFile(); + VirtualFile vFile = getVirtualFile(createTempFile("txt", "abc")); PsiDocumentManagerImpl documentManager = getPsiDocumentManager(); long id = System.identityHashCode(documentManager.getDocument(getPsiManager().findFile(vFile))); @@ -93,7 +93,7 @@ public class PsiDocumentManagerImplTest extends PlatformLangTestCase { }); //Class.forName("com.intellij.util.ProfilingUtil").getDeclaredMethod("forceCaptureMemorySnapshot").invoke(null); - for (int i=0;i<1000;i++) { + for (int i = 0; i < 1000; i++) { PlatformTestUtil.tryGcSoftlyReachableObjects(); UIUtil.dispatchAllInvocationEvents(); if (documentManager.getCachedDocument(getPsiManager().findFile(vFile)) == null) break; diff --git a/platform/platform-tests/testSrc/com/intellij/usages/impl/UsageViewTest.java b/platform/platform-tests/testSrc/com/intellij/usages/impl/UsageViewTest.java index 085afbf5c126..3fcc42baa645 100644 --- a/platform/platform-tests/testSrc/com/intellij/usages/impl/UsageViewTest.java +++ b/platform/platform-tests/testSrc/com/intellij/usages/impl/UsageViewTest.java @@ -26,7 +26,7 @@ import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.psi.impl.source.PsiFileImpl; import com.intellij.testFramework.LeakHunter; -import com.intellij.testFramework.LightPlatformCodeInsightTestCase; +import com.intellij.testFramework.fixtures.LightPlatformCodeInsightFixtureTestCase; import com.intellij.usageView.UsageInfo; import com.intellij.usages.*; import com.intellij.util.ui.UIUtil; @@ -34,9 +34,9 @@ import com.intellij.util.ui.UIUtil; /** * User: cdr */ -public class UsageViewTest extends LightPlatformCodeInsightTestCase{ +public class UsageViewTest extends LightPlatformCodeInsightFixtureTestCase { public void testUsageViewDoesNotHoldPsiFilesOrDocuments() throws Exception { - PsiFile psiFile = createFile("X.java", "public class X{} //iuggjhfg"); + PsiFile psiFile = myFixture.addFileToProject("X.java", "public class X{} //iuggjhfg"); Usage[] usages = new Usage[100]; for (int i = 0; i < usages.length; i++) { usages[i] = createUsage(psiFile,i); @@ -55,7 +55,7 @@ public class UsageViewTest extends LightPlatformCodeInsightTestCase{ } public void testUsageViewHandlesDocumentChange() throws Exception { - PsiFile psiFile = createFile("X.java", "public class X{ int xxx; } //comment"); + PsiFile psiFile = myFixture.addFileToProject("X.java", "public class X{ int xxx; } //comment"); Usage usage = createUsage(psiFile, psiFile.getText().indexOf("xxx")); UsageView usageView = UsageViewManager.getInstance(getProject()).createUsageView(UsageTarget.EMPTY_ARRAY, new Usage[]{usage}, new UsageViewPresentation(), null); @@ -69,7 +69,7 @@ public class UsageViewTest extends LightPlatformCodeInsightTestCase{ assertEquals(psiFile.getText().indexOf("xxx"), navigationOffset); } public void testTextUsageInfoHandlesDocumentChange() throws Exception { - PsiFile psiFile = createFile("X.java", "public class X{ int xxx; } //comment"); + PsiFile psiFile = myFixture.addFileToProject("X.java", "public class X{ int xxx; } //comment"); Usage usage = new UsageInfo2UsageAdapter(new UsageInfo(psiFile, psiFile.getText().indexOf("xxx"), StringUtil.indexOfSubstringEnd(psiFile.getText(),"xxx"))); UsageView usageView = UsageViewManager.getInstance(getProject()).createUsageView(UsageTarget.EMPTY_ARRAY, new Usage[]{usage}, new UsageViewPresentation(), null);