don't recreate code fragment psi (IDEA-127039)

This commit is contained in:
peter
2014-07-18 15:38:28 +02:00
parent 5379b771ca
commit 2ff73e2b6e
5 changed files with 42 additions and 14 deletions
@@ -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());
}
}
@@ -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<FileViewProvider> 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;
}
@@ -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(
@@ -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;
@@ -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);