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 1861affcc4f..0164eca07e6 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForJavaDescriptorResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForJavaDescriptorResolver.java @@ -32,7 +32,9 @@ import org.jetbrains.jet.lang.resolve.kotlin.VirtualFileFinder; import org.jetbrains.jet.lang.resolve.java.lazy.LazyJavaPackageFragmentProvider; import org.jetbrains.jet.lang.resolve.java.lazy.GlobalJavaResolverContext; import org.jetbrains.jet.lang.resolve.kotlin.DeserializedDescriptorResolver; +import org.jetbrains.jet.lang.resolve.kotlin.DescriptorDeserializers; import org.jetbrains.jet.lang.resolve.kotlin.AnnotationDescriptorDeserializer; +import org.jetbrains.jet.lang.resolve.kotlin.DescriptorDeserializersStorage; import org.jetbrains.annotations.NotNull; import javax.annotation.PreDestroy; @@ -56,7 +58,9 @@ public class InjectorForJavaDescriptorResolver { private final LazyJavaPackageFragmentProvider lazyJavaPackageFragmentProvider; private final GlobalJavaResolverContext globalJavaResolverContext; private final DeserializedDescriptorResolver deserializedDescriptorResolver; + private final DescriptorDeserializers descriptorDeserializers; private final AnnotationDescriptorDeserializer annotationDescriptorDeserializer; + private final DescriptorDeserializersStorage descriptorDeserializersStorage; public InjectorForJavaDescriptorResolver( @NotNull Project project, @@ -78,7 +82,9 @@ public class InjectorForJavaDescriptorResolver { this.globalJavaResolverContext = new GlobalJavaResolverContext(lockBasedStorageManager, getJavaClassFinder(), virtualFileFinder, deserializedDescriptorResolver, psiBasedExternalAnnotationResolver, traceBasedExternalSignatureResolver, traceBasedErrorReporter, psiBasedMethodSignatureChecker, traceBasedJavaResolverCache); this.lazyJavaPackageFragmentProvider = new LazyJavaPackageFragmentProvider(globalJavaResolverContext, getModule()); this.javaDescriptorResolver = new JavaDescriptorResolver(lazyJavaPackageFragmentProvider, getModule()); - this.annotationDescriptorDeserializer = new AnnotationDescriptorDeserializer(lockBasedStorageManager); + this.descriptorDeserializers = new DescriptorDeserializers(); + this.annotationDescriptorDeserializer = new AnnotationDescriptorDeserializer(); + this.descriptorDeserializersStorage = new DescriptorDeserializersStorage(lockBasedStorageManager); this.javaClassFinder.setProject(project); @@ -92,15 +98,21 @@ public class InjectorForJavaDescriptorResolver { psiBasedMethodSignatureChecker.setExternalAnnotationResolver(psiBasedExternalAnnotationResolver); psiBasedMethodSignatureChecker.setExternalSignatureResolver(traceBasedExternalSignatureResolver); - deserializedDescriptorResolver.setAnnotationDeserializer(annotationDescriptorDeserializer); + deserializedDescriptorResolver.setAnnotationDeserializer(descriptorDeserializers); deserializedDescriptorResolver.setErrorReporter(traceBasedErrorReporter); deserializedDescriptorResolver.setJavaDescriptorResolver(javaDescriptorResolver); deserializedDescriptorResolver.setJavaPackageFragmentProvider(lazyJavaPackageFragmentProvider); deserializedDescriptorResolver.setStorageManager(lockBasedStorageManager); + descriptorDeserializers.setAnnotationDescriptorDeserializer(annotationDescriptorDeserializer); + annotationDescriptorDeserializer.setClassResolver(javaDescriptorResolver); annotationDescriptorDeserializer.setErrorReporter(traceBasedErrorReporter); annotationDescriptorDeserializer.setKotlinClassFinder(virtualFileFinder); + annotationDescriptorDeserializer.setStorage(descriptorDeserializersStorage); + + descriptorDeserializersStorage.setClassResolver(javaDescriptorResolver); + descriptorDeserializersStorage.setErrorReporter(traceBasedErrorReporter); javaClassFinder.initialize(); diff --git a/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForLazyResolveWithJava.java b/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForLazyResolveWithJava.java index 987de5fb7f1..7bdc798dc77 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForLazyResolveWithJava.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForLazyResolveWithJava.java @@ -52,7 +52,9 @@ import org.jetbrains.jet.lang.resolve.lazy.ScopeProvider; import org.jetbrains.jet.lang.resolve.java.lazy.LazyJavaPackageFragmentProvider; import org.jetbrains.jet.lang.resolve.java.lazy.GlobalJavaResolverContext; import org.jetbrains.jet.lang.resolve.kotlin.DeserializedDescriptorResolver; +import org.jetbrains.jet.lang.resolve.kotlin.DescriptorDeserializers; import org.jetbrains.jet.lang.resolve.kotlin.AnnotationDescriptorDeserializer; +import org.jetbrains.jet.lang.resolve.kotlin.DescriptorDeserializersStorage; import org.jetbrains.annotations.NotNull; import javax.annotation.PreDestroy; @@ -96,7 +98,9 @@ public class InjectorForLazyResolveWithJava { private final LazyJavaPackageFragmentProvider lazyJavaPackageFragmentProvider; private final GlobalJavaResolverContext globalJavaResolverContext; private final DeserializedDescriptorResolver deserializedDescriptorResolver; + private final DescriptorDeserializers descriptorDeserializers; private final AnnotationDescriptorDeserializer annotationDescriptorDeserializer; + private final DescriptorDeserializersStorage descriptorDeserializersStorage; public InjectorForLazyResolveWithJava( @NotNull Project project, @@ -140,7 +144,9 @@ public class InjectorForLazyResolveWithJava { this.candidateResolver = new CandidateResolver(); this.jetImportsFactory = new JetImportsFactory(); this.scopeProvider = new ScopeProvider(getResolveSession()); - this.annotationDescriptorDeserializer = new AnnotationDescriptorDeserializer(lockBasedStorageManager); + this.descriptorDeserializers = new DescriptorDeserializers(); + this.annotationDescriptorDeserializer = new AnnotationDescriptorDeserializer(); + this.descriptorDeserializersStorage = new DescriptorDeserializersStorage(lockBasedStorageManager); this.resolveSession.setAnnotationResolve(annotationResolver); this.resolveSession.setDescriptorResolver(descriptorResolver); @@ -211,15 +217,21 @@ public class InjectorForLazyResolveWithJava { jetImportsFactory.setProject(project); - deserializedDescriptorResolver.setAnnotationDeserializer(annotationDescriptorDeserializer); + deserializedDescriptorResolver.setAnnotationDeserializer(descriptorDeserializers); deserializedDescriptorResolver.setErrorReporter(traceBasedErrorReporter); deserializedDescriptorResolver.setJavaDescriptorResolver(javaDescriptorResolver); deserializedDescriptorResolver.setJavaPackageFragmentProvider(lazyJavaPackageFragmentProvider); deserializedDescriptorResolver.setStorageManager(lockBasedStorageManager); + descriptorDeserializers.setAnnotationDescriptorDeserializer(annotationDescriptorDeserializer); + annotationDescriptorDeserializer.setClassResolver(javaDescriptorResolver); annotationDescriptorDeserializer.setErrorReporter(traceBasedErrorReporter); annotationDescriptorDeserializer.setKotlinClassFinder(virtualFileFinder); + annotationDescriptorDeserializer.setStorage(descriptorDeserializersStorage); + + descriptorDeserializersStorage.setClassResolver(javaDescriptorResolver); + descriptorDeserializersStorage.setErrorReporter(traceBasedErrorReporter); javaClassFinder.initialize(); 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 8415b35e6c7..c7163b5f8ce 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerForJvm.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerForJvm.java @@ -62,7 +62,9 @@ import org.jetbrains.jet.lang.resolve.TypeHierarchyResolver; import org.jetbrains.jet.lang.resolve.java.lazy.LazyJavaPackageFragmentProvider; import org.jetbrains.jet.lang.resolve.java.lazy.GlobalJavaResolverContext; import org.jetbrains.jet.lang.resolve.kotlin.DeserializedDescriptorResolver; +import org.jetbrains.jet.lang.resolve.kotlin.DescriptorDeserializers; import org.jetbrains.jet.lang.resolve.kotlin.AnnotationDescriptorDeserializer; +import org.jetbrains.jet.lang.resolve.kotlin.DescriptorDeserializersStorage; import org.jetbrains.annotations.NotNull; import javax.annotation.PreDestroy; @@ -116,7 +118,9 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly private final LazyJavaPackageFragmentProvider lazyJavaPackageFragmentProvider; private final GlobalJavaResolverContext globalJavaResolverContext; private final DeserializedDescriptorResolver deserializedDescriptorResolver; + private final DescriptorDeserializers descriptorDeserializers; private final AnnotationDescriptorDeserializer annotationDescriptorDeserializer; + private final DescriptorDeserializersStorage descriptorDeserializersStorage; public InjectorForTopDownAnalyzerForJvm( @NotNull Project project, @@ -170,7 +174,9 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly this.overloadResolver = new OverloadResolver(); this.overrideResolver = new OverrideResolver(); this.typeHierarchyResolver = new TypeHierarchyResolver(); - this.annotationDescriptorDeserializer = new AnnotationDescriptorDeserializer(storageManager); + this.descriptorDeserializers = new DescriptorDeserializers(); + this.annotationDescriptorDeserializer = new AnnotationDescriptorDeserializer(); + this.descriptorDeserializersStorage = new DescriptorDeserializersStorage(storageManager); this.topDownAnalyzer.setBodyResolver(bodyResolver); this.topDownAnalyzer.setDeclarationResolver(declarationResolver); @@ -286,15 +292,21 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly typeHierarchyResolver.setScriptHeaderResolver(scriptHeaderResolver); typeHierarchyResolver.setTrace(bindingTrace); - deserializedDescriptorResolver.setAnnotationDeserializer(annotationDescriptorDeserializer); + deserializedDescriptorResolver.setAnnotationDeserializer(descriptorDeserializers); deserializedDescriptorResolver.setErrorReporter(traceBasedErrorReporter); deserializedDescriptorResolver.setJavaDescriptorResolver(javaDescriptorResolver); deserializedDescriptorResolver.setJavaPackageFragmentProvider(lazyJavaPackageFragmentProvider); deserializedDescriptorResolver.setStorageManager(storageManager); + descriptorDeserializers.setAnnotationDescriptorDeserializer(annotationDescriptorDeserializer); + annotationDescriptorDeserializer.setClassResolver(javaDescriptorResolver); annotationDescriptorDeserializer.setErrorReporter(traceBasedErrorReporter); annotationDescriptorDeserializer.setKotlinClassFinder(virtualFileFinder); + annotationDescriptorDeserializer.setStorage(descriptorDeserializersStorage); + + descriptorDeserializersStorage.setClassResolver(javaDescriptorResolver); + descriptorDeserializersStorage.setErrorReporter(traceBasedErrorReporter); javaClassFinder.initialize(); diff --git a/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/AbstractDescriptorFinder.java b/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/AbstractDescriptorFinder.java index fd92b41f0ef..27a2eeb9123 100644 --- a/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/AbstractDescriptorFinder.java +++ b/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/AbstractDescriptorFinder.java @@ -19,7 +19,7 @@ package org.jetbrains.jet.descriptors.serialization; import kotlin.Function1; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.jet.descriptors.serialization.descriptors.AnnotationDeserializer; +import org.jetbrains.jet.descriptors.serialization.descriptors.Deserializers; import org.jetbrains.jet.descriptors.serialization.descriptors.DeserializedClassDescriptor; import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.PackageFragmentProvider; @@ -28,14 +28,14 @@ import org.jetbrains.jet.storage.StorageManager; public abstract class AbstractDescriptorFinder implements DescriptorFinder { private final MemoizedFunctionToNullable findClass; - private final AnnotationDeserializer annotationDeserializer; + private final Deserializers deserializers; public AbstractDescriptorFinder( @NotNull final StorageManager storageManager, - @NotNull AnnotationDeserializer annotationDeserializer, + @NotNull Deserializers deserializers, @NotNull final PackageFragmentProvider packageFragmentProvider ) { - this.annotationDeserializer = annotationDeserializer; + this.deserializers = deserializers; this.findClass = storageManager.createMemoizedFunctionWithNullableValues(new Function1() { @Override @@ -46,7 +46,7 @@ public abstract class AbstractDescriptorFinder implements DescriptorFinder { } AbstractDescriptorFinder _this = AbstractDescriptorFinder.this; - return new DeserializedClassDescriptor(storageManager, _this.annotationDeserializer, _this, packageFragmentProvider, + return new DeserializedClassDescriptor(storageManager, _this.deserializers, _this, packageFragmentProvider, classData.getNameResolver(), classData.getClassProto()); } }); @@ -60,4 +60,4 @@ public abstract class AbstractDescriptorFinder implements DescriptorFinder { @Nullable protected abstract ClassData getClassData(@NotNull ClassId classId); -} \ No newline at end of file +} diff --git a/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/DescriptorDeserializer.java b/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/DescriptorDeserializer.java index ffa24c715ca..5cf8d0c85ad 100644 --- a/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/DescriptorDeserializer.java +++ b/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/DescriptorDeserializer.java @@ -21,10 +21,9 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.descriptors.serialization.descriptors.AnnotationDeserializer; import org.jetbrains.jet.descriptors.serialization.descriptors.DeserializedSimpleFunctionDescriptor; import org.jetbrains.jet.descriptors.serialization.descriptors.DeserializedTypeParameterDescriptor; +import org.jetbrains.jet.descriptors.serialization.descriptors.Deserializers; import org.jetbrains.jet.lang.descriptors.*; -import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.descriptors.annotations.Annotations; -import org.jetbrains.jet.lang.descriptors.annotations.AnnotationsImpl; import org.jetbrains.jet.lang.descriptors.impl.*; import org.jetbrains.jet.lang.resolve.DescriptorFactory; import org.jetbrains.jet.lang.resolve.DescriptorUtils; @@ -38,7 +37,7 @@ import java.util.List; import static org.jetbrains.jet.descriptors.serialization.ProtoBuf.Callable; import static org.jetbrains.jet.descriptors.serialization.ProtoBuf.TypeParameter; import static org.jetbrains.jet.descriptors.serialization.TypeDeserializer.TypeParameterResolver.NONE; -import static org.jetbrains.jet.descriptors.serialization.descriptors.AnnotationDeserializer.AnnotatedCallableKind; +import static org.jetbrains.jet.descriptors.serialization.descriptors.Deserializers.AnnotatedCallableKind; public class DescriptorDeserializer { @@ -48,7 +47,7 @@ public class DescriptorDeserializer { @NotNull DeclarationDescriptor containingDeclaration, @NotNull NameResolver nameResolver, @NotNull DescriptorFinder descriptorFinder, - @NotNull AnnotationDeserializer annotationDeserializer + @NotNull Deserializers annotationDeserializer ) { return new DescriptorDeserializer(storageManager, new TypeDeserializer(storageManager, null, nameResolver, descriptorFinder, @@ -62,7 +61,7 @@ public class DescriptorDeserializer { @NotNull TypeDeserializer typeDeserializer, @NotNull DeclarationDescriptor containingDeclaration, @NotNull NameResolver nameResolver, - @NotNull AnnotationDeserializer annotationDeserializer + @NotNull Deserializers annotationDeserializer ) { return new DescriptorDeserializer(storageManager, typeDeserializer, containingDeclaration, nameResolver, annotationDeserializer); } @@ -70,7 +69,7 @@ public class DescriptorDeserializer { private final DeclarationDescriptor containingDeclaration; private final NameResolver nameResolver; private final TypeDeserializer typeDeserializer; - private final AnnotationDeserializer annotationDeserializer; + private final Deserializers deserializers; private final StorageManager storageManager; @@ -79,13 +78,13 @@ public class DescriptorDeserializer { @NotNull TypeDeserializer typeDeserializer, @NotNull DeclarationDescriptor containingDeclaration, @NotNull NameResolver nameResolver, - @NotNull AnnotationDeserializer annotationDeserializer + @NotNull Deserializers deserializers ) { this.storageManager = storageManager; this.typeDeserializer = typeDeserializer; this.containingDeclaration = containingDeclaration; this.nameResolver = nameResolver; - this.annotationDeserializer = annotationDeserializer; + this.deserializers = deserializers; } @NotNull @@ -116,7 +115,7 @@ public class DescriptorDeserializer { return descriptors; } }); - return create(storageManager, childTypeDeserializer, descriptor, nameResolver, annotationDeserializer); + return create(storageManager, childTypeDeserializer, descriptor, nameResolver, deserializers); } @NotNull @@ -206,7 +205,7 @@ public class DescriptorDeserializer { int flags = proto.getFlags(); DeserializedSimpleFunctionDescriptor function = new DeserializedSimpleFunctionDescriptor( containingDeclaration, proto, - annotationDeserializer, + deserializers, nameResolver ); List typeParameters = new ArrayList(proto.getTypeParameterCount()); @@ -251,7 +250,7 @@ public class DescriptorDeserializer { @NotNull private Annotations getAnnotations(@NotNull Callable proto, int flags, @NotNull AnnotatedCallableKind kind) { - return getAnnotations(containingDeclaration, proto, flags, kind, annotationDeserializer, nameResolver); + return getAnnotations(containingDeclaration, proto, flags, kind, deserializers.getAnnotationDeserializer(), nameResolver); } public static Annotations getAnnotations( @@ -402,7 +401,7 @@ public class DescriptorDeserializer { @NotNull Callable.ValueParameter valueParameter ) { return Flags.HAS_ANNOTATIONS.get(valueParameter.getFlags()) - ? annotationDeserializer.loadValueParameterAnnotations(classOrPackage, callable, nameResolver, kind, valueParameter) + ? deserializers.getAnnotationDeserializer().loadValueParameterAnnotations(classOrPackage, callable, nameResolver, kind, valueParameter) : Annotations.EMPTY; } } diff --git a/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/descriptors/AnnotationDeserializer.java b/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/descriptors/AnnotationDeserializer.java index 213d84a5973..0186a81646e 100644 --- a/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/descriptors/AnnotationDeserializer.java +++ b/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/descriptors/AnnotationDeserializer.java @@ -23,6 +23,8 @@ import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.ClassOrPackageFragmentDescriptor; import org.jetbrains.jet.lang.descriptors.annotations.Annotations; +import static org.jetbrains.jet.descriptors.serialization.descriptors.Deserializers.AnnotatedCallableKind; + public interface AnnotationDeserializer { AnnotationDeserializer UNSUPPORTED = new AnnotationDeserializer() { @NotNull @@ -60,13 +62,6 @@ public interface AnnotationDeserializer { } }; - enum AnnotatedCallableKind { - FUNCTION, - PROPERTY, - PROPERTY_GETTER, - PROPERTY_SETTER - } - @NotNull Annotations loadClassAnnotations(@NotNull ClassDescriptor descriptor, @NotNull ProtoBuf.Class classProto); diff --git a/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/descriptors/DeserializedClassDescriptor.java b/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/descriptors/DeserializedClassDescriptor.java index 2877cfd73d3..1735b49960f 100644 --- a/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/descriptors/DeserializedClassDescriptor.java +++ b/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/descriptors/DeserializedClassDescriptor.java @@ -58,7 +58,7 @@ public class DeserializedClassDescriptor extends AbstractClassDescriptor impleme private final NullableLazyValue primaryConstructor; - private final AnnotationDeserializer annotationDeserializer; + private final Deserializers deserializers; private final NotNullLazyValue annotations; private final NullableLazyValue classObjectDescriptor; @@ -76,7 +76,7 @@ public class DeserializedClassDescriptor extends AbstractClassDescriptor impleme public DeserializedClassDescriptor( @NotNull StorageManager storageManager, - @NotNull AnnotationDeserializer annotationResolver, + @NotNull Deserializers deserializers, @NotNull DescriptorFinder descriptorFinder, @NotNull PackageFragmentProvider packageFragmentProvider, @NotNull NameResolver nameResolver, @@ -92,7 +92,7 @@ public class DeserializedClassDescriptor extends AbstractClassDescriptor impleme TypeDeserializer notNullTypeDeserializer = new TypeDeserializer(storageManager, null, nameResolver, descriptorFinder, "Deserializer for class " + getName(), NONE); DescriptorDeserializer outerDeserializer = DescriptorDeserializer.create(storageManager, notNullTypeDeserializer, - this, nameResolver, annotationResolver); + this, nameResolver, deserializers); List typeParameters = new ArrayList(classProto.getTypeParameterCount()); this.deserializer = outerDeserializer.createChildDeserializer(this, classProto.getTypeParameterList(), typeParameters); this.typeDeserializer = deserializer.getTypeDeserializer(); @@ -113,7 +113,7 @@ public class DeserializedClassDescriptor extends AbstractClassDescriptor impleme this.kind = DescriptorDeserializer.classKind(Flags.CLASS_KIND.get(flags)); this.isInner = Flags.INNER.get(flags); - this.annotationDeserializer = annotationResolver; + this.deserializers = deserializers; this.annotations = storageManager.createLazyValue(new Function0() { @Override public Annotations invoke() { @@ -191,7 +191,7 @@ public class DeserializedClassDescriptor extends AbstractClassDescriptor impleme if (!Flags.HAS_ANNOTATIONS.get(classProto.getFlags())) { return Annotations.EMPTY; } - return annotationDeserializer.loadClassAnnotations(this, classProto); + return deserializers.getAnnotationDeserializer().loadClassAnnotations(this, classProto); } @NotNull @@ -253,7 +253,7 @@ public class DeserializedClassDescriptor extends AbstractClassDescriptor impleme throw new IllegalStateException("Object should have a serialized class object: " + classId); } - return new DeserializedClassDescriptor(storageManager, annotationDeserializer, descriptorFinder, packageFragmentProvider, + return new DeserializedClassDescriptor(storageManager, deserializers, descriptorFinder, packageFragmentProvider, deserializer.getNameResolver(), classObjectProto.getData()); } diff --git a/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/descriptors/DeserializedPackageMemberScope.java b/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/descriptors/DeserializedPackageMemberScope.java index d8ba0e4cb4b..a146735ce53 100644 --- a/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/descriptors/DeserializedPackageMemberScope.java +++ b/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/descriptors/DeserializedPackageMemberScope.java @@ -35,13 +35,13 @@ public class DeserializedPackageMemberScope extends DeserializedMemberScope { public DeserializedPackageMemberScope( @NotNull StorageManager storageManager, @NotNull PackageFragmentDescriptor packageDescriptor, - @NotNull AnnotationDeserializer annotationDeserializer, + @NotNull Deserializers deserializers, @NotNull DescriptorFinder descriptorFinder, @NotNull ProtoBuf.Package proto, @NotNull NameResolver nameResolver ) { super(storageManager, packageDescriptor, - DescriptorDeserializer.create(storageManager, packageDescriptor, nameResolver, descriptorFinder, annotationDeserializer), + DescriptorDeserializer.create(storageManager, packageDescriptor, nameResolver, descriptorFinder, deserializers), proto.getMemberList()); this.descriptorFinder = descriptorFinder; this.packageFqName = packageDescriptor.getFqName(); @@ -50,11 +50,11 @@ public class DeserializedPackageMemberScope extends DeserializedMemberScope { public DeserializedPackageMemberScope( @NotNull StorageManager storageManager, @NotNull PackageFragmentDescriptor packageDescriptor, - @NotNull AnnotationDeserializer annotationDeserializer, + @NotNull Deserializers deserializers, @NotNull DescriptorFinder descriptorFinder, @NotNull PackageData packageData ) { - this(storageManager, packageDescriptor, annotationDeserializer, descriptorFinder, packageData.getPackageProto(), + this(storageManager, packageDescriptor, deserializers, descriptorFinder, packageData.getPackageProto(), packageData.getNameResolver()); } diff --git a/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/descriptors/DeserializedSimpleFunctionDescriptor.java b/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/descriptors/DeserializedSimpleFunctionDescriptor.java index f8a1a0feb2d..8e03fb2282c 100644 --- a/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/descriptors/DeserializedSimpleFunctionDescriptor.java +++ b/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/descriptors/DeserializedSimpleFunctionDescriptor.java @@ -62,12 +62,12 @@ public class DeserializedSimpleFunctionDescriptor extends SimpleFunctionDescript public DeserializedSimpleFunctionDescriptor( @NotNull DeclarationDescriptor containingDeclaration, @NotNull ProtoBuf.Callable functionProto, - @NotNull AnnotationDeserializer annotationDeserializer, + @NotNull Deserializers deserializers, @NotNull NameResolver nameResolver ) { this(containingDeclaration, DescriptorDeserializer.getAnnotations(containingDeclaration, functionProto, functionProto.getFlags(), - AnnotationDeserializer.AnnotatedCallableKind.FUNCTION, annotationDeserializer, + Deserializers.AnnotatedCallableKind.FUNCTION, deserializers.getAnnotationDeserializer(), nameResolver), nameResolver.getName(functionProto.getName()), DescriptorDeserializer.memberKind(Flags.MEMBER_KIND.get(functionProto.getFlags())), diff --git a/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/descriptors/Deserializers.java b/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/descriptors/Deserializers.java new file mode 100644 index 00000000000..e890f7ea8d7 --- /dev/null +++ b/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/descriptors/Deserializers.java @@ -0,0 +1,39 @@ +/* + * Copyright 2010-2014 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.descriptors.serialization.descriptors; + +import org.jetbrains.annotations.NotNull; + +public interface Deserializers { + Deserializers UNSUPPORTED = new Deserializers() { + @NotNull + @Override + public AnnotationDeserializer getAnnotationDeserializer() { + return AnnotationDeserializer.UNSUPPORTED; + } + }; + + @NotNull + AnnotationDeserializer getAnnotationDeserializer(); + + enum AnnotatedCallableKind { + FUNCTION, + PROPERTY, + PROPERTY_GETTER, + PROPERTY_SETTER + } +} 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 6e9ee19d6bd..d761dcd7a10 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 @@ -16,7 +16,6 @@ package org.jetbrains.jet.lang.resolve.kotlin; -import kotlin.Function1; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.descriptors.serialization.JavaProtoBuf; @@ -28,69 +27,48 @@ import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptorImpl; import org.jetbrains.jet.lang.descriptors.annotations.Annotations; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationsImpl; -import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant; import org.jetbrains.jet.lang.resolve.constants.EnumValue; import org.jetbrains.jet.lang.resolve.constants.ErrorValue; +import org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames; import org.jetbrains.jet.lang.resolve.java.JvmClassName; -import org.jetbrains.jet.lang.resolve.java.PackageClassUtils; import org.jetbrains.jet.lang.resolve.java.resolver.DescriptorResolverUtils; import org.jetbrains.jet.lang.resolve.java.resolver.ErrorReporter; import org.jetbrains.jet.lang.resolve.java.resolver.ResolverPackage; -import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.types.DependencyClassByQualifiedNameResolver; import org.jetbrains.jet.lang.types.ErrorUtils; -import org.jetbrains.jet.storage.MemoizedFunctionToNotNull; -import org.jetbrains.jet.storage.StorageManager; import javax.inject.Inject; import java.io.IOException; -import java.util.*; +import java.util.ArrayList; +import java.util.List; -import static org.jetbrains.jet.lang.resolve.DescriptorUtils.isClassObject; -import static org.jetbrains.jet.lang.resolve.DescriptorUtils.isTrait; -import static org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames.*; -import static org.jetbrains.jet.lang.resolve.kotlin.DeserializedResolverUtils.kotlinFqNameToJavaFqName; -import static org.jetbrains.jet.lang.resolve.kotlin.DeserializedResolverUtils.naiveKotlinFqName; +import static org.jetbrains.jet.descriptors.serialization.descriptors.Deserializers.AnnotatedCallableKind; +import static org.jetbrains.jet.lang.resolve.kotlin.DescriptorDeserializersStorage.MemberSignature; -public class AnnotationDescriptorDeserializer implements AnnotationDeserializer { - private DependencyClassByQualifiedNameResolver classResolver; - private KotlinClassFinder kotlinClassFinder; - private ErrorReporter errorReporter; - - private final MemoizedFunctionToNotNull>> memberAnnotations; - - public AnnotationDescriptorDeserializer(@NotNull StorageManager storageManager) { - this.memberAnnotations = storageManager.createMemoizedFunction( - new Function1>>() { - @NotNull - @Override - public Map> invoke(@NotNull KotlinJvmBinaryClass kotlinClass) { - try { - return loadMemberAnnotationsFromClass(kotlinClass); - } - catch (IOException e) { - errorReporter.reportAnnotationLoadingError( - "Error loading member annotations from Kotlin class: " + kotlinClass, e); - return Collections.emptyMap(); - } - } - }); +public class AnnotationDescriptorDeserializer extends BaseDescriptorDeserializer implements AnnotationDeserializer { + @Inject + @Override + public void setStorage(@NotNull DescriptorDeserializersStorage storage) { + this.storage = storage; } @Inject - public void setClassResolver(DependencyClassByQualifiedNameResolver classResolver) { + @Override + public void setClassResolver(@NotNull DependencyClassByQualifiedNameResolver classResolver) { this.classResolver = classResolver; } @Inject - public void setKotlinClassFinder(KotlinClassFinder kotlinClassFinder) { + @Override + public void setKotlinClassFinder(@NotNull KotlinClassFinder kotlinClassFinder) { this.kotlinClassFinder = kotlinClassFinder; } @Inject - public void setErrorReporter(ErrorReporter errorReporter) { + @Override + public void setErrorReporter(@NotNull ErrorReporter errorReporter) { this.errorReporter = errorReporter; } @@ -113,20 +91,6 @@ public class AnnotationDescriptorDeserializer implements AnnotationDeserializer } } - @Nullable - private KotlinJvmBinaryClass findKotlinClassByDescriptor(@NotNull ClassOrPackageFragmentDescriptor descriptor) { - if (descriptor instanceof ClassDescriptor) { - return kotlinClassFinder.findKotlinClass(kotlinFqNameToJavaFqName(naiveKotlinFqName((ClassDescriptor) descriptor))); - } - else if (descriptor instanceof PackageFragmentDescriptor) { - return kotlinClassFinder.findKotlinClass( - PackageClassUtils.getPackageClassFqName(((PackageFragmentDescriptor) descriptor).getFqName())); - } - else { - throw new IllegalStateException("Unrecognized descriptor: " + descriptor); - } - } - @NotNull private Annotations loadClassAnnotationsFromClass(@NotNull KotlinJvmBinaryClass kotlinClass) throws IOException { final List result = new ArrayList(); @@ -135,7 +99,7 @@ public class AnnotationDescriptorDeserializer implements AnnotationDeserializer @Nullable @Override public KotlinJvmBinaryClass.AnnotationArgumentVisitor visitAnnotation(@NotNull JvmClassName className) { - return resolveAnnotation(className, result); + return resolveAnnotation(className, result, classResolver); } @Override @@ -147,21 +111,22 @@ public class AnnotationDescriptorDeserializer implements AnnotationDeserializer } private static boolean ignoreAnnotation(@NotNull JvmClassName className) { - return className.equals(JvmClassName.byFqNameWithoutInnerClasses(KOTLIN_CLASS)) - || className.equals(JvmClassName.byFqNameWithoutInnerClasses(KOTLIN_PACKAGE)) - || className.equals(JvmClassName.byFqNameWithoutInnerClasses(JETBRAINS_NOT_NULL_ANNOTATION)) - || className.equals(JvmClassName.byFqNameWithoutInnerClasses(JETBRAINS_NULLABLE_ANNOTATION)) + return className.equals(JvmClassName.byFqNameWithoutInnerClasses(JvmAnnotationNames.KOTLIN_CLASS)) + || className.equals(JvmClassName.byFqNameWithoutInnerClasses(JvmAnnotationNames.KOTLIN_PACKAGE)) + || className.equals(JvmClassName.byFqNameWithoutInnerClasses(JvmAnnotationNames.JETBRAINS_NOT_NULL_ANNOTATION)) + || className.equals(JvmClassName.byFqNameWithoutInnerClasses(JvmAnnotationNames.JETBRAINS_NULLABLE_ANNOTATION)) || className.getInternalName().startsWith("jet/runtime/typeinfo/"); } @Nullable - private KotlinJvmBinaryClass.AnnotationArgumentVisitor resolveAnnotation( + public static KotlinJvmBinaryClass.AnnotationArgumentVisitor resolveAnnotation( @NotNull JvmClassName className, - @NotNull final List result + @NotNull final List result, + @NotNull final DependencyClassByQualifiedNameResolver classResolver ) { if (ignoreAnnotation(className)) return null; - final ClassDescriptor annotationClass = resolveClass(className); + final ClassDescriptor annotationClass = resolveClass(className, classResolver); final AnnotationDescriptorImpl annotation = new AnnotationDescriptorImpl(); annotation.setAnnotationType(annotationClass.getDefaultType()); @@ -188,7 +153,7 @@ public class AnnotationDescriptorDeserializer implements AnnotationDeserializer @NotNull private CompileTimeConstant enumEntryValue(@NotNull JvmClassName enumClassName, @NotNull Name name) { - ClassDescriptor enumClass = resolveClass(enumClassName); + ClassDescriptor enumClass = resolveClass(enumClassName, classResolver); if (enumClass.getKind() == ClassKind.ENUM_CLASS) { ClassifierDescriptor classifier = enumClass.getUnsubstitutedInnerClassesScope().getClassifier(name); if (classifier instanceof ClassDescriptor) { @@ -213,7 +178,7 @@ public class AnnotationDescriptorDeserializer implements AnnotationDeserializer } @NotNull - private ClassDescriptor resolveClass(@NotNull JvmClassName className) { + private static ClassDescriptor resolveClass(@NotNull JvmClassName className, DependencyClassByQualifiedNameResolver classResolver) { ClassDescriptor annotationClass = classResolver.resolveClass(className.getFqNameForClassNameWithoutDollars()); return annotationClass != null ? annotationClass : ErrorUtils.getErrorClass(); } @@ -246,257 +211,10 @@ public class AnnotationDescriptorDeserializer implements AnnotationDeserializer return Annotations.EMPTY; } - List annotations = memberAnnotations.invoke(kotlinClass).get(signature); + List annotations = storage.getMemberAnnotations().invoke(kotlinClass).get(signature); return annotations == null ? Annotations.EMPTY : new AnnotationsImpl(annotations); } - @Nullable - private KotlinJvmBinaryClass findClassWithMemberAnnotations( - @NotNull ClassOrPackageFragmentDescriptor container, - @NotNull ProtoBuf.Callable proto, - @NotNull NameResolver nameResolver, - @NotNull AnnotatedCallableKind kind - ) { - if (container instanceof PackageFragmentDescriptor) { - return loadPackageFragmentClassFqName((PackageFragmentDescriptor) container, proto, nameResolver); - } - else if (isClassObject(container) && isStaticFieldInOuter(proto)) { - // Backing fields of properties of a class object are generated in the outer class - return findKotlinClassByDescriptor((ClassOrPackageFragmentDescriptor) container.getContainingDeclaration()); - } - else if (isTrait(container) && kind == AnnotatedCallableKind.PROPERTY) { - PackageFragmentDescriptor containingPackage = DescriptorUtils.getParentOfType(container, PackageFragmentDescriptor.class); - assert containingPackage != null : "Trait must have a package fragment among his parents: " + container; - - if (proto.hasExtension(JavaProtoBuf.implClassName)) { - Name tImplName = nameResolver.getName(proto.getExtension(JavaProtoBuf.implClassName)); - return kotlinClassFinder.findKotlinClass(containingPackage.getFqName().child(tImplName)); - } - return null; - } - - return findKotlinClassByDescriptor(container); - } - - @Nullable - private KotlinJvmBinaryClass loadPackageFragmentClassFqName( - @NotNull PackageFragmentDescriptor container, - @NotNull ProtoBuf.Callable proto, - @NotNull NameResolver nameResolver - ) { - if (proto.hasExtension(JavaProtoBuf.implClassName)) { - Name name = nameResolver.getName(proto.getExtension(JavaProtoBuf.implClassName)); - FqName fqName = PackageClassUtils.getPackageClassFqName(container.getFqName()).parent().child(name); - return kotlinClassFinder.findKotlinClass(fqName); - } - return null; - } - - private static boolean isStaticFieldInOuter(@NotNull ProtoBuf.Callable proto) { - if (!proto.hasExtension(JavaProtoBuf.propertySignature)) return false; - JavaProtoBuf.JavaPropertySignature propertySignature = proto.getExtension(JavaProtoBuf.propertySignature); - return propertySignature.hasField() && propertySignature.getField().getIsStaticInOuter(); - } - - @Nullable - private static MemberSignature getCallableSignature( - @NotNull ProtoBuf.Callable proto, - @NotNull NameResolver nameResolver, - @NotNull AnnotatedCallableKind kind - ) { - SignatureDeserializer deserializer = new SignatureDeserializer(nameResolver); - switch (kind) { - case FUNCTION: - if (proto.hasExtension(JavaProtoBuf.methodSignature)) { - return deserializer.methodSignature(proto.getExtension(JavaProtoBuf.methodSignature)); - } - break; - case PROPERTY_GETTER: - if (proto.hasExtension(JavaProtoBuf.propertySignature)) { - return deserializer.methodSignature(proto.getExtension(JavaProtoBuf.propertySignature).getGetter()); - } - break; - case PROPERTY_SETTER: - if (proto.hasExtension(JavaProtoBuf.propertySignature)) { - return deserializer.methodSignature(proto.getExtension(JavaProtoBuf.propertySignature).getSetter()); - } - break; - case PROPERTY: - if (proto.hasExtension(JavaProtoBuf.propertySignature)) { - JavaProtoBuf.JavaPropertySignature propertySignature = proto.getExtension(JavaProtoBuf.propertySignature); - - if (propertySignature.hasField()) { - JavaProtoBuf.JavaFieldSignature field = propertySignature.getField(); - String type = deserializer.typeDescriptor(field.getType()); - Name name = nameResolver.getName(field.getName()); - return MemberSignature.fromFieldNameAndDesc(name, type); - } - else if (propertySignature.hasSyntheticMethod()) { - return deserializer.methodSignature(propertySignature.getSyntheticMethod()); - } - } - break; - } - return null; - } - - @NotNull - private Map> loadMemberAnnotationsFromClass(@NotNull KotlinJvmBinaryClass kotlinClass) - throws IOException { - final Map> memberAnnotations = - new HashMap>(); - - kotlinClass.loadMemberAnnotations(new KotlinJvmBinaryClass.MemberVisitor() { - @Nullable - @Override - public KotlinJvmBinaryClass.MethodAnnotationVisitor visitMethod(@NotNull Name name, @NotNull String desc) { - return new AnnotationVisitorForMethod(MemberSignature.fromMethodNameAndDesc(name, desc)); - } - - @Nullable - @Override - public KotlinJvmBinaryClass.AnnotationVisitor visitField(@NotNull Name name, @NotNull String desc) { - return new MemberAnnotationVisitor(MemberSignature.fromFieldNameAndDesc(name, desc)); - } - - class AnnotationVisitorForMethod extends MemberAnnotationVisitor implements KotlinJvmBinaryClass.MethodAnnotationVisitor { - public AnnotationVisitorForMethod(@NotNull MemberSignature signature) { - super(signature); - } - - @Nullable - @Override - public KotlinJvmBinaryClass.AnnotationArgumentVisitor visitParameterAnnotation(int index, @NotNull JvmClassName className) { - MemberSignature paramSignature = MemberSignature.fromMethodSignatureAndParameterIndex(signature, index); - List result = memberAnnotations.get(paramSignature); - if (result == null) { - result = new ArrayList(); - memberAnnotations.put(paramSignature, result); - } - return resolveAnnotation(className, result); - } - } - - class MemberAnnotationVisitor implements KotlinJvmBinaryClass.AnnotationVisitor { - private final List result = new ArrayList(); - protected final MemberSignature signature; - - public MemberAnnotationVisitor(@NotNull MemberSignature signature) { - this.signature = signature; - } - - @Nullable - @Override - public KotlinJvmBinaryClass.AnnotationArgumentVisitor visitAnnotation(@NotNull JvmClassName className) { - return resolveAnnotation(className, result); - } - - @Override - public void visitEnd() { - if (!result.isEmpty()) { - memberAnnotations.put(signature, result); - } - } - } - }); - - return memberAnnotations; - } - - // The purpose of this class is to hold a unique signature of either a method or a field, so that annotations on a member can be put - // into a map indexed by these signatures - private static final class MemberSignature { - private final String signature; - - private MemberSignature(@NotNull String signature) { - this.signature = signature; - } - - @NotNull - public static MemberSignature fromMethodNameAndDesc(@NotNull Name name, @NotNull String desc) { - return new MemberSignature(name.asString() + desc); - } - - @NotNull - public static MemberSignature fromFieldNameAndDesc(@NotNull Name name, @NotNull String desc) { - return new MemberSignature(name.asString() + "#" + desc); - } - - @NotNull - public static MemberSignature fromMethodSignatureAndParameterIndex(@NotNull MemberSignature signature, int index) { - return new MemberSignature(signature.signature + "@" + index); - } - - @Override - public int hashCode() { - return signature.hashCode(); - } - - @Override - public boolean equals(Object o) { - return o instanceof MemberSignature && signature.equals(((MemberSignature) o).signature); - } - - @Override - public String toString() { - return signature; - } - } - - private static class SignatureDeserializer { - // These types are ordered according to their sorts, this is significant for deserialization - private static final char[] PRIMITIVE_TYPES = new char[] { 'V', 'Z', 'C', 'B', 'S', 'I', 'F', 'J', 'D' }; - - private final NameResolver nameResolver; - - public SignatureDeserializer(@NotNull NameResolver nameResolver) { - this.nameResolver = nameResolver; - } - - @NotNull - public MemberSignature methodSignature(@NotNull JavaProtoBuf.JavaMethodSignature signature) { - Name name = nameResolver.getName(signature.getName()); - - StringBuilder sb = new StringBuilder(); - sb.append('('); - for (int i = 0, length = signature.getParameterTypeCount(); i < length; i++) { - typeDescriptor(signature.getParameterType(i), sb); - } - sb.append(')'); - typeDescriptor(signature.getReturnType(), sb); - - return MemberSignature.fromMethodNameAndDesc(name, sb.toString()); - } - - @NotNull - public String typeDescriptor(@NotNull JavaProtoBuf.JavaType type) { - return typeDescriptor(type, new StringBuilder()).toString(); - } - - @NotNull - private StringBuilder typeDescriptor(@NotNull JavaProtoBuf.JavaType type, @NotNull StringBuilder sb) { - for (int i = 0; i < type.getArrayDimension(); i++) { - sb.append('['); - } - - if (type.hasPrimitiveType()) { - sb.append(PRIMITIVE_TYPES[type.getPrimitiveType().ordinal()]); - } - else { - sb.append("L"); - sb.append(fqNameToInternalName(nameResolver.getFqName(type.getClassFqName()))); - sb.append(";"); - } - - return sb; - } - - @NotNull - private static String fqNameToInternalName(@NotNull FqName fqName) { - return fqName.asString().replace('.', '/'); - } - } - @NotNull @Override public Annotations loadValueParameterAnnotations( @@ -517,4 +235,4 @@ public class AnnotationDescriptorDeserializer implements AnnotationDeserializer return Annotations.EMPTY; } -} \ No newline at end of file +} diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/BaseDescriptorDeserializer.java b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/BaseDescriptorDeserializer.java new file mode 100644 index 00000000000..a8e17bae251 --- /dev/null +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/BaseDescriptorDeserializer.java @@ -0,0 +1,214 @@ +/* + * Copyright 2010-2014 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.descriptors.serialization.JavaProtoBuf; +import org.jetbrains.jet.descriptors.serialization.NameResolver; +import org.jetbrains.jet.descriptors.serialization.ProtoBuf; +import org.jetbrains.jet.lang.descriptors.ClassDescriptor; +import org.jetbrains.jet.lang.descriptors.ClassOrPackageFragmentDescriptor; +import org.jetbrains.jet.lang.descriptors.PackageFragmentDescriptor; +import org.jetbrains.jet.lang.resolve.DescriptorUtils; +import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver; +import org.jetbrains.jet.lang.resolve.java.PackageClassUtils; +import org.jetbrains.jet.lang.resolve.java.resolver.ErrorReporter; +import org.jetbrains.jet.lang.resolve.name.FqName; +import org.jetbrains.jet.lang.resolve.name.Name; +import org.jetbrains.jet.lang.types.DependencyClassByQualifiedNameResolver; + +import static org.jetbrains.jet.descriptors.serialization.descriptors.Deserializers.AnnotatedCallableKind; +import static org.jetbrains.jet.lang.resolve.DescriptorUtils.isClassObject; +import static org.jetbrains.jet.lang.resolve.DescriptorUtils.isTrait; +import static org.jetbrains.jet.lang.resolve.kotlin.DescriptorDeserializersStorage.MemberSignature; +import static org.jetbrains.jet.lang.resolve.kotlin.DeserializedResolverUtils.kotlinFqNameToJavaFqName; +import static org.jetbrains.jet.lang.resolve.kotlin.DeserializedResolverUtils.naiveKotlinFqName; + +public abstract class BaseDescriptorDeserializer { + protected DependencyClassByQualifiedNameResolver classResolver; + protected KotlinClassFinder kotlinClassFinder; + protected ErrorReporter errorReporter; + + protected DescriptorDeserializersStorage storage; + + public abstract void setClassResolver(@NotNull DependencyClassByQualifiedNameResolver classResolver); + + public abstract void setKotlinClassFinder(@NotNull KotlinClassFinder kotlinClassFinder); + + public abstract void setErrorReporter(@NotNull ErrorReporter errorReporter); + + public abstract void setStorage(@NotNull DescriptorDeserializersStorage storage); + + @Nullable + protected static MemberSignature getCallableSignature( + @NotNull ProtoBuf.Callable proto, + @NotNull NameResolver nameResolver, + @NotNull AnnotatedCallableKind kind + ) { + SignatureDeserializer deserializer = new SignatureDeserializer(nameResolver); + switch (kind) { + case FUNCTION: + if (proto.hasExtension(JavaProtoBuf.methodSignature)) { + return deserializer.methodSignature(proto.getExtension(JavaProtoBuf.methodSignature)); + } + break; + case PROPERTY_GETTER: + if (proto.hasExtension(JavaProtoBuf.propertySignature)) { + return deserializer.methodSignature(proto.getExtension(JavaProtoBuf.propertySignature).getGetter()); + } + break; + case PROPERTY_SETTER: + if (proto.hasExtension(JavaProtoBuf.propertySignature)) { + return deserializer.methodSignature(proto.getExtension(JavaProtoBuf.propertySignature).getSetter()); + } + break; + case PROPERTY: + if (proto.hasExtension(JavaProtoBuf.propertySignature)) { + JavaProtoBuf.JavaPropertySignature propertySignature = proto.getExtension(JavaProtoBuf.propertySignature); + + if (propertySignature.hasField()) { + JavaProtoBuf.JavaFieldSignature field = propertySignature.getField(); + String type = deserializer.typeDescriptor(field.getType()); + Name name = nameResolver.getName(field.getName()); + return MemberSignature.fromFieldNameAndDesc(name, type); + } + else if (propertySignature.hasSyntheticMethod()) { + return deserializer.methodSignature(propertySignature.getSyntheticMethod()); + } + } + break; + } + return null; + } + + @Nullable + protected KotlinJvmBinaryClass findClassWithMemberAnnotations( + @NotNull ClassOrPackageFragmentDescriptor container, + @NotNull ProtoBuf.Callable proto, + @NotNull NameResolver nameResolver, + @NotNull AnnotatedCallableKind kind + ) { + if (container instanceof PackageFragmentDescriptor) { + return loadPackageFragmentClassFqName((PackageFragmentDescriptor) container, proto, nameResolver); + } + else if (isClassObject(container) && isStaticFieldInOuter(proto)) { + // Backing fields of properties of a class object are generated in the outer class + return findKotlinClassByDescriptor((ClassOrPackageFragmentDescriptor) container.getContainingDeclaration()); + } + else if (isTrait(container) && kind == AnnotatedCallableKind.PROPERTY) { + PackageFragmentDescriptor containingPackage = DescriptorUtils.getParentOfType(container, PackageFragmentDescriptor.class); + assert containingPackage != null : "Trait must have a package fragment among his parents: " + container; + + if (proto.hasExtension(JavaProtoBuf.implClassName)) { + Name tImplName = nameResolver.getName(proto.getExtension(JavaProtoBuf.implClassName)); + return kotlinClassFinder.findKotlinClass(containingPackage.getFqName().child(tImplName)); + } + return null; + } + + return findKotlinClassByDescriptor(container); + } + + @Nullable + private KotlinJvmBinaryClass loadPackageFragmentClassFqName( + @NotNull PackageFragmentDescriptor container, + @NotNull ProtoBuf.Callable proto, + @NotNull NameResolver nameResolver + ) { + if (proto.hasExtension(JavaProtoBuf.implClassName)) { + Name name = nameResolver.getName(proto.getExtension(JavaProtoBuf.implClassName)); + FqName fqName = PackageClassUtils.getPackageClassFqName(container.getFqName()).parent().child(name); + return kotlinClassFinder.findKotlinClass(fqName); + } + return null; + } + + private static boolean isStaticFieldInOuter(@NotNull ProtoBuf.Callable proto) { + if (!proto.hasExtension(JavaProtoBuf.propertySignature)) return false; + JavaProtoBuf.JavaPropertySignature propertySignature = proto.getExtension(JavaProtoBuf.propertySignature); + return propertySignature.hasField() && propertySignature.getField().getIsStaticInOuter(); + } + + @Nullable + protected KotlinJvmBinaryClass findKotlinClassByDescriptor(@NotNull ClassOrPackageFragmentDescriptor descriptor) { + if (descriptor instanceof ClassDescriptor) { + return kotlinClassFinder.findKotlinClass(kotlinFqNameToJavaFqName(naiveKotlinFqName((ClassDescriptor) descriptor))); + } + else if (descriptor instanceof PackageFragmentDescriptor) { + return kotlinClassFinder.findKotlinClass( + PackageClassUtils.getPackageClassFqName(((PackageFragmentDescriptor) descriptor).getFqName())); + } + else { + throw new IllegalStateException("Unrecognized descriptor: " + descriptor); + } + } + + protected static class SignatureDeserializer { + // These types are ordered according to their sorts, this is significant for deserialization + private static final char[] PRIMITIVE_TYPES = new char[] { 'V', 'Z', 'C', 'B', 'S', 'I', 'F', 'J', 'D' }; + + private final NameResolver nameResolver; + + public SignatureDeserializer(@NotNull NameResolver nameResolver) { + this.nameResolver = nameResolver; + } + + @NotNull + public MemberSignature methodSignature(@NotNull JavaProtoBuf.JavaMethodSignature signature) { + Name name = nameResolver.getName(signature.getName()); + + StringBuilder sb = new StringBuilder(); + sb.append('('); + for (int i = 0, length = signature.getParameterTypeCount(); i < length; i++) { + typeDescriptor(signature.getParameterType(i), sb); + } + sb.append(')'); + typeDescriptor(signature.getReturnType(), sb); + + return MemberSignature.fromMethodNameAndDesc(name, sb.toString()); + } + + @NotNull + public String typeDescriptor(@NotNull JavaProtoBuf.JavaType type) { + return typeDescriptor(type, new StringBuilder()).toString(); + } + + @NotNull + private StringBuilder typeDescriptor(@NotNull JavaProtoBuf.JavaType type, @NotNull StringBuilder sb) { + for (int i = 0; i < type.getArrayDimension(); i++) { + sb.append('['); + } + + if (type.hasPrimitiveType()) { + sb.append(PRIMITIVE_TYPES[type.getPrimitiveType().ordinal()]); + } + else { + sb.append("L"); + sb.append(fqNameToInternalName(nameResolver.getFqName(type.getClassFqName()))); + sb.append(";"); + } + + return sb; + } + + @NotNull + private static String fqNameToInternalName(@NotNull FqName fqName) { + return fqName.asString().replace('.', '/'); + } + } +} diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/DescriptorDeserializers.java b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/DescriptorDeserializers.java new file mode 100644 index 00000000000..0000253a254 --- /dev/null +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/DescriptorDeserializers.java @@ -0,0 +1,39 @@ +/* + * Copyright 2010-2014 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.jet.descriptors.serialization.descriptors.AnnotationDeserializer; +import org.jetbrains.jet.descriptors.serialization.descriptors.Deserializers; + +import javax.inject.Inject; + +public class DescriptorDeserializers implements Deserializers { + + private AnnotationDescriptorDeserializer annotationDescriptorDeserializer; + + @Inject + public void setAnnotationDescriptorDeserializer(AnnotationDescriptorDeserializer annotationDescriptorDeserializer) { + this.annotationDescriptorDeserializer = annotationDescriptorDeserializer; + } + + @NotNull + @Override + public AnnotationDeserializer getAnnotationDeserializer() { + return annotationDescriptorDeserializer; + } +} diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/DescriptorDeserializersStorage.java b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/DescriptorDeserializersStorage.java new file mode 100644 index 00000000000..a695c65e73f --- /dev/null +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/DescriptorDeserializersStorage.java @@ -0,0 +1,176 @@ +/* +* Copyright 2010-2014 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 kotlin.Function1; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; +import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver; +import org.jetbrains.jet.lang.resolve.java.JvmClassName; +import org.jetbrains.jet.lang.resolve.java.resolver.ErrorReporter; +import org.jetbrains.jet.lang.resolve.name.Name; +import org.jetbrains.jet.lang.types.DependencyClassByQualifiedNameResolver; +import org.jetbrains.jet.storage.MemoizedFunctionToNotNull; +import org.jetbrains.jet.storage.StorageManager; + +import javax.inject.Inject; +import java.io.IOException; +import java.util.*; + +public class DescriptorDeserializersStorage { + private DependencyClassByQualifiedNameResolver classResolver; + private ErrorReporter errorReporter; + + private final MemoizedFunctionToNotNull>> memberAnnotations; + + public DescriptorDeserializersStorage(@NotNull StorageManager storageManager) { + this.memberAnnotations = storageManager.createMemoizedFunction( + new Function1>>() { + @NotNull + @Override + public Map> invoke(@NotNull KotlinJvmBinaryClass kotlinClass) { + try { + return loadMemberAnnotationsFromClass(kotlinClass); + } + catch (IOException e) { + errorReporter.reportAnnotationLoadingError( + "Error loading member annotations from Kotlin class: " + kotlinClass, e); + return Collections.emptyMap(); + } + } + }); + } + + @Inject + public void setClassResolver(DependencyClassByQualifiedNameResolver classResolver) { + this.classResolver = classResolver; + } + + @Inject + public void setErrorReporter(ErrorReporter errorReporter) { + this.errorReporter = errorReporter; + } + + @NotNull + public MemoizedFunctionToNotNull>> getMemberAnnotations() { + return memberAnnotations; + } + + @NotNull + protected Map> loadMemberAnnotationsFromClass(@NotNull KotlinJvmBinaryClass kotlinClass) + throws IOException { + final Map> memberAnnotations = + new HashMap>(); + + kotlinClass.loadMemberAnnotations(new KotlinJvmBinaryClass.MemberVisitor() { + @Nullable + @Override + public KotlinJvmBinaryClass.MethodAnnotationVisitor visitMethod(@NotNull Name name, @NotNull String desc) { + return new AnnotationVisitorForMethod(MemberSignature.fromMethodNameAndDesc(name, desc)); + } + + @Nullable + @Override + public KotlinJvmBinaryClass.AnnotationVisitor visitField(@NotNull Name name, @NotNull String desc) { + return new MemberAnnotationVisitor(MemberSignature.fromFieldNameAndDesc(name, desc)); + } + + class AnnotationVisitorForMethod extends MemberAnnotationVisitor implements KotlinJvmBinaryClass.MethodAnnotationVisitor { + public AnnotationVisitorForMethod(@NotNull MemberSignature signature) { + super(signature); + } + + @Nullable + @Override + public KotlinJvmBinaryClass.AnnotationArgumentVisitor visitParameterAnnotation(int index, @NotNull JvmClassName className) { + MemberSignature paramSignature = MemberSignature.fromMethodSignatureAndParameterIndex(signature, index); + List result = memberAnnotations.get(paramSignature); + if (result == null) { + result = new ArrayList(); + memberAnnotations.put(paramSignature, result); + } + return AnnotationDescriptorDeserializer.resolveAnnotation(className, result, classResolver); + } + } + + class MemberAnnotationVisitor implements KotlinJvmBinaryClass.AnnotationVisitor { + private final List result = new ArrayList(); + protected final MemberSignature signature; + + public MemberAnnotationVisitor(@NotNull MemberSignature signature) { + this.signature = signature; + } + + @Nullable + @Override + public KotlinJvmBinaryClass.AnnotationArgumentVisitor visitAnnotation(@NotNull JvmClassName className) { + return AnnotationDescriptorDeserializer.resolveAnnotation(className, result, classResolver); + } + + @Override + public void visitEnd() { + if (!result.isEmpty()) { + memberAnnotations.put(signature, result); + } + } + } + }); + + return memberAnnotations; + } + + // The purpose of this class is to hold a unique signature of either a method or a field, so that annotations on a member can be put + // into a map indexed by these signatures + protected static final class MemberSignature { + private final String signature; + + private MemberSignature(@NotNull String signature) { + this.signature = signature; + } + + @NotNull + public static MemberSignature fromMethodNameAndDesc(@NotNull Name name, @NotNull String desc) { + return new MemberSignature(name.asString() + desc); + } + + @NotNull + public static MemberSignature fromFieldNameAndDesc(@NotNull Name name, @NotNull String desc) { + return new MemberSignature(name.asString() + "#" + desc); + } + + @NotNull + public static MemberSignature fromMethodSignatureAndParameterIndex(@NotNull MemberSignature signature, int index) { + return new MemberSignature(signature.signature + "@" + index); + } + + @Override + public int hashCode() { + return signature.hashCode(); + } + + @Override + public boolean equals(Object o) { + return o instanceof MemberSignature && signature.equals(((MemberSignature) o).signature); + } + + @Override + public String toString() { + return signature; + } + } +} 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 0498b6bf59d..46e4067071b 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 @@ -43,7 +43,7 @@ import static org.jetbrains.jet.lang.resolve.kotlin.header.KotlinClassHeader.Kin import static org.jetbrains.jet.lang.resolve.kotlin.header.KotlinClassHeader.Kind.PACKAGE_FACADE; public final class DeserializedDescriptorResolver { - private AnnotationDescriptorDeserializer annotationDeserializer; + private DescriptorDeserializers annotationDeserializer; private StorageManager storageManager; @@ -69,7 +69,7 @@ public final class DeserializedDescriptorResolver { }; @Inject - public void setAnnotationDeserializer(AnnotationDescriptorDeserializer annotationDeserializer) { + public void setAnnotationDeserializer(DescriptorDeserializers annotationDeserializer) { this.annotationDeserializer = annotationDeserializer; } diff --git a/core/descriptors/src/org/jetbrains/jet/lang/types/lang/BuiltinsPackageFragment.java b/core/descriptors/src/org/jetbrains/jet/lang/types/lang/BuiltinsPackageFragment.java index 51b8a9a8b25..3c2edbc17a7 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/types/lang/BuiltinsPackageFragment.java +++ b/core/descriptors/src/org/jetbrains/jet/lang/types/lang/BuiltinsPackageFragment.java @@ -4,7 +4,7 @@ import kotlin.Function0; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.descriptors.serialization.*; -import org.jetbrains.jet.descriptors.serialization.descriptors.AnnotationDeserializer; +import org.jetbrains.jet.descriptors.serialization.descriptors.Deserializers; import org.jetbrains.jet.descriptors.serialization.descriptors.DeserializedPackageMemberScope; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.annotations.Annotations; @@ -39,7 +39,7 @@ class BuiltinsPackageFragment extends DeclarationDescriptorImpl implements Packa packageFragmentProvider = new BuiltinsPackageFragmentProvider(); // TODO: support annotations - members = new DeserializedPackageMemberScope(storageManager, this, AnnotationDeserializer.UNSUPPORTED, + members = new DeserializedPackageMemberScope(storageManager, this, Deserializers.UNSUPPORTED, new BuiltInsDescriptorFinder(storageManager), loadPackage(), nameResolver); } @@ -133,7 +133,7 @@ class BuiltinsPackageFragment extends DeclarationDescriptorImpl implements Packa public BuiltInsDescriptorFinder(@NotNull StorageManager storageManager) { // TODO: support annotations - super(storageManager, AnnotationDeserializer.UNSUPPORTED, packageFragmentProvider); + super(storageManager, Deserializers.UNSUPPORTED, packageFragmentProvider); classNames = storageManager.createLazyValue(new Function0>() { @Override @@ -194,4 +194,4 @@ class BuiltinsPackageFragment extends DeclarationDescriptorImpl implements Packa return packageName.equals(KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME) ? classNames.invoke() : Collections.emptyList(); } } -} \ No newline at end of file +} diff --git a/idea/src/org/jetbrains/jet/plugin/libraries/DeserializerForDecompiler.kt b/idea/src/org/jetbrains/jet/plugin/libraries/DeserializerForDecompiler.kt index a6fbccc3931..8308713f286 100644 --- a/idea/src/org/jetbrains/jet/plugin/libraries/DeserializerForDecompiler.kt +++ b/idea/src/org/jetbrains/jet/plugin/libraries/DeserializerForDecompiler.kt @@ -40,6 +40,8 @@ import org.jetbrains.jet.lang.resolve.java.PackageClassUtils import com.intellij.openapi.diagnostic.Logger import org.jetbrains.jet.lang.resolve.kotlin.KotlinClassFinder import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe +import org.jetbrains.jet.lang.resolve.kotlin.DescriptorDeserializers +import org.jetbrains.jet.lang.resolve.kotlin.DescriptorDeserializersStorage public fun DeserializerForDecompiler(classFile: VirtualFile): DeserializerForDecompiler { val kotlinClass = KotlinBinaryClassCache.getKotlinBinaryClass(classFile) @@ -64,7 +66,7 @@ public class DeserializerForDecompiler(val packageDirectory: VirtualFile, val di val membersScope = DeserializedPackageMemberScope( storageManager, createDummyPackageFragment(packageFqName), - annotationDeserializer, + deserializers, descriptorFinder, JavaProtoBufUtil.readPackageDataFrom(annotationData) ) @@ -93,7 +95,16 @@ public class DeserializerForDecompiler(val packageDirectory: VirtualFile, val di resolveClassByClassId(classId) } - private val annotationDeserializer = AnnotationDescriptorDeserializer(storageManager); + private val deserializerStorage = DescriptorDeserializersStorage(storageManager); + { + deserializerStorage.setClassResolver { + fqName -> + classes(fqName.toClassId()) + } + deserializerStorage.setErrorReporter(LOGGING_REPORTER) + } + + private val annotationDeserializer = AnnotationDescriptorDeserializer(); { annotationDeserializer.setClassResolver { fqName -> @@ -101,6 +112,12 @@ public class DeserializerForDecompiler(val packageDirectory: VirtualFile, val di } annotationDeserializer.setKotlinClassFinder(localClassFinder) annotationDeserializer.setErrorReporter(LOGGING_REPORTER) + annotationDeserializer.setStorage(deserializerStorage) + } + + private val deserializers = DescriptorDeserializers(); + { + deserializers.setAnnotationDescriptorDeserializer(annotationDeserializer) } private val descriptorFinder = object : DescriptorFinder { @@ -149,7 +166,7 @@ public class DeserializerForDecompiler(val packageDirectory: VirtualFile, val di LOG.error("Annotation data missing for ${kotlinClass.getClassName()}") } val classData = JavaProtoBufUtil.readClassDataFrom(data!!) - return DeserializedClassDescriptor(storageManager, annotationDeserializer, descriptorFinder, packageFragmentProvider, + return DeserializedClassDescriptor(storageManager, deserializers, descriptorFinder, packageFragmentProvider, classData.getNameResolver(), classData.getClassProto()) }