From dafa878a7d32991c33ca5315d9d3d8012f3d3640 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Fri, 11 May 2012 17:39:57 +0200 Subject: [PATCH] extract LibraryScopeCache out of ProjectRootManagerImpl --- .../openapi/roots/impl/LibraryScopeCache.java | 100 ++++++++++++++++++ .../impl/ProjectRootManagerComponent.java | 16 +++ .../roots/impl/ProjectRootManagerImpl.java | 58 ---------- .../file/impl/ResolveScopeManagerImpl.java | 6 +- .../src/META-INF/LangExtensions.xml | 3 + .../roots/ex/ProjectRootManagerEx.java | 8 -- 6 files changed, 122 insertions(+), 69 deletions(-) create mode 100644 platform/lang-impl/src/com/intellij/openapi/roots/impl/LibraryScopeCache.java diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/impl/LibraryScopeCache.java b/platform/lang-impl/src/com/intellij/openapi/roots/impl/LibraryScopeCache.java new file mode 100644 index 000000000000..1aad284ced03 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/openapi/roots/impl/LibraryScopeCache.java @@ -0,0 +1,100 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.openapi.roots.impl; + +import com.intellij.openapi.components.ServiceManager; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.impl.scopes.JdkScope; +import com.intellij.openapi.module.impl.scopes.LibraryRuntimeClasspathScope; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.JdkOrderEntry; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.util.ConcurrencyUtil; +import com.intellij.util.containers.ConcurrentHashMap; +import org.jetbrains.annotations.NotNull; + +import java.util.List; +import java.util.concurrent.ConcurrentMap; + +/** + * @author yole + */ +public class LibraryScopeCache { + public static LibraryScopeCache getInstance(Project project) { + return ServiceManager.getService(project, LibraryScopeCache.class); + } + + private final Project myProject; + private final ConcurrentMap, GlobalSearchScope> myLibraryScopes = new ConcurrentHashMap, GlobalSearchScope>(); + private final ConcurrentMap mySdkScopes = new ConcurrentHashMap(); + + public LibraryScopeCache(Project project) { + myProject = project; + } + + public void clear() { + myLibraryScopes.clear(); + mySdkScopes.clear(); + } + + public GlobalSearchScope getScopeForLibraryUsedIn(List modulesLibraryIsUsedIn) { + GlobalSearchScope scope = myLibraryScopes.get(modulesLibraryIsUsedIn); + if (scope != null) { + return scope; + } + GlobalSearchScope newScope = modulesLibraryIsUsedIn.isEmpty() + ? new LibrariesOnlyScope(GlobalSearchScope.allScope(myProject)) + : new LibraryRuntimeClasspathScope(myProject, modulesLibraryIsUsedIn); + return ConcurrencyUtil.cacheOrGet(myLibraryScopes, modulesLibraryIsUsedIn, newScope); + } + + public GlobalSearchScope getScopeForSdk(final JdkOrderEntry jdkOrderEntry) { + final String jdk = jdkOrderEntry.getJdkName(); + if (jdk == null) return GlobalSearchScope.allScope(myProject); + GlobalSearchScope scope = mySdkScopes.get(jdk); + if (scope == null) { + return ConcurrencyUtil.cacheOrGet(mySdkScopes, jdk, new JdkScope(myProject, jdkOrderEntry)); + } + return scope; + } + + private static class LibrariesOnlyScope extends GlobalSearchScope { + private final GlobalSearchScope myOriginal; + + private LibrariesOnlyScope(final GlobalSearchScope original) { + super(original.getProject()); + myOriginal = original; + } + + public boolean contains(VirtualFile file) { + return myOriginal.contains(file); + } + + public int compare(VirtualFile file1, VirtualFile file2) { + return myOriginal.compare(file1, file2); + } + + public boolean isSearchInModuleContent(@NotNull Module aModule) { + return false; + } + + public boolean isSearchInLibraries() { + return true; + } + } + +} diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/impl/ProjectRootManagerComponent.java b/platform/lang-impl/src/com/intellij/openapi/roots/impl/ProjectRootManagerComponent.java index f6e2e70d81ff..675d8fbab79e 100644 --- a/platform/lang-impl/src/com/intellij/openapi/roots/impl/ProjectRootManagerComponent.java +++ b/platform/lang-impl/src/com/intellij/openapi/roots/impl/ProjectRootManagerComponent.java @@ -27,6 +27,7 @@ import com.intellij.openapi.fileTypes.FileTypeListener; import com.intellij.openapi.fileTypes.FileTypeManager; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.module.impl.ModuleImpl; import com.intellij.openapi.project.DumbServiceImpl; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.*; @@ -269,6 +270,21 @@ public class ProjectRootManagerComponent extends ProjectRootManagerImpl { return result; } + @Override + protected void clearScopesCaches() { + super.clearScopesCaches(); + LibraryScopeCache.getInstance(myProject).clear(); + } + + @Override + public void clearScopesCachesForModules() { + super.clearScopesCachesForModules(); + Module[] modules = ModuleManager.getInstance(myProject).getModules(); + for (Module module : modules) { + ((ModuleImpl)module).clearScopesCache(); + } + } + private class AppListener extends ApplicationAdapter { public void beforeWriteActionStart(Object action) { myInsideRefresh++; diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/impl/ProjectRootManagerImpl.java b/platform/lang-impl/src/com/intellij/openapi/roots/impl/ProjectRootManagerImpl.java index 1a34f20de8a4..82a1a91c3f01 100644 --- a/platform/lang-impl/src/com/intellij/openapi/roots/impl/ProjectRootManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/openapi/roots/impl/ProjectRootManagerImpl.java @@ -24,9 +24,6 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleManager; -import com.intellij.openapi.module.impl.ModuleImpl; -import com.intellij.openapi.module.impl.scopes.JdkScope; -import com.intellij.openapi.module.impl.scopes.LibraryRuntimeClasspathScope; import com.intellij.openapi.project.Project; import com.intellij.openapi.projectRoots.ProjectJdkTable; import com.intellij.openapi.projectRoots.Sdk; @@ -43,10 +40,7 @@ import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiManager; import com.intellij.psi.impl.PsiModificationTrackerImpl; -import com.intellij.psi.search.GlobalSearchScope; -import com.intellij.util.ConcurrencyUtil; import com.intellij.util.EventDispatcher; -import com.intellij.util.containers.ConcurrentHashMap; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.HashMap; import com.intellij.util.containers.HashSet; @@ -56,7 +50,6 @@ import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import java.util.*; -import java.util.concurrent.ConcurrentMap; /** * @author max @@ -77,8 +70,6 @@ public class ProjectRootManagerImpl extends ProjectRootManagerEx implements Proj private long myModificationCount = 0; @NonNls private static final String ATTRIBUTE_VERSION = "version"; - private final ConcurrentMap, GlobalSearchScope> myLibraryScopes = new ConcurrentHashMap, GlobalSearchScope>(); - private final ConcurrentMap myJdkScopes = new ConcurrentHashMap(); private final OrderRootsCache myRootsCache; protected boolean myStartupActivityPerformed = false; @@ -350,8 +341,6 @@ public class ProjectRootManagerImpl extends ProjectRootManagerEx implements Proj protected void clearScopesCaches() { clearScopesCachesForModules(); - myJdkScopes.clear(); - myLibraryScopes.clear(); } public void clearScopesCachesForModules() { @@ -359,7 +348,6 @@ public class ProjectRootManagerImpl extends ProjectRootManagerEx implements Proj Module[] modules = ModuleManager.getInstance(myProject).getModules(); for (Module module : modules) { ((ModuleRootManagerImpl)ModuleRootManager.getInstance(module)).dropCaches(); - ((ModuleImpl)module).clearScopesCache(); } } @@ -456,52 +444,6 @@ public class ProjectRootManagerImpl extends ProjectRootManagerEx implements Proj return myProject; } - private static class LibrariesOnlyScope extends GlobalSearchScope { - private final GlobalSearchScope myOriginal; - - private LibrariesOnlyScope(final GlobalSearchScope original) { - super(original.getProject()); - myOriginal = original; - } - - public boolean contains(VirtualFile file) { - return myOriginal.contains(file); - } - - public int compare(VirtualFile file1, VirtualFile file2) { - return myOriginal.compare(file1, file2); - } - - public boolean isSearchInModuleContent(@NotNull Module aModule) { - return false; - } - - public boolean isSearchInLibraries() { - return true; - } - } - - public GlobalSearchScope getScopeForLibraryUsedIn(List modulesLibraryIsUsedIn) { - GlobalSearchScope scope = myLibraryScopes.get(modulesLibraryIsUsedIn); - if (scope != null) { - return scope; - } - GlobalSearchScope newScope = modulesLibraryIsUsedIn.isEmpty() - ? new LibrariesOnlyScope(GlobalSearchScope.allScope(myProject)) - : new LibraryRuntimeClasspathScope(myProject, modulesLibraryIsUsedIn); - return ConcurrencyUtil.cacheOrGet(myLibraryScopes, modulesLibraryIsUsedIn, newScope); - } - - public GlobalSearchScope getScopeForJdk(final JdkOrderEntry jdkOrderEntry) { - final String jdk = jdkOrderEntry.getJdkName(); - if (jdk == null) return GlobalSearchScope.allScope(myProject); - GlobalSearchScope scope = myJdkScopes.get(jdk); - if (scope == null) { - return ConcurrencyUtil.cacheOrGet(myJdkScopes,jdk, new JdkScope(myProject, jdkOrderEntry)); - } - return scope; - } - protected void doSynchronizeRoots() { } diff --git a/platform/lang-impl/src/com/intellij/psi/impl/file/impl/ResolveScopeManagerImpl.java b/platform/lang-impl/src/com/intellij/psi/impl/file/impl/ResolveScopeManagerImpl.java index e4a733bc9de2..5e638f303b43 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/file/impl/ResolveScopeManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/file/impl/ResolveScopeManagerImpl.java @@ -21,7 +21,7 @@ import com.intellij.openapi.module.impl.scopes.LibraryRuntimeClasspathScope; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.*; -import com.intellij.openapi.roots.ex.ProjectRootManagerEx; +import com.intellij.openapi.roots.impl.LibraryScopeCache; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; import com.intellij.psi.impl.PsiManagerImpl; @@ -99,7 +99,7 @@ public class ResolveScopeManagerImpl extends ResolveScopeManager { ProgressManager.checkCanceled(); if (entry instanceof JdkOrderEntry) { - return ((ProjectRootManagerEx)myProjectRootManager).getScopeForJdk((JdkOrderEntry)entry); + return LibraryScopeCache.getInstance(myProject).getScopeForSdk((JdkOrderEntry)entry); } if (entry instanceof LibraryOrderEntry) { @@ -111,7 +111,7 @@ public class ResolveScopeManagerImpl extends ResolveScopeManager { } } - GlobalSearchScope allCandidates = ((ProjectRootManagerEx)myProjectRootManager).getScopeForLibraryUsedIn(modulesLibraryUsedIn); + GlobalSearchScope allCandidates = LibraryScopeCache.getInstance(myProject).getScopeForLibraryUsedIn(modulesLibraryUsedIn); if (lib != null) { final LibraryRuntimeClasspathScope preferred = new LibraryRuntimeClasspathScope(myProject, lib); // prefer current library diff --git a/platform/platform-resources/src/META-INF/LangExtensions.xml b/platform/platform-resources/src/META-INF/LangExtensions.xml index e5e671fa4bff..ff268fe07ccc 100644 --- a/platform/platform-resources/src/META-INF/LangExtensions.xml +++ b/platform/platform-resources/src/META-INF/LangExtensions.xml @@ -305,6 +305,9 @@ + + diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/ex/ProjectRootManagerEx.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/ex/ProjectRootManagerEx.java index 76aa70683b4e..2d48c8f7ec3f 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/roots/ex/ProjectRootManagerEx.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/ex/ProjectRootManagerEx.java @@ -16,15 +16,11 @@ package com.intellij.openapi.roots.ex; -import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; -import com.intellij.openapi.roots.JdkOrderEntry; import com.intellij.openapi.roots.ProjectRootManager; -import com.intellij.psi.search.GlobalSearchScope; import org.jetbrains.annotations.NotNull; import java.util.EventListener; -import java.util.List; public abstract class ProjectRootManagerEx extends ProjectRootManager { public static ProjectRootManagerEx getInstanceEx(Project project) { @@ -40,10 +36,6 @@ public abstract class ProjectRootManagerEx extends ProjectRootManager { public abstract void mergeRootsChangesDuring(@NotNull Runnable runnable); - public abstract GlobalSearchScope getScopeForLibraryUsedIn(List modulesLibraryIsUsedIn); - - public abstract GlobalSearchScope getScopeForJdk(final JdkOrderEntry jdkOrderEntry); - public abstract void clearScopesCachesForModules();