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
@@ -17,27 +17,30 @@
package org.jetbrains.kotlin.idea.decompiler.navigation;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.*;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
import com.intellij.psi.search.GlobalSearchScope;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
import org.jetbrains.kotlin.descriptors.ClassOrPackageFragmentDescriptor;
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor;
import org.jetbrains.kotlin.idea.caches.resolve.JsProjectDetector;
import org.jetbrains.kotlin.idea.decompiler.DecompilerPackage;
import org.jetbrains.kotlin.idea.decompiler.KotlinClsFileBase;
import org.jetbrains.kotlin.idea.stubindex.JetSourceFilterScope;
import org.jetbrains.kotlin.load.kotlin.PackageClassUtils;
import org.jetbrains.kotlin.load.kotlin.VirtualFileFinder;
import org.jetbrains.kotlin.load.kotlin.VirtualFileFinderFactory;
import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.name.FqNameUnsafe;
import org.jetbrains.kotlin.name.ClassId;
import org.jetbrains.kotlin.psi.JetDeclaration;
import org.jetbrains.kotlin.resolve.DescriptorUtils;
import org.jetbrains.kotlin.types.ErrorUtils;
import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils;
import static org.jetbrains.kotlin.resolve.DescriptorUtils.getFqName;
import static org.jetbrains.kotlin.load.kotlin.PackageClassUtils.getPackageClassId;
import static org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilPackage.getClassId;
public final class DecompiledNavigationUtils {
@@ -76,34 +79,30 @@ public final class DecompiledNavigationUtils {
@NotNull Project project,
@NotNull DeclarationDescriptor referencedDescriptor
) {
FqName containerFqName = getContainerFqName(referencedDescriptor);
if (containerFqName == null) {
return null;
}
if (ErrorUtils.isError(referencedDescriptor)) return null;
ClassId containerClassId = getContainerClassId(referencedDescriptor);
if (containerClassId == null) return null;
GlobalSearchScope scopeToSearchIn = JetSourceFilterScope.kotlinSourceAndClassFiles(GlobalSearchScope.allScope(project), project);
VirtualFileFinder fileFinder = VirtualFileFinderFactory.SERVICE.getInstance(project).create(scopeToSearchIn);
VirtualFile virtualFile = fileFinder.findVirtualFileWithHeader(containerFqName);
if (virtualFile == null) {
return null;
}
return virtualFile;
return fileFinder.findVirtualFileWithHeader(containerClassId);
}
//TODO: navigate to inner classes
@Nullable
private static FqName getContainerFqName(@NotNull DeclarationDescriptor referencedDescriptor) {
private static ClassId getContainerClassId(@NotNull DeclarationDescriptor referencedDescriptor) {
ClassOrPackageFragmentDescriptor
containerDescriptor = DescriptorUtils.getParentOfType(referencedDescriptor, ClassOrPackageFragmentDescriptor.class, false);
if (containerDescriptor instanceof PackageFragmentDescriptor) {
return PackageClassUtils.getPackageClassFqName(((PackageFragmentDescriptor) containerDescriptor).getFqName());
return getPackageClassId(((PackageFragmentDescriptor) containerDescriptor).getFqName());
}
if (containerDescriptor instanceof ClassDescriptor) {
if (containerDescriptor.getContainingDeclaration() instanceof ClassDescriptor
|| ExpressionTypingUtils.isLocal(containerDescriptor.getContainingDeclaration(), containerDescriptor)) {
return getContainerFqName(containerDescriptor.getContainingDeclaration());
return getContainerClassId(containerDescriptor.getContainingDeclaration());
}
FqNameUnsafe fqNameUnsafe = getFqName(containerDescriptor);
return fqNameUnsafe.isSafe() ? fqNameUnsafe.toSafe() : null;
return getClassId((ClassDescriptor) containerDescriptor);
}
return null;
}
@@ -17,7 +17,6 @@
package org.jetbrains.kotlin.idea.vfilefinder;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.util.indexing.FileBasedIndex;
@@ -25,7 +24,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.load.kotlin.VirtualFileFinder;
import org.jetbrains.kotlin.load.kotlin.VirtualFileKotlinClassFinder;
import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.name.ClassId;
import java.util.Collection;
@@ -33,11 +32,9 @@ public final class IDEVirtualFileFinder extends VirtualFileKotlinClassFinder imp
private static final Logger LOG = Logger.getInstance(IDEVirtualFileFinder.class);
@NotNull private final Project project;
@NotNull private final GlobalSearchScope scope;
public IDEVirtualFileFinder(@NotNull Project project, @NotNull GlobalSearchScope scope) {
this.project = project;
public IDEVirtualFileFinder(@NotNull GlobalSearchScope scope) {
this.scope = scope;
if (scope != GlobalSearchScope.EMPTY_SCOPE && scope.getProject() == null) {
@@ -47,13 +44,13 @@ public final class IDEVirtualFileFinder extends VirtualFileKotlinClassFinder imp
@Nullable
@Override
public VirtualFile findVirtualFileWithHeader(@NotNull FqName className) {
Collection<VirtualFile> files = FileBasedIndex.getInstance().getContainingFiles(KotlinClassFileIndex.KEY, className, scope);
public VirtualFile findVirtualFileWithHeader(@NotNull ClassId classId) {
Collection<VirtualFile> files = FileBasedIndex.getInstance().getContainingFiles(KotlinClassFileIndex.KEY, classId.asSingleFqName(), scope);
if (files.isEmpty()) {
return null;
}
if (files.size() > 1) {
LOG.warn("There are " + files.size() + " classes with same fqName: " + className + " found.");
LOG.warn("There are " + files.size() + " classes with same fqName: " + classId + " found.");
}
return files.iterator().next();
}
@@ -16,7 +16,6 @@
package org.jetbrains.kotlin.idea.vfilefinder;
import com.intellij.openapi.project.Project;
import com.intellij.psi.search.GlobalSearchScope;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.load.kotlin.VirtualFileFinder;
@@ -24,16 +23,9 @@ import org.jetbrains.kotlin.load.kotlin.VirtualFileFinderFactory;
public class IDEVirtualFileFinderFactory implements VirtualFileFinderFactory {
@NotNull
private final Project project;
public IDEVirtualFileFinderFactory(@NotNull Project project) {
this.project = project;
}
@NotNull
@Override
public VirtualFileFinder create(@NotNull GlobalSearchScope scope) {
return new IDEVirtualFileFinder(project, scope);
return new IDEVirtualFileFinder(scope);
}
}