diff --git a/idea/src/org/jetbrains/jet/plugin/java/JavaElementFinder.java b/idea/src/org/jetbrains/jet/plugin/java/JavaElementFinder.java index adf84a87b4c..fe2513823e0 100644 --- a/idea/src/org/jetbrains/jet/plugin/java/JavaElementFinder.java +++ b/idea/src/org/jetbrains/jet/plugin/java/JavaElementFinder.java @@ -9,7 +9,7 @@ import com.intellij.openapi.fileTypes.FileTypeManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.*; import com.intellij.psi.*; import com.intellij.psi.impl.file.PsiPackageImpl; import com.intellij.psi.search.GlobalSearchScope; @@ -18,18 +18,40 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.plugin.JetFileType; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; +import java.util.*; public class JavaElementFinder extends PsiElementFinder { private final Project project; private final PsiManager psiManager; + private WeakHashMap> jetFiles = new WeakHashMap>(); + public JavaElementFinder(Project project) { this.project = project; psiManager = PsiManager.getInstance(project); + + // Monitoring for files instead of collecting them each time + VirtualFileManager.getInstance().addVirtualFileListener(new VirtualFileAdapter() { + @Override + public void fileCreated(VirtualFileEvent event) { + invalidateJetFilesCache(); + } + + @Override + public void fileDeleted(VirtualFileEvent event) { + invalidateJetFilesCache(); + } + + @Override + public void fileMoved(VirtualFileMoveEvent event) { + invalidateJetFilesCache(); + } + + @Override + public void fileCopied(VirtualFileCopyEvent event) { + invalidateJetFilesCache(); + } + }); } @Override @@ -45,7 +67,7 @@ public class JavaElementFinder extends PsiElementFinder { if (qualifiedName.startsWith("java.")) return PsiClass.EMPTY_ARRAY; List answer = new SmartList(); - final List filesInScope = collectProjectFiles(project, scope); + final List filesInScope = collectProjectJetFiles(project, scope); for (JetFile file : filesInScope) { JetNamespace rootNamespace = file.getRootNamespace(); final String packageName = JetPsiUtil.getFQName(rootNamespace); @@ -71,7 +93,7 @@ public class JavaElementFinder extends PsiElementFinder { Set answer = new HashSet(); String packageFQN = psiPackage.getQualifiedName(); - for (JetFile psiFile : collectProjectFiles(project, GlobalSearchScope.allScope(project))) { + for (JetFile psiFile : collectProjectJetFiles(project, GlobalSearchScope.allScope(project))) { final JetNamespace rootNamespace = psiFile.getRootNamespace(); if (packageFQN.equals(JetPsiUtil.getFQName(rootNamespace))) { answer.add("namespace"); @@ -93,7 +115,7 @@ public class JavaElementFinder extends PsiElementFinder { @Override public PsiPackage findPackage(@NotNull String qualifiedName) { - final List psiFiles = collectProjectFiles(project, GlobalSearchScope.allScope(project)); + final List psiFiles = collectProjectJetFiles(project, GlobalSearchScope.allScope(project)); for (JetFile psiFile : psiFiles) { if (qualifiedName.equals(JetPsiUtil.getFQName(psiFile.getRootNamespace()))) { @@ -108,7 +130,7 @@ public class JavaElementFinder extends PsiElementFinder { @Override public PsiClass[] getClasses(@NotNull PsiPackage psiPackage, @NotNull GlobalSearchScope scope) { List answer = new SmartList(); - final List filesInScope = collectProjectFiles(project, scope); + final List filesInScope = collectProjectJetFiles(project, scope); String packageFQN = psiPackage.getQualifiedName(); for (JetFile file : filesInScope) { final JetNamespace rootNamespace = file.getRootNamespace(); @@ -125,31 +147,40 @@ public class JavaElementFinder extends PsiElementFinder { return answer.toArray(new PsiClass[answer.size()]); } + private synchronized void invalidateJetFilesCache() { + jetFiles.clear(); + } - private static List collectProjectFiles(final Project project, @NotNull final GlobalSearchScope scope) { - final List answer = new ArrayList(); + private synchronized List collectProjectJetFiles(final Project project, @NotNull final GlobalSearchScope scope) { + List cachedFiles = jetFiles.get(scope); + + if (cachedFiles == null) { + final List answer = new ArrayList(); + final FileTypeManager fileTypeManager = FileTypeManager.getInstance(); - final FileTypeManager fileTypeManager = FileTypeManager.getInstance(); - final PsiManager psiManager = PsiManager.getInstance(project); + VirtualFile[] contentRoots = ProjectRootManager.getInstance(project).getContentRoots(); - VirtualFile[] contentRoots = ProjectRootManager.getInstance(project).getContentRoots(); - CompilerPathsEx.visitFiles(contentRoots, new CompilerPathsEx.FileVisitor() { - @Override - protected void acceptFile(VirtualFile file, String fileRoot, String filePath) { - final FileType fileType = fileTypeManager.getFileTypeByFile(file); - if (fileType != JetFileType.INSTANCE) return; + CompilerPathsEx.visitFiles(contentRoots, new CompilerPathsEx.FileVisitor() { + @Override + protected void acceptFile(VirtualFile file, String fileRoot, String filePath) { + final FileType fileType = fileTypeManager.getFileTypeByFile(file); + if (fileType != JetFileType.INSTANCE) return; - if (scope.accept(file)) { - final PsiFile psiFile = psiManager.findFile(file); - if (psiFile instanceof JetFile) { - answer.add((JetFile) psiFile); + if (scope.accept(file)) { + final PsiFile psiFile = psiManager.findFile(file); + if (psiFile instanceof JetFile) { + answer.add((JetFile) psiFile); + } } } - } - }); + }); - return answer; + cachedFiles = answer; + jetFiles.put(scope, answer); + } + + return cachedFiles; } }