diff --git a/java/java-impl/src/com/intellij/psi/NonClasspathClassFinder.java b/java/java-impl/src/com/intellij/psi/NonClasspathClassFinder.java index feb111e02e38..dd60aefb5a3e 100644 --- a/java/java-impl/src/com/intellij/psi/NonClasspathClassFinder.java +++ b/java/java-impl/src/com/intellij/psi/NonClasspathClassFinder.java @@ -31,18 +31,44 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.*; +import java.util.concurrent.atomic.AtomicLong; /** * @author peter */ public abstract class NonClasspathClassFinder extends PsiElementFinder { private static final Logger LOG = Logger.getInstance("#com.intellij.psi.NonClasspathClassFinder"); + private final AtomicLong myLastStamp = new AtomicLong(); protected final Project myProject; + private volatile List myCache; public NonClasspathClassFinder(Project project) { myProject = project; } + protected List getClassRoots() { + List cache = myCache; + long stamp = PsiManager.getInstance(myProject).getModificationTracker().getModificationCount(); + if (myLastStamp.get() != stamp) { + cache = null; + } + + if (cache != null && !cache.isEmpty()) { + for (VirtualFile file : cache) { + if (!file.isValid()) { + cache = null; + break; + } + } + } + + if (cache == null) { + myCache = cache = calcClassRoots(); + myLastStamp.set(stamp); + } + return cache; + } + @Override public PsiClass findClass(@NotNull String qualifiedName, @NotNull GlobalSearchScope scope) { final List classRoots = getClassRoots(); @@ -71,7 +97,7 @@ public abstract class NonClasspathClassFinder extends PsiElementFinder { return null; } - protected abstract List getClassRoots(); + protected abstract List calcClassRoots(); @NotNull @Override diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/gant/GantClassFinder.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/gant/GantClassFinder.java index 4496fb1afa95..6d2e0105aac3 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/gant/GantClassFinder.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/gant/GantClassFinder.java @@ -33,7 +33,7 @@ public class GantClassFinder extends NonClasspathClassFinder { } @Override - protected List getClassRoots() { + protected List calcClassRoots() { return mySettings.getClassRoots(); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/gant/GantSettings.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/gant/GantSettings.java index e2f46ad52ccb..2af617fd06d5 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/gant/GantSettings.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/gant/GantSettings.java @@ -33,6 +33,9 @@ import org.jetbrains.plugins.groovy.util.SdkHomeSettings; } ) public class GantSettings extends SdkHomeSettings { + public GantSettings(Project project) { + super(project); + } public static GantSettings getInstance(Project project) { return ServiceManager.getService(project, GantSettings.class); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/gradle/GradleClassFinder.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/gradle/GradleClassFinder.java index d30ec8b12fc6..39b3168b0322 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/gradle/GradleClassFinder.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/gradle/GradleClassFinder.java @@ -34,7 +34,7 @@ public class GradleClassFinder extends NonClasspathClassFinder { } @Override - protected List getClassRoots() { + protected List calcClassRoots() { return mySettings.getClassRoots(); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/gradle/GradleSettings.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/gradle/GradleSettings.java index 15f8b7e5f29f..d897bf33dca4 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/gradle/GradleSettings.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/gradle/GradleSettings.java @@ -33,6 +33,9 @@ import org.jetbrains.plugins.groovy.util.SdkHomeSettings; } ) public class GradleSettings extends SdkHomeSettings { + public GradleSettings(Project project) { + super(project); + } public static GradleSettings getInstance(Project project) { return ServiceManager.getService(project, GradleSettings.class); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/util/SdkHomeSettings.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/util/SdkHomeSettings.java index 2ec1dd20b9af..22302709e669 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/util/SdkHomeSettings.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/util/SdkHomeSettings.java @@ -16,11 +16,14 @@ package org.jetbrains.plugins.groovy.util; +import com.intellij.openapi.components.PersistentStateComponent; +import com.intellij.openapi.project.Project; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.JarFileSystem; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.openapi.components.PersistentStateComponent; +import com.intellij.psi.PsiManager; +import com.intellij.psi.impl.PsiModificationTrackerImpl; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.Nullable; @@ -32,9 +35,12 @@ import java.util.List; * @author peter */ public abstract class SdkHomeSettings implements PersistentStateComponent { + private final PsiModificationTrackerImpl myTracker; private SdkHomeConfigurable.SdkHomeBean mySdkPath; - private volatile VirtualFile mySdkHome; - private volatile List myClassRoots; + + protected SdkHomeSettings(Project project) { + myTracker = (PsiModificationTrackerImpl)PsiManager.getInstance(project).getModificationTracker(); + } public SdkHomeConfigurable.SdkHomeBean getState() { return mySdkPath; @@ -42,16 +48,7 @@ public abstract class SdkHomeSettings implements PersistentStateComponent getClassRoots() { - if (myClassRoots == null) { - calculateRoots(); - } - return myClassRoots; + return calcRoots(getSdkHome()); } private static List calcRoots(@Nullable VirtualFile home) {