Speed up finding kotlin binaries and java files in CLI

Change VirtualFileFinder api to accept ClassId and adjust usages
Introduce KotlinCoreProjectEnvironment to create special KotlinCliJavaFileManager which shares cache with CliVirtualFileFinder
Truly distinguish between java source roots and binary roots: don't search for source files in classpath and vica versa
Implement JvmDependenciesIndex
This commit is contained in:
Pavel V. Talanov
2015-03-17 15:46:04 +03:00
parent 94cc847c48
commit d76f293dc9
20 changed files with 755 additions and 198 deletions
@@ -86,13 +86,11 @@ public class JavaClassFinderImpl implements JavaClassFinder {
@Nullable
@Override
public JavaClass findClass(@NotNull ClassId classId) {
FqName fqName = classId.asSingleFqName();
PsiClass psiClass = javaFacade.findClass(fqName.asString(), javaSearchScope);
PsiClass psiClass = javaFacade.findClass(classId, javaSearchScope);
if (psiClass == null) return null;
JavaClassImpl javaClass = new JavaClassImpl(psiClass);
FqName fqName = classId.asSingleFqName();
if (!fqName.equals(javaClass.getFqName())) {
throw new IllegalStateException("Requested " + fqName + ", got " + javaClass.getFqName());
}
@@ -22,7 +22,7 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.search.GlobalSearchScope;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.name.ClassId;
public interface VirtualFileFinder extends KotlinClassFinder {
class SERVICE {
@@ -33,5 +33,5 @@ public interface VirtualFileFinder extends KotlinClassFinder {
}
@Nullable
VirtualFile findVirtualFileWithHeader(@NotNull FqName className);
VirtualFile findVirtualFileWithHeader(@NotNull ClassId className);
}
@@ -23,7 +23,7 @@ import org.jetbrains.kotlin.utils.sure
public abstract class VirtualFileKotlinClassFinder : VirtualFileFinder {
override fun findKotlinClass(classId: ClassId): KotlinJvmBinaryClass? {
val file = findVirtualFileWithHeader(classId.asSingleFqName()) ?: return null
val file = findVirtualFileWithHeader(classId) ?: return null
return KotlinBinaryClassCache.getKotlinBinaryClass(file)
}
@@ -0,0 +1,26 @@
/*
* Copyright 2010-2015 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 org.jetbrains.kotlin.resolve.jvm
import com.intellij.psi.PsiClass
import com.intellij.psi.impl.file.impl.JavaFileManager
import com.intellij.psi.search.GlobalSearchScope
import org.jetbrains.kotlin.name.ClassId
public trait KotlinCliJavaFileManager : JavaFileManager {
public fun findClass(classId: ClassId, searchScope: GlobalSearchScope): PsiClass?
}
@@ -16,7 +16,6 @@
package org.jetbrains.kotlin.resolve.jvm;
import com.intellij.core.CoreJavaFileManager;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.progress.ProgressIndicatorProvider;
import com.intellij.openapi.project.DumbAware;
@@ -44,6 +43,7 @@ import com.intellij.util.messages.MessageBus;
import kotlin.Function1;
import kotlin.KotlinPackage;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.name.ClassId;
import java.util.ArrayList;
import java.util.Arrays;
@@ -87,9 +87,11 @@ public class KotlinJavaPsiFacade {
});
}
public PsiClass findClass(@NotNull String qualifiedName, @NotNull GlobalSearchScope scope) {
public PsiClass findClass(@NotNull ClassId classId, @NotNull GlobalSearchScope scope) {
ProgressIndicatorProvider.checkCanceled(); // We hope this method is being called often enough to cancel daemon processes smoothly
String qualifiedName = classId.asSingleFqName().asString();
if (shouldUseSlowResolve()) {
PsiClass[] classes = findClassesInDumbMode(qualifiedName, scope);
if (classes.length != 0) {
@@ -99,8 +101,14 @@ public class KotlinJavaPsiFacade {
}
for (KotlinPsiElementFinderWrapper finder : finders()) {
PsiClass aClass = finder.findClass(qualifiedName, scope);
if (aClass != null) return aClass;
if (finder instanceof KotlinPsiElementFinderImpl) {
PsiClass aClass = ((KotlinPsiElementFinderImpl) finder).findClass(classId, scope);
if (aClass != null) return aClass;
}
else {
PsiClass aClass = finder.findClass(qualifiedName, scope);
if (aClass != null) return aClass;
}
}
return null;
@@ -286,14 +294,14 @@ public class KotlinJavaPsiFacade {
static class KotlinPsiElementFinderImpl implements KotlinPsiElementFinderWrapper, DumbAware {
private final JavaFileManager javaFileManager;
private final boolean isCoreJavaFileManager;
private final boolean isCliFileManager;
private final PsiManager psiManager;
private final PackageIndex packageIndex;
public KotlinPsiElementFinderImpl(Project project) {
this.javaFileManager = findJavaFileManager(project);
this.isCoreJavaFileManager = javaFileManager instanceof CoreJavaFileManager;
this.isCliFileManager = javaFileManager instanceof KotlinCliJavaFileManager;
this.packageIndex = PackageIndex.getInstance(project);
this.psiManager = PsiManager.getInstance(project);
@@ -312,20 +320,19 @@ public class KotlinJavaPsiFacade {
@Override
public PsiClass findClass(@NotNull String qualifiedName, @NotNull GlobalSearchScope scope) {
PsiClass aClass = javaFileManager.findClass(qualifiedName, scope);
if (aClass != null) {
//TODO: (module refactoring) CoreJavaFileManager should check scope
if (!isCoreJavaFileManager || scope.contains(aClass.getContainingFile().getOriginalFile().getVirtualFile())) {
return aClass;
}
}
return javaFileManager.findClass(qualifiedName, scope);
}
return null;
public PsiClass findClass(@NotNull ClassId classId, @NotNull GlobalSearchScope scope) {
if (isCliFileManager) {
return ((KotlinCliJavaFileManager) javaFileManager).findClass(classId, scope);
}
return findClass(classId.asSingleFqName().asString(), scope);
}
@Override
public PsiPackage findPackage(@NotNull String qualifiedName, @NotNull GlobalSearchScope scope) {
if (isCoreJavaFileManager) {
if (isCliFileManager) {
return javaFileManager.findPackage(qualifiedName);
}