Direct instantiations of VirtualFileKotlinClass are replaced by access to caching service
This commit is contained in:
@@ -46,7 +46,7 @@ public class CliVirtualFileFinder extends VirtualFileKotlinClassFinder implement
|
|||||||
|
|
||||||
//NOTE: copied with some changes from CoreJavaFileManager
|
//NOTE: copied with some changes from CoreJavaFileManager
|
||||||
@Nullable
|
@Nullable
|
||||||
private static VirtualFile findFileInRoot(@NotNull String qName, @NotNull VirtualFile root) {
|
private VirtualFile findFileInRoot(@NotNull String qName, @NotNull VirtualFile root) {
|
||||||
String pathRest = qName;
|
String pathRest = qName;
|
||||||
VirtualFile cur = root;
|
VirtualFile cur = root;
|
||||||
|
|
||||||
@@ -70,7 +70,7 @@ public class CliVirtualFileFinder extends VirtualFileKotlinClassFinder implement
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
//NOTE: currently we use VirtualFileFinder to find Kotlin binaries only
|
//NOTE: currently we use VirtualFileFinder to find Kotlin binaries only
|
||||||
if (KotlinClassHeader.read(new VirtualFileKotlinClass(vFile)) != null) {
|
if (KotlinClassHeader.read(createKotlinClass(vFile)) != null) {
|
||||||
return vFile;
|
return vFile;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+19
-1
@@ -17,16 +17,34 @@
|
|||||||
package org.jetbrains.jet.lang.resolve.kotlin;
|
package org.jetbrains.jet.lang.resolve.kotlin;
|
||||||
|
|
||||||
import com.intellij.openapi.vfs.VirtualFile;
|
import com.intellij.openapi.vfs.VirtualFile;
|
||||||
|
import com.intellij.util.containers.SLRUCache;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||||
|
|
||||||
public abstract class VirtualFileKotlinClassFinder implements VirtualFileFinder {
|
public abstract class VirtualFileKotlinClassFinder implements VirtualFileFinder {
|
||||||
|
|
||||||
|
// This cache must be small: we only query the same file a few times in a row (from different places)
|
||||||
|
private final SLRUCache<VirtualFile, KotlinJvmBinaryClass> cache = new SLRUCache<VirtualFile, KotlinJvmBinaryClass>(2, 2) {
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public KotlinJvmBinaryClass createValue(VirtualFile virtualFile) {
|
||||||
|
return new VirtualFileKotlinClass(virtualFile);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public KotlinJvmBinaryClass findKotlinClass(@NotNull FqName fqName) {
|
public KotlinJvmBinaryClass findKotlinClass(@NotNull FqName fqName) {
|
||||||
VirtualFile file = findVirtualFile(fqName);
|
VirtualFile file = findVirtualFile(fqName);
|
||||||
return file == null ? null : new VirtualFileKotlinClass(file);
|
return file == null ? null : createKotlinClass(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@NotNull
|
||||||
|
public KotlinJvmBinaryClass createKotlinClass(@NotNull VirtualFile file) {
|
||||||
|
synchronized (cache) {
|
||||||
|
return cache.get(file);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+14
@@ -16,11 +16,25 @@
|
|||||||
|
|
||||||
package org.jetbrains.jet.lang.resolve.kotlin;
|
package org.jetbrains.jet.lang.resolve.kotlin;
|
||||||
|
|
||||||
|
import com.intellij.openapi.components.ServiceManager;
|
||||||
|
import com.intellij.openapi.project.Project;
|
||||||
|
import com.intellij.openapi.vfs.VirtualFile;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||||
|
|
||||||
public interface KotlinClassFinder {
|
public interface KotlinClassFinder {
|
||||||
|
|
||||||
|
class SERVICE {
|
||||||
|
@NotNull
|
||||||
|
public static KotlinClassFinder getInstance(@NotNull Project project) {
|
||||||
|
return ServiceManager.getService(project, KotlinClassFinder.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
KotlinJvmBinaryClass findKotlinClass(@NotNull FqName fqName);
|
KotlinJvmBinaryClass findKotlinClass(@NotNull FqName fqName);
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
KotlinJvmBinaryClass createKotlinClass(@NotNull VirtualFile virtualFile);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,8 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
import org.jetbrains.jet.descriptors.serialization.*;
|
import org.jetbrains.jet.descriptors.serialization.*;
|
||||||
import org.jetbrains.jet.lang.descriptors.ClassKind;
|
import org.jetbrains.jet.lang.descriptors.ClassKind;
|
||||||
import org.jetbrains.jet.lang.resolve.java.JavaResolverPsiUtils;
|
import org.jetbrains.jet.lang.resolve.java.JavaResolverPsiUtils;
|
||||||
|
import org.jetbrains.jet.lang.resolve.kotlin.KotlinClassFinder;
|
||||||
|
import org.jetbrains.jet.lang.resolve.kotlin.KotlinJvmBinaryClass;
|
||||||
import org.jetbrains.jet.lang.resolve.kotlin.VirtualFileKotlinClass;
|
import org.jetbrains.jet.lang.resolve.kotlin.VirtualFileKotlinClass;
|
||||||
import org.jetbrains.jet.lang.resolve.kotlin.header.KotlinClassHeader;
|
import org.jetbrains.jet.lang.resolve.kotlin.header.KotlinClassHeader;
|
||||||
import org.jetbrains.jet.lang.resolve.kotlin.header.SerializedDataHeader;
|
import org.jetbrains.jet.lang.resolve.kotlin.header.SerializedDataHeader;
|
||||||
@@ -117,7 +119,8 @@ public class JetFromJavaDescriptorHelper {
|
|||||||
private static String[] getAnnotationDataForKotlinClass(@NotNull PsiClass psiClass) {
|
private static String[] getAnnotationDataForKotlinClass(@NotNull PsiClass psiClass) {
|
||||||
VirtualFile virtualFile = getVirtualFileForPsiClass(psiClass);
|
VirtualFile virtualFile = getVirtualFileForPsiClass(psiClass);
|
||||||
if (virtualFile != null) {
|
if (virtualFile != null) {
|
||||||
KotlinClassHeader header = KotlinClassHeader.read(new VirtualFileKotlinClass(virtualFile));
|
KotlinJvmBinaryClass kotlinClass = KotlinClassFinder.SERVICE.getInstance(psiClass.getProject()).createKotlinClass(virtualFile);
|
||||||
|
KotlinClassHeader header = KotlinClassHeader.read(kotlinClass);
|
||||||
if (header instanceof SerializedDataHeader) {
|
if (header instanceof SerializedDataHeader) {
|
||||||
return ((SerializedDataHeader) header).getAnnotationData();
|
return ((SerializedDataHeader) header).getAnnotationData();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,8 @@ import org.jetbrains.jet.lang.psi.JetFile;
|
|||||||
import org.jetbrains.jet.lang.resolve.BindingTraceContext;
|
import org.jetbrains.jet.lang.resolve.BindingTraceContext;
|
||||||
import org.jetbrains.jet.lang.resolve.MemberComparator;
|
import org.jetbrains.jet.lang.resolve.MemberComparator;
|
||||||
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver;
|
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver;
|
||||||
import org.jetbrains.jet.lang.resolve.kotlin.VirtualFileKotlinClass;
|
import org.jetbrains.jet.lang.resolve.kotlin.KotlinClassFinder;
|
||||||
|
import org.jetbrains.jet.lang.resolve.kotlin.KotlinJvmBinaryClass;
|
||||||
import org.jetbrains.jet.lang.resolve.kotlin.header.KotlinClassHeader;
|
import org.jetbrains.jet.lang.resolve.kotlin.header.KotlinClassHeader;
|
||||||
import org.jetbrains.jet.lang.resolve.kotlin.header.SerializedDataHeader;
|
import org.jetbrains.jet.lang.resolve.kotlin.header.SerializedDataHeader;
|
||||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||||
@@ -67,7 +68,7 @@ public final class DecompiledDataFactory {
|
|||||||
InjectorForJavaDescriptorResolver injector = InjectorForJavaDescriptorResolverUtil.create(project, new BindingTraceContext());
|
InjectorForJavaDescriptorResolver injector = InjectorForJavaDescriptorResolverUtil.create(project, new BindingTraceContext());
|
||||||
this.javaDescriptorResolver = injector.getJavaDescriptorResolver();
|
this.javaDescriptorResolver = injector.getJavaDescriptorResolver();
|
||||||
|
|
||||||
VirtualFileKotlinClass kotlinClass = new VirtualFileKotlinClass(classFile);
|
KotlinJvmBinaryClass kotlinClass = KotlinClassFinder.SERVICE.getInstance(project).createKotlinClass(classFile);
|
||||||
this.classFqName = kotlinClass.getClassName().getFqNameForClassNameWithoutDollars();
|
this.classFqName = kotlinClass.getClassName().getFqNameForClassNameWithoutDollars();
|
||||||
|
|
||||||
KotlinClassHeader header = KotlinClassHeader.read(kotlinClass);
|
KotlinClassHeader header = KotlinClassHeader.read(kotlinClass);
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ public final class DecompiledNavigationUtils {
|
|||||||
DeclarationDescriptor effectiveReferencedDescriptor = getEffectiveReferencedDescriptor(referencedDescriptor);
|
DeclarationDescriptor effectiveReferencedDescriptor = getEffectiveReferencedDescriptor(referencedDescriptor);
|
||||||
VirtualFile virtualFile = findVirtualFileContainingDescriptor(project, effectiveReferencedDescriptor);
|
VirtualFile virtualFile = findVirtualFileContainingDescriptor(project, effectiveReferencedDescriptor);
|
||||||
|
|
||||||
if (virtualFile == null || !DecompiledUtils.isKotlinCompiledFile(virtualFile)) return null;
|
if (virtualFile == null || !DecompiledUtils.isKotlinCompiledFile(project, virtualFile)) return null;
|
||||||
|
|
||||||
JetDecompiledData data = JetDecompiledData.getDecompiledData(virtualFile, project);
|
JetDecompiledData data = JetDecompiledData.getDecompiledData(virtualFile, project);
|
||||||
JetDeclaration jetDeclaration = data.getDeclarationForDescriptor(effectiveReferencedDescriptor);
|
JetDeclaration jetDeclaration = data.getDeclarationForDescriptor(effectiveReferencedDescriptor);
|
||||||
|
|||||||
@@ -17,20 +17,23 @@
|
|||||||
package org.jetbrains.jet.plugin.libraries;
|
package org.jetbrains.jet.plugin.libraries;
|
||||||
|
|
||||||
import com.intellij.openapi.fileTypes.StdFileTypes;
|
import com.intellij.openapi.fileTypes.StdFileTypes;
|
||||||
|
import com.intellij.openapi.project.Project;
|
||||||
import com.intellij.openapi.vfs.VirtualFile;
|
import com.intellij.openapi.vfs.VirtualFile;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.jet.lang.resolve.kotlin.VirtualFileKotlinClass;
|
import org.jetbrains.jet.lang.resolve.kotlin.KotlinClassFinder;
|
||||||
|
import org.jetbrains.jet.lang.resolve.kotlin.KotlinJvmBinaryClass;
|
||||||
import org.jetbrains.jet.lang.resolve.kotlin.header.KotlinClassHeader;
|
import org.jetbrains.jet.lang.resolve.kotlin.header.KotlinClassHeader;
|
||||||
import org.jetbrains.jet.lang.resolve.kotlin.header.SerializedDataHeader;
|
import org.jetbrains.jet.lang.resolve.kotlin.header.SerializedDataHeader;
|
||||||
|
|
||||||
public final class DecompiledUtils {
|
public final class DecompiledUtils {
|
||||||
|
|
||||||
public static boolean isKotlinCompiledFile(@NotNull VirtualFile file) {
|
public static boolean isKotlinCompiledFile(@NotNull Project project, @NotNull VirtualFile file) {
|
||||||
if (!StdFileTypes.CLASS.getDefaultExtension().equals(file.getExtension())) {
|
if (!StdFileTypes.CLASS.getDefaultExtension().equals(file.getExtension())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
//TODO: check index
|
//TODO: check index
|
||||||
return KotlinClassHeader.read(new VirtualFileKotlinClass(file)) instanceof SerializedDataHeader;
|
KotlinJvmBinaryClass kotlinClass = KotlinClassFinder.SERVICE.getInstance(project).createKotlinClass(file);
|
||||||
|
return KotlinClassHeader.read(kotlinClass) instanceof SerializedDataHeader;
|
||||||
}
|
}
|
||||||
|
|
||||||
private DecompiledUtils() {
|
private DecompiledUtils() {
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ public final class JetContentBasedFileSubstitutor implements ContentBasedClassFi
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isApplicable(@Nullable Project project, @NotNull final VirtualFile file) {
|
public boolean isApplicable(@Nullable final Project project, @NotNull final VirtualFile file) {
|
||||||
if (project == null) {
|
if (project == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -76,7 +76,7 @@ public final class JetContentBasedFileSubstitutor implements ContentBasedClassFi
|
|||||||
DumbService.getInstance(project).runWhenSmart(new Runnable() {
|
DumbService.getInstance(project).runWhenSmart(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
if (DecompiledUtils.isKotlinCompiledFile(file)) {
|
if (DecompiledUtils.isKotlinCompiledFile(project, file)) {
|
||||||
FileDocumentManager docManager = FileDocumentManager.getInstance();
|
FileDocumentManager docManager = FileDocumentManager.getInstance();
|
||||||
docManager.getDocument(file); // force getting document because it can be collected
|
docManager.getDocument(file); // force getting document because it can be collected
|
||||||
docManager.reloadFiles(file);
|
docManager.reloadFiles(file);
|
||||||
@@ -86,13 +86,13 @@ public final class JetContentBasedFileSubstitutor implements ContentBasedClassFi
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return DecompiledUtils.isKotlinCompiledFile(file);
|
return DecompiledUtils.isKotlinCompiledFile(project, file);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public String obtainFileText(Project project, VirtualFile file) {
|
public String obtainFileText(Project project, VirtualFile file) {
|
||||||
if (file != null && DecompiledUtils.isKotlinCompiledFile(file)) {
|
if (file != null && DecompiledUtils.isKotlinCompiledFile(project, file)) {
|
||||||
JetDecompiledData data = JetDecompiledData.getDecompiledData(file, project);
|
JetDecompiledData data = JetDecompiledData.getDecompiledData(file, project);
|
||||||
deferredDocumentBinding.put(file, data.getFile());
|
deferredDocumentBinding.put(file, data.getFile());
|
||||||
|
|
||||||
|
|||||||
+4
-1
@@ -25,6 +25,7 @@ import com.intellij.psi.stubs.PsiFileStub;
|
|||||||
import com.intellij.util.cls.ClsFormatException;
|
import com.intellij.util.cls.ClsFormatException;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lang.resolve.java.PackageClassUtils;
|
import org.jetbrains.jet.lang.resolve.java.PackageClassUtils;
|
||||||
|
import org.jetbrains.jet.lang.resolve.kotlin.KotlinJvmBinaryClass;
|
||||||
import org.jetbrains.jet.lang.resolve.kotlin.VirtualFileKotlinClass;
|
import org.jetbrains.jet.lang.resolve.kotlin.VirtualFileKotlinClass;
|
||||||
import org.jetbrains.jet.lang.resolve.kotlin.header.KotlinClassHeader;
|
import org.jetbrains.jet.lang.resolve.kotlin.header.KotlinClassHeader;
|
||||||
import org.jetbrains.jet.lang.resolve.kotlin.header.PackageFragmentClassHeader;
|
import org.jetbrains.jet.lang.resolve.kotlin.header.PackageFragmentClassHeader;
|
||||||
@@ -34,6 +35,7 @@ import org.jetbrains.jet.lang.resolve.kotlin.header.PackageFragmentClassHeader;
|
|||||||
* in completion, go-to-class, etc.
|
* in completion, go-to-class, etc.
|
||||||
*/
|
*/
|
||||||
public class EmptyPackageFragmentClsStubBuilderFactory extends ClsStubBuilderFactory<PsiJavaFile> {
|
public class EmptyPackageFragmentClsStubBuilderFactory extends ClsStubBuilderFactory<PsiJavaFile> {
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public PsiFileStub<PsiJavaFile> buildFileStub(VirtualFile file, byte[] bytes) throws ClsFormatException {
|
public PsiFileStub<PsiJavaFile> buildFileStub(VirtualFile file, byte[] bytes) throws ClsFormatException {
|
||||||
@@ -44,7 +46,8 @@ public class EmptyPackageFragmentClsStubBuilderFactory extends ClsStubBuilderFac
|
|||||||
public boolean canBeProcessed(VirtualFile file, byte[] bytes) {
|
public boolean canBeProcessed(VirtualFile file, byte[] bytes) {
|
||||||
if (file.getName().contains(PackageClassUtils.PACKAGE_CLASS_NAME_SUFFIX + "-") &&
|
if (file.getName().contains(PackageClassUtils.PACKAGE_CLASS_NAME_SUFFIX + "-") &&
|
||||||
StdFileTypes.CLASS.getDefaultExtension().equals(file.getExtension())) {
|
StdFileTypes.CLASS.getDefaultExtension().equals(file.getExtension())) {
|
||||||
return KotlinClassHeader.read(new VirtualFileKotlinClass(file)) instanceof PackageFragmentClassHeader;
|
KotlinJvmBinaryClass kotlinClass = new VirtualFileKotlinClass(file);
|
||||||
|
return KotlinClassHeader.read(kotlinClass) instanceof PackageFragmentClassHeader;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,8 @@ import com.intellij.openapi.vfs.VirtualFile;
|
|||||||
import com.intellij.util.indexing.*;
|
import com.intellij.util.indexing.*;
|
||||||
import com.intellij.util.io.KeyDescriptor;
|
import com.intellij.util.io.KeyDescriptor;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.jet.lang.resolve.kotlin.VirtualFileKotlinClass;
|
import org.jetbrains.jet.lang.resolve.kotlin.KotlinClassFinder;
|
||||||
|
import org.jetbrains.jet.lang.resolve.kotlin.KotlinJvmBinaryClass;
|
||||||
import org.jetbrains.jet.lang.resolve.kotlin.header.IncompatibleAnnotationHeader;
|
import org.jetbrains.jet.lang.resolve.kotlin.header.IncompatibleAnnotationHeader;
|
||||||
import org.jetbrains.jet.lang.resolve.kotlin.header.KotlinClassHeader;
|
import org.jetbrains.jet.lang.resolve.kotlin.header.KotlinClassHeader;
|
||||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||||
@@ -75,7 +76,8 @@ public final class KotlinClassFileIndex extends ScalarIndexExtension<FqName> {
|
|||||||
@Override
|
@Override
|
||||||
public Map<FqName, Void> map(FileContent inputData) {
|
public Map<FqName, Void> map(FileContent inputData) {
|
||||||
try {
|
try {
|
||||||
VirtualFileKotlinClass kotlinClass = new VirtualFileKotlinClass(inputData.getFile());
|
KotlinJvmBinaryClass kotlinClass = KotlinClassFinder.SERVICE.getInstance(inputData.getProject())
|
||||||
|
.createKotlinClass(inputData.getFile());
|
||||||
KotlinClassHeader header = KotlinClassHeader.read(kotlinClass);
|
KotlinClassHeader header = KotlinClassHeader.read(kotlinClass);
|
||||||
if (header != null && !(header instanceof IncompatibleAnnotationHeader)) {
|
if (header != null && !(header instanceof IncompatibleAnnotationHeader)) {
|
||||||
return Collections.singletonMap(kotlinClass.getClassName().getFqNameForClassNameWithoutDollars(), null);
|
return Collections.singletonMap(kotlinClass.getClassName().getFqNameForClassNameWithoutDollars(), null);
|
||||||
|
|||||||
Reference in New Issue
Block a user