From 7eff1292f092310679b2260b8b4f8598cf429b38 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Fri, 20 Sep 2013 21:21:16 +0400 Subject: [PATCH] Make an abstraction over VirtualFileFinder Java descriptor loader now can work with KotlinClassFinder, which finds abstract KotlinJvmBinaryClass'es: they are based on VirtualFile in the compiler/IDE and will be based on j.l.Class in the reflection --- .../di/InjectorForJavaDescriptorResolver.java | 11 ++- .../di/InjectorForTopDownAnalyzerForJvm.java | 11 ++- .../resolve/kotlin/VirtualFileFinder.java | 0 .../kotlin/VirtualFileKotlinClass.java | 49 ++++++++++++++ .../kotlin/VirtualFileKotlinClassFinder.java | 40 +++++++++++ .../java/resolver/JavaClassResolver.java | 22 +++--- .../java/resolver/JavaNamespaceResolver.java | 16 ++--- .../AnnotationDescriptorDeserializer.java | 67 +++++++++---------- .../DeserializedDescriptorResolver.java | 15 ++--- .../resolve/kotlin/KotlinClassFinder.java | 26 +++++++ .../resolve/kotlin/KotlinJvmBinaryClass.java | 25 +++++++ .../injectors/GenerateInjectors.java | 3 + 12 files changed, 218 insertions(+), 67 deletions(-) rename {core/descriptor.loader.java => compiler/frontend.java}/src/org/jetbrains/jet/lang/resolve/kotlin/VirtualFileFinder.java (100%) create mode 100644 compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/kotlin/VirtualFileKotlinClass.java create mode 100644 compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/kotlin/VirtualFileKotlinClassFinder.java create mode 100644 core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/KotlinClassFinder.java create mode 100644 core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/KotlinJvmBinaryClass.java diff --git a/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForJavaDescriptorResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForJavaDescriptorResolver.java index 4736d9f6b4f..4522ace1698 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForJavaDescriptorResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForJavaDescriptorResolver.java @@ -26,6 +26,7 @@ import org.jetbrains.jet.lang.resolve.java.resolver.PsiBasedMethodSignatureCheck import org.jetbrains.jet.lang.resolve.java.resolver.PsiBasedExternalAnnotationResolver; import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver; import org.jetbrains.jet.lang.resolve.java.PsiClassFinderImpl; +import org.jetbrains.jet.lang.resolve.kotlin.VirtualFileKotlinClassFinder; import org.jetbrains.jet.lang.resolve.kotlin.VirtualFileFinder; import org.jetbrains.jet.lang.resolve.java.resolver.JavaAnnotationResolver; import org.jetbrains.jet.lang.resolve.java.resolver.JavaAnnotationArgumentResolver; @@ -57,6 +58,7 @@ public class InjectorForJavaDescriptorResolver { private final PsiBasedExternalAnnotationResolver psiBasedExternalAnnotationResolver; private final JavaDescriptorResolver javaDescriptorResolver; private final PsiClassFinderImpl psiClassFinder; + private final VirtualFileKotlinClassFinder virtualFileKotlinClassFinder; private final VirtualFileFinder virtualFileFinder; private final JavaAnnotationResolver javaAnnotationResolver; private final JavaAnnotationArgumentResolver javaAnnotationArgumentResolver; @@ -87,6 +89,7 @@ public class InjectorForJavaDescriptorResolver { this.psiBasedExternalAnnotationResolver = new PsiBasedExternalAnnotationResolver(); this.javaDescriptorResolver = new JavaDescriptorResolver(); this.psiClassFinder = new PsiClassFinderImpl(); + this.virtualFileKotlinClassFinder = new VirtualFileKotlinClassFinder(); this.virtualFileFinder = com.intellij.openapi.components.ServiceManager.getService(project, VirtualFileFinder.class); this.javaAnnotationResolver = new JavaAnnotationResolver(); this.javaAnnotationArgumentResolver = new JavaAnnotationArgumentResolver(); @@ -120,6 +123,8 @@ public class InjectorForJavaDescriptorResolver { this.psiClassFinder.setProject(project); + virtualFileKotlinClassFinder.setVirtualFileFinder(virtualFileFinder); + javaAnnotationResolver.setArgumentResolver(javaAnnotationArgumentResolver); javaAnnotationResolver.setClassResolver(javaClassResolver); javaAnnotationResolver.setExternalAnnotationResolver(psiBasedExternalAnnotationResolver); @@ -133,11 +138,11 @@ public class InjectorForJavaDescriptorResolver { javaClassResolver.setDeserializedDescriptorResolver(deserializedDescriptorResolver); javaClassResolver.setFunctionResolver(javaFunctionResolver); javaClassResolver.setJavaClassFinder(javaClassFinder); + javaClassResolver.setKotlinClassFinder(virtualFileKotlinClassFinder); javaClassResolver.setMemberResolver(javaMemberResolver); javaClassResolver.setNamespaceResolver(javaNamespaceResolver); javaClassResolver.setSupertypesResolver(javaSupertypeResolver); javaClassResolver.setTypeParameterResolver(javaTypeParameterResolver); - javaClassResolver.setVirtualFileFinder(virtualFileFinder); deserializedDescriptorResolver.setAnnotationDeserializer(annotationDescriptorDeserializer); deserializedDescriptorResolver.setErrorReporter(traceBasedErrorReporter); @@ -145,13 +150,13 @@ public class InjectorForJavaDescriptorResolver { deserializedDescriptorResolver.setJavaNamespaceResolver(javaNamespaceResolver); annotationDescriptorDeserializer.setJavaClassResolver(javaClassResolver); - annotationDescriptorDeserializer.setVirtualFileFinder(virtualFileFinder); + annotationDescriptorDeserializer.setKotlinClassFinder(virtualFileKotlinClassFinder); javaNamespaceResolver.setCache(traceBasedJavaResolverCache); javaNamespaceResolver.setDeserializedDescriptorResolver(deserializedDescriptorResolver); javaNamespaceResolver.setJavaClassFinder(javaClassFinder); + javaNamespaceResolver.setKotlinClassFinder(virtualFileKotlinClassFinder); javaNamespaceResolver.setMemberResolver(javaMemberResolver); - javaNamespaceResolver.setVirtualFileFinder(virtualFileFinder); javaMemberResolver.setClassResolver(javaClassResolver); javaMemberResolver.setConstructorResolver(javaConstructorResolver); diff --git a/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerForJvm.java b/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerForJvm.java index 39340de78d8..ac33935f9cf 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerForJvm.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerForJvm.java @@ -37,6 +37,7 @@ import org.jetbrains.jet.lang.resolve.java.resolver.TraceBasedJavaResolverCache; import org.jetbrains.jet.lang.resolve.java.resolver.TraceBasedErrorReporter; import org.jetbrains.jet.lang.resolve.java.resolver.PsiBasedMethodSignatureChecker; import org.jetbrains.jet.lang.resolve.java.resolver.PsiBasedExternalAnnotationResolver; +import org.jetbrains.jet.lang.resolve.kotlin.VirtualFileKotlinClassFinder; import org.jetbrains.jet.lang.resolve.NamespaceFactoryImpl; import org.jetbrains.jet.lang.resolve.kotlin.VirtualFileFinder; import org.jetbrains.jet.lang.resolve.DeclarationResolver; @@ -96,6 +97,7 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly private final TraceBasedErrorReporter traceBasedErrorReporter; private final PsiBasedMethodSignatureChecker psiBasedMethodSignatureChecker; private final PsiBasedExternalAnnotationResolver psiBasedExternalAnnotationResolver; + private final VirtualFileKotlinClassFinder virtualFileKotlinClassFinder; private final NamespaceFactoryImpl namespaceFactory; private final VirtualFileFinder virtualFileFinder; private final DeclarationResolver declarationResolver; @@ -156,6 +158,7 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly this.traceBasedErrorReporter = new TraceBasedErrorReporter(); this.psiBasedMethodSignatureChecker = new PsiBasedMethodSignatureChecker(); this.psiBasedExternalAnnotationResolver = new PsiBasedExternalAnnotationResolver(); + this.virtualFileKotlinClassFinder = new VirtualFileKotlinClassFinder(); this.namespaceFactory = new NamespaceFactoryImpl(); this.virtualFileFinder = com.intellij.openapi.components.ServiceManager.getService(project, VirtualFileFinder.class); this.declarationResolver = new DeclarationResolver(); @@ -241,6 +244,8 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly psiBasedMethodSignatureChecker.setAnnotationResolver(javaAnnotationResolver); psiBasedMethodSignatureChecker.setExternalSignatureResolver(traceBasedExternalSignatureResolver); + virtualFileKotlinClassFinder.setVirtualFileFinder(virtualFileFinder); + this.namespaceFactory.setModuleDescriptor(moduleDescriptor); this.namespaceFactory.setTrace(bindingTrace); @@ -316,11 +321,11 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly javaClassResolver.setDeserializedDescriptorResolver(deserializedDescriptorResolver); javaClassResolver.setFunctionResolver(javaFunctionResolver); javaClassResolver.setJavaClassFinder(javaClassFinder); + javaClassResolver.setKotlinClassFinder(virtualFileKotlinClassFinder); javaClassResolver.setMemberResolver(javaMemberResolver); javaClassResolver.setNamespaceResolver(javaNamespaceResolver); javaClassResolver.setSupertypesResolver(javaSupertypeResolver); javaClassResolver.setTypeParameterResolver(javaTypeParameterResolver); - javaClassResolver.setVirtualFileFinder(virtualFileFinder); javaAnnotationResolver.setArgumentResolver(javaAnnotationArgumentResolver); javaAnnotationResolver.setClassResolver(javaClassResolver); @@ -338,13 +343,13 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly deserializedDescriptorResolver.setJavaNamespaceResolver(javaNamespaceResolver); annotationDescriptorDeserializer.setJavaClassResolver(javaClassResolver); - annotationDescriptorDeserializer.setVirtualFileFinder(virtualFileFinder); + annotationDescriptorDeserializer.setKotlinClassFinder(virtualFileKotlinClassFinder); javaNamespaceResolver.setCache(traceBasedJavaResolverCache); javaNamespaceResolver.setDeserializedDescriptorResolver(deserializedDescriptorResolver); javaNamespaceResolver.setJavaClassFinder(javaClassFinder); + javaNamespaceResolver.setKotlinClassFinder(virtualFileKotlinClassFinder); javaNamespaceResolver.setMemberResolver(javaMemberResolver); - javaNamespaceResolver.setVirtualFileFinder(virtualFileFinder); javaMemberResolver.setClassResolver(javaClassResolver); javaMemberResolver.setConstructorResolver(javaConstructorResolver); diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/VirtualFileFinder.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/kotlin/VirtualFileFinder.java similarity index 100% rename from core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/VirtualFileFinder.java rename to compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/kotlin/VirtualFileFinder.java diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/kotlin/VirtualFileKotlinClass.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/kotlin/VirtualFileKotlinClass.java new file mode 100644 index 00000000000..939b5484818 --- /dev/null +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/kotlin/VirtualFileKotlinClass.java @@ -0,0 +1,49 @@ +/* + * Copyright 2010-2013 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.jet.lang.resolve.kotlin; + +import com.intellij.openapi.vfs.VirtualFile; +import org.jetbrains.annotations.NotNull; + +public class VirtualFileKotlinClass implements KotlinJvmBinaryClass { + private final VirtualFile file; + + public VirtualFileKotlinClass(@NotNull VirtualFile file) { + this.file = file; + } + + @NotNull + @Override + public VirtualFile getFile() { + return file; + } + + @Override + public int hashCode() { + return file.hashCode(); + } + + @Override + public boolean equals(Object obj) { + return obj instanceof VirtualFileKotlinClass && ((VirtualFileKotlinClass) obj).file.equals(file); + } + + @Override + public String toString() { + return getClass().getSimpleName() + ": " + file.toString(); + } +} diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/kotlin/VirtualFileKotlinClassFinder.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/kotlin/VirtualFileKotlinClassFinder.java new file mode 100644 index 00000000000..43ae75ffb11 --- /dev/null +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/kotlin/VirtualFileKotlinClassFinder.java @@ -0,0 +1,40 @@ +/* + * Copyright 2010-2013 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.jet.lang.resolve.kotlin; + +import com.intellij.openapi.vfs.VirtualFile; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.resolve.name.FqName; + +import javax.inject.Inject; + +public class VirtualFileKotlinClassFinder implements KotlinClassFinder { + private VirtualFileFinder virtualFileFinder; + + @Inject + public void setVirtualFileFinder(@NotNull VirtualFileFinder virtualFileFinder) { + this.virtualFileFinder = virtualFileFinder; + } + + @Nullable + @Override + public KotlinJvmBinaryClass find(@NotNull FqName fqName) { + VirtualFile file = virtualFileFinder.find(fqName); + return file == null ? null : new VirtualFileKotlinClass(file); + } +} diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaClassResolver.java b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaClassResolver.java index 6759ecf63f4..ccb0ec2449d 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaClassResolver.java +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaClassResolver.java @@ -18,7 +18,6 @@ package org.jetbrains.jet.lang.resolve.java.resolver; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.*; @@ -34,7 +33,8 @@ import org.jetbrains.jet.lang.resolve.java.scope.JavaClassNonStaticMembersScope; import org.jetbrains.jet.lang.resolve.java.structure.JavaClass; import org.jetbrains.jet.lang.resolve.java.structure.JavaMethod; import org.jetbrains.jet.lang.resolve.kotlin.DeserializedDescriptorResolver; -import org.jetbrains.jet.lang.resolve.kotlin.VirtualFileFinder; +import org.jetbrains.jet.lang.resolve.kotlin.KotlinClassFinder; +import org.jetbrains.jet.lang.resolve.kotlin.KotlinJvmBinaryClass; import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe; import org.jetbrains.jet.lang.resolve.name.Name; @@ -71,16 +71,11 @@ public final class JavaClassResolver { private JavaSupertypeResolver supertypesResolver; private JavaFunctionResolver functionResolver; private DeserializedDescriptorResolver deserializedDescriptorResolver; - private VirtualFileFinder virtualFileFinder; + private KotlinClassFinder kotlinClassFinder; public JavaClassResolver() { } - @Inject - public void setVirtualFileFinder(VirtualFileFinder virtualFileFinder) { - this.virtualFileFinder = virtualFileFinder; - } - @Inject public void setCache(JavaResolverCache cache) { this.cache = cache; @@ -126,6 +121,11 @@ public final class JavaClassResolver { this.functionResolver = functionResolver; } + @Inject + public void setKotlinClassFinder(KotlinClassFinder kotlinClassFinder) { + this.kotlinClassFinder = kotlinClassFinder; + } + @Nullable public ClassDescriptor resolveClass(@NotNull FqName qualifiedName, @NotNull DescriptorSearchRule searchRule) { PostponedTasks postponedTasks = new PostponedTasks(); @@ -189,9 +189,9 @@ public final class JavaClassResolver { private ClassDescriptor doResolveClass(@NotNull FqName qualifiedName, @NotNull PostponedTasks tasks) { //TODO: correct scope - VirtualFile file = virtualFileFinder.find(qualifiedName); - if (file != null) { - ClassDescriptor deserializedDescriptor = deserializedDescriptorResolver.resolveClass(file); + KotlinJvmBinaryClass kotlinClass = kotlinClassFinder.find(qualifiedName); + if (kotlinClass != null) { + ClassDescriptor deserializedDescriptor = deserializedDescriptorResolver.resolveClass(kotlinClass); if (deserializedDescriptor != null) { cache(javaClassToKotlinFqName(qualifiedName), deserializedDescriptor); return deserializedDescriptor; diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaNamespaceResolver.java b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaNamespaceResolver.java index 78a1c0e4103..22585723388 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaNamespaceResolver.java +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaNamespaceResolver.java @@ -16,7 +16,6 @@ package org.jetbrains.jet.lang.resolve.java.resolver; -import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.ModuleDescriptor; @@ -36,7 +35,8 @@ import org.jetbrains.jet.lang.resolve.java.structure.JavaField; import org.jetbrains.jet.lang.resolve.java.structure.JavaMethod; import org.jetbrains.jet.lang.resolve.java.structure.JavaPackage; import org.jetbrains.jet.lang.resolve.kotlin.DeserializedDescriptorResolver; -import org.jetbrains.jet.lang.resolve.kotlin.VirtualFileFinder; +import org.jetbrains.jet.lang.resolve.kotlin.KotlinClassFinder; +import org.jetbrains.jet.lang.resolve.kotlin.KotlinJvmBinaryClass; import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.scopes.JetScope; @@ -62,11 +62,11 @@ public final class JavaNamespaceResolver { private JavaMemberResolver memberResolver; private DeserializedDescriptorResolver deserializedDescriptorResolver; - private VirtualFileFinder virtualFileFinder; + private KotlinClassFinder kotlinClassFinder; @Inject - public void setVirtualFileFinder(VirtualFileFinder virtualFileFinder) { - this.virtualFileFinder = virtualFileFinder; + public void setKotlinClassFinder(KotlinClassFinder kotlinClassFinder) { + this.kotlinClassFinder = kotlinClassFinder; } @Inject @@ -153,12 +153,12 @@ public final class JavaNamespaceResolver { JavaPackage javaPackage = javaClassFinder.findPackage(fqName); if (javaPackage != null) { FqName packageClassFqName = PackageClassUtils.getPackageClassFqName(fqName); - VirtualFile virtualFile = virtualFileFinder.find(packageClassFqName); + KotlinJvmBinaryClass kotlinClass = kotlinClassFinder.find(packageClassFqName); cache.recordProperNamespace(namespaceDescriptor); - if (virtualFile != null) { - JetScope kotlinPackageScope = deserializedDescriptorResolver.createKotlinPackageScope(namespaceDescriptor, virtualFile); + if (kotlinClass != null) { + JetScope kotlinPackageScope = deserializedDescriptorResolver.createKotlinPackageScope(namespaceDescriptor, kotlinClass); if (kotlinPackageScope != null) { return kotlinPackageScope; } diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/AnnotationDescriptorDeserializer.java b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/AnnotationDescriptorDeserializer.java index 8aba49d5f5e..8616b795382 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/AnnotationDescriptorDeserializer.java +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/AnnotationDescriptorDeserializer.java @@ -17,7 +17,6 @@ package org.jetbrains.jet.lang.resolve.kotlin; import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.asm4.*; @@ -57,64 +56,63 @@ public class AnnotationDescriptorDeserializer implements AnnotationDeserializer private static final Logger LOG = Logger.getInstance(AnnotationDescriptorDeserializer.class); private JavaClassResolver javaClassResolver; - - private VirtualFileFinder virtualFileFinder; + private KotlinClassFinder kotlinClassFinder; // TODO: a single instance of StorageManager for all computations in resolve-java private final LockBasedStorageManager storageManager = new LockBasedStorageManager(); - private final MemoizedFunctionToNotNull>> memberAnnotations = + private final MemoizedFunctionToNotNull>> memberAnnotations = storageManager.createMemoizedFunction( - new MemoizedFunctionToNotNull>>() { + new MemoizedFunctionToNotNull>>() { @NotNull @Override - public Map> fun(@NotNull VirtualFile file) { + public Map> fun(@NotNull KotlinJvmBinaryClass kotlinClass) { try { - return loadMemberAnnotationsFromFile(file); + return loadMemberAnnotationsFromClass(kotlinClass); } catch (IOException e) { - LOG.error("Error loading member annotations from file: " + file, e); + LOG.error("Error loading member annotations from Kotlin class: " + kotlinClass, e); return Collections.emptyMap(); } } }, StorageManager.ReferenceKind.STRONG); @Inject - public void setVirtualFileFinder(VirtualFileFinder virtualFileFinder) { - this.virtualFileFinder = virtualFileFinder; + public void setJavaClassResolver(JavaClassResolver javaClassResolver) { + this.javaClassResolver = javaClassResolver; } @Inject - public void setJavaClassResolver(JavaClassResolver javaClassResolver) { - this.javaClassResolver = javaClassResolver; + public void setKotlinClassFinder(KotlinClassFinder kotlinClassFinder) { + this.kotlinClassFinder = kotlinClassFinder; } @NotNull @Override public List loadClassAnnotations(@NotNull ClassDescriptor descriptor, @NotNull ProtoBuf.Class classProto) { - VirtualFile virtualFile = findVirtualFileByDescriptor(descriptor); - if (virtualFile == null) { - // This means that the resource we're constructing the descriptor from is no longer present: VirtualFileFinder had found the - // file earlier, but it can't now - LOG.error("Virtual file for loading class annotations is not found: " + descriptor); + KotlinJvmBinaryClass kotlinClass = findKotlinClassByDescriptor(descriptor); + if (kotlinClass == null) { + // This means that the resource we're constructing the descriptor from is no longer present: KotlinClassFinder had found the + // class earlier, but it can't now + LOG.error("Kotlin class for loading class annotations is not found: " + descriptor); return Collections.emptyList(); } try { - return loadClassAnnotationsFromFile(virtualFile); + return loadClassAnnotationsFromClass(kotlinClass); } catch (IOException e) { - LOG.error("Error loading member annotations from file: " + virtualFile, e); + LOG.error("Error loading member annotations from Kotlin class: " + kotlinClass, e); return Collections.emptyList(); } } @Nullable - private VirtualFile findVirtualFileByDescriptor(@NotNull ClassOrNamespaceDescriptor descriptor) { + private KotlinJvmBinaryClass findKotlinClassByDescriptor(@NotNull ClassOrNamespaceDescriptor descriptor) { if (descriptor instanceof ClassDescriptor) { - return virtualFileFinder.find(kotlinFqNameToJavaFqName(naiveKotlinFqName((ClassDescriptor) descriptor))); + return kotlinClassFinder.find(kotlinFqNameToJavaFqName(naiveKotlinFqName((ClassDescriptor) descriptor))); } else if (descriptor instanceof NamespaceDescriptor) { - return virtualFileFinder.find(PackageClassUtils.getPackageClassFqName(DescriptorUtils.getFQName(descriptor).toSafe())); + return kotlinClassFinder.find(PackageClassUtils.getPackageClassFqName(DescriptorUtils.getFQName(descriptor).toSafe())); } else { throw new IllegalStateException("Unrecognized descriptor: " + descriptor); @@ -122,10 +120,10 @@ public class AnnotationDescriptorDeserializer implements AnnotationDeserializer } @NotNull - private List loadClassAnnotationsFromFile(@NotNull VirtualFile virtualFile) throws IOException { + private List loadClassAnnotationsFromClass(@NotNull KotlinJvmBinaryClass kotlinClass) throws IOException { final List result = new ArrayList(); - new ClassReader(virtualFile.contentsToByteArray()).accept(new ClassVisitor(Opcodes.ASM4) { + new ClassReader(kotlinClass.getFile().contentsToByteArray()).accept(new ClassVisitor(Opcodes.ASM4) { @Override public AnnotationVisitor visitAnnotation(String desc, boolean visible) { return resolveAnnotation(desc, result); @@ -222,17 +220,17 @@ public class AnnotationDescriptorDeserializer implements AnnotationDeserializer MemberSignature signature = getCallableSignature(proto, nameResolver, kind); if (signature == null) return Collections.emptyList(); - VirtualFile file = getVirtualFileWithMemberAnnotations(container, proto, nameResolver); - if (file == null) { - LOG.error("Virtual file for loading member annotations is not found: " + container); + KotlinJvmBinaryClass kotlinClass = findClassWithMemberAnnotations(container, proto, nameResolver); + if (kotlinClass == null) { + LOG.error("Kotlin class for loading member annotations is not found: " + container); } - List annotations = memberAnnotations.fun(file).get(signature); + List annotations = memberAnnotations.fun(kotlinClass).get(signature); return annotations == null ? Collections.emptyList() : annotations; } @Nullable - private VirtualFile getVirtualFileWithMemberAnnotations( + private KotlinJvmBinaryClass findClassWithMemberAnnotations( @NotNull ClassOrNamespaceDescriptor container, @NotNull ProtoBuf.Callable proto, @NotNull NameResolver nameResolver @@ -240,18 +238,18 @@ public class AnnotationDescriptorDeserializer implements AnnotationDeserializer if (container instanceof NamespaceDescriptor) { Name name = loadSrcClassName(proto, nameResolver); if (name != null) { - return virtualFileFinder.find(getSrcClassFqName((NamespaceDescriptor) container, name)); + return kotlinClassFinder.find(getSrcClassFqName((NamespaceDescriptor) container, name)); } return null; } else if (container instanceof ClassDescriptor && ((ClassDescriptor) container).getKind() == ClassKind.CLASS_OBJECT) { // Backing fields of properties of a class object are generated in the outer class if (isStaticFieldInOuter(proto)) { - return findVirtualFileByDescriptor((ClassOrNamespaceDescriptor) container.getContainingDeclaration()); + return findKotlinClassByDescriptor((ClassOrNamespaceDescriptor) container.getContainingDeclaration()); } } - return findVirtualFileByDescriptor(container); + return findKotlinClassByDescriptor(container); } @NotNull @@ -316,11 +314,12 @@ public class AnnotationDescriptorDeserializer implements AnnotationDeserializer } @NotNull - private Map> loadMemberAnnotationsFromFile(@NotNull VirtualFile file) throws IOException { + private Map> loadMemberAnnotationsFromClass(@NotNull KotlinJvmBinaryClass kotlinClass) + throws IOException { final Map> memberAnnotations = new HashMap>(); - new ClassReader(file.contentsToByteArray()).accept(new ClassVisitor(Opcodes.ASM4) { + new ClassReader(kotlinClass.getFile().contentsToByteArray()).accept(new ClassVisitor(Opcodes.ASM4) { @Override public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { final MemberSignature methodSignature = MemberSignature.fromMethodNameAndDesc(name, desc); diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/DeserializedDescriptorResolver.java b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/DeserializedDescriptorResolver.java index 4a09f5c3cbc..38d345a6329 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/DeserializedDescriptorResolver.java +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/DeserializedDescriptorResolver.java @@ -16,7 +16,6 @@ package org.jetbrains.jet.lang.resolve.kotlin; -import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.descriptors.serialization.ClassId; @@ -96,28 +95,28 @@ public final class DeserializedDescriptorResolver { } @Nullable - public ClassDescriptor resolveClass(@NotNull VirtualFile virtualFile) { - String[] data = readData(virtualFile); + public ClassDescriptor resolveClass(@NotNull KotlinJvmBinaryClass kotlinClass) { + String[] data = readData(kotlinClass); return data == null ? null : new DeserializedClassDescriptor(storageManager, annotationDeserializer, javaDescriptorFinder, JavaProtoBufUtil.readClassDataFrom(data)); } @Nullable - public JetScope createKotlinPackageScope(@NotNull NamespaceDescriptor descriptor, @NotNull VirtualFile virtualFile) { - String[] data = readData(virtualFile); + public JetScope createKotlinPackageScope(@NotNull NamespaceDescriptor descriptor, @NotNull KotlinJvmBinaryClass kotlinClass) { + String[] data = readData(kotlinClass); return data == null ? null : new DeserializedPackageMemberScope(storageManager, descriptor, annotationDeserializer, javaDescriptorFinder, JavaProtoBufUtil.readPackageDataFrom(data)); } @Nullable - private String[] readData(@NotNull VirtualFile virtualFile) { - KotlinClassFileHeader header = KotlinClassFileHeader.readKotlinHeaderFromClassFile(virtualFile); + private String[] readData(@NotNull KotlinJvmBinaryClass kotlinClass) { + KotlinClassFileHeader header = KotlinClassFileHeader.readKotlinHeaderFromClassFile(kotlinClass.getFile()); if (header instanceof SerializedDataHeader) { return ((SerializedDataHeader) header).getAnnotationData(); } if (header != null) { - errorReporter.reportIncompatibleAbiVersion(header.getFqName(), virtualFile, header.getVersion()); + errorReporter.reportIncompatibleAbiVersion(header.getFqName(), kotlinClass.getFile(), header.getVersion()); } return null; diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/KotlinClassFinder.java b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/KotlinClassFinder.java new file mode 100644 index 00000000000..e7a95e556dc --- /dev/null +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/KotlinClassFinder.java @@ -0,0 +1,26 @@ +/* + * Copyright 2010-2013 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.jet.lang.resolve.kotlin; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.resolve.name.FqName; + +public interface KotlinClassFinder { + @Nullable + KotlinJvmBinaryClass find(@NotNull FqName fqName); +} diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/KotlinJvmBinaryClass.java b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/KotlinJvmBinaryClass.java new file mode 100644 index 00000000000..b4b70d89477 --- /dev/null +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/KotlinJvmBinaryClass.java @@ -0,0 +1,25 @@ +/* + * Copyright 2010-2013 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.jet.lang.resolve.kotlin; + +import com.intellij.openapi.vfs.VirtualFile; +import org.jetbrains.annotations.NotNull; + +public interface KotlinJvmBinaryClass { + @NotNull + VirtualFile getFile(); +} diff --git a/generators/src/org/jetbrains/jet/generators/injectors/GenerateInjectors.java b/generators/src/org/jetbrains/jet/generators/injectors/GenerateInjectors.java index cbb3fefadf2..96e45c62cc2 100644 --- a/generators/src/org/jetbrains/jet/generators/injectors/GenerateInjectors.java +++ b/generators/src/org/jetbrains/jet/generators/injectors/GenerateInjectors.java @@ -41,6 +41,7 @@ import org.jetbrains.jet.lang.resolve.java.PsiClassFinderImpl; import org.jetbrains.jet.lang.resolve.java.mapping.JavaToKotlinClassMap; import org.jetbrains.jet.lang.resolve.java.resolver.*; import org.jetbrains.jet.lang.resolve.kotlin.VirtualFileFinder; +import org.jetbrains.jet.lang.resolve.kotlin.VirtualFileKotlinClassFinder; import org.jetbrains.jet.lang.resolve.lazy.ResolveSession; import org.jetbrains.jet.lang.resolve.lazy.ScopeProvider; import org.jetbrains.jet.lang.types.DependencyClassByQualifiedNameResolverDummyImpl; @@ -130,6 +131,7 @@ public class GenerateInjectors { generator.addField(TraceBasedErrorReporter.class); generator.addField(PsiBasedMethodSignatureChecker.class); generator.addField(PsiBasedExternalAnnotationResolver.class); + generator.addField(VirtualFileKotlinClassFinder.class); generator.addPublicField(NamespaceFactoryImpl.class); generator.addField(false, VirtualFileFinder.class, "virtualFileFinder", new GivenExpression( @@ -155,6 +157,7 @@ public class GenerateInjectors { generator.addField(PsiBasedExternalAnnotationResolver.class); generator.addPublicField(JavaDescriptorResolver.class); generator.addPublicField(PsiClassFinderImpl.class); + generator.addField(VirtualFileKotlinClassFinder.class); generator.addField(false, VirtualFileFinder.class, "virtualFileFinder", new GivenExpression("com.intellij.openapi.components.ServiceManager.getService(project, VirtualFileFinder.class)"));