Extract BaseDeserializer from AnnotationDeserializer. Move storage to separate class

This commit is contained in:
Natalia Ukhorskaya
2014-02-05 11:38:34 +04:00
parent 6089f5e3ef
commit 073d345841
17 changed files with 596 additions and 363 deletions
@@ -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.LazyJavaPackageFragmentProvider;
import org.jetbrains.jet.lang.resolve.java.lazy.GlobalJavaResolverContext; import org.jetbrains.jet.lang.resolve.java.lazy.GlobalJavaResolverContext;
import org.jetbrains.jet.lang.resolve.kotlin.DeserializedDescriptorResolver; 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.AnnotationDescriptorDeserializer;
import org.jetbrains.jet.lang.resolve.kotlin.DescriptorDeserializersStorage;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import javax.annotation.PreDestroy; import javax.annotation.PreDestroy;
@@ -56,7 +58,9 @@ public class InjectorForJavaDescriptorResolver {
private final LazyJavaPackageFragmentProvider lazyJavaPackageFragmentProvider; private final LazyJavaPackageFragmentProvider lazyJavaPackageFragmentProvider;
private final GlobalJavaResolverContext globalJavaResolverContext; private final GlobalJavaResolverContext globalJavaResolverContext;
private final DeserializedDescriptorResolver deserializedDescriptorResolver; private final DeserializedDescriptorResolver deserializedDescriptorResolver;
private final DescriptorDeserializers descriptorDeserializers;
private final AnnotationDescriptorDeserializer annotationDescriptorDeserializer; private final AnnotationDescriptorDeserializer annotationDescriptorDeserializer;
private final DescriptorDeserializersStorage descriptorDeserializersStorage;
public InjectorForJavaDescriptorResolver( public InjectorForJavaDescriptorResolver(
@NotNull Project project, @NotNull Project project,
@@ -78,7 +82,9 @@ public class InjectorForJavaDescriptorResolver {
this.globalJavaResolverContext = new GlobalJavaResolverContext(lockBasedStorageManager, getJavaClassFinder(), virtualFileFinder, deserializedDescriptorResolver, psiBasedExternalAnnotationResolver, traceBasedExternalSignatureResolver, traceBasedErrorReporter, psiBasedMethodSignatureChecker, traceBasedJavaResolverCache); this.globalJavaResolverContext = new GlobalJavaResolverContext(lockBasedStorageManager, getJavaClassFinder(), virtualFileFinder, deserializedDescriptorResolver, psiBasedExternalAnnotationResolver, traceBasedExternalSignatureResolver, traceBasedErrorReporter, psiBasedMethodSignatureChecker, traceBasedJavaResolverCache);
this.lazyJavaPackageFragmentProvider = new LazyJavaPackageFragmentProvider(globalJavaResolverContext, getModule()); this.lazyJavaPackageFragmentProvider = new LazyJavaPackageFragmentProvider(globalJavaResolverContext, getModule());
this.javaDescriptorResolver = new JavaDescriptorResolver(lazyJavaPackageFragmentProvider, 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); this.javaClassFinder.setProject(project);
@@ -92,15 +98,21 @@ public class InjectorForJavaDescriptorResolver {
psiBasedMethodSignatureChecker.setExternalAnnotationResolver(psiBasedExternalAnnotationResolver); psiBasedMethodSignatureChecker.setExternalAnnotationResolver(psiBasedExternalAnnotationResolver);
psiBasedMethodSignatureChecker.setExternalSignatureResolver(traceBasedExternalSignatureResolver); psiBasedMethodSignatureChecker.setExternalSignatureResolver(traceBasedExternalSignatureResolver);
deserializedDescriptorResolver.setAnnotationDeserializer(annotationDescriptorDeserializer); deserializedDescriptorResolver.setAnnotationDeserializer(descriptorDeserializers);
deserializedDescriptorResolver.setErrorReporter(traceBasedErrorReporter); deserializedDescriptorResolver.setErrorReporter(traceBasedErrorReporter);
deserializedDescriptorResolver.setJavaDescriptorResolver(javaDescriptorResolver); deserializedDescriptorResolver.setJavaDescriptorResolver(javaDescriptorResolver);
deserializedDescriptorResolver.setJavaPackageFragmentProvider(lazyJavaPackageFragmentProvider); deserializedDescriptorResolver.setJavaPackageFragmentProvider(lazyJavaPackageFragmentProvider);
deserializedDescriptorResolver.setStorageManager(lockBasedStorageManager); deserializedDescriptorResolver.setStorageManager(lockBasedStorageManager);
descriptorDeserializers.setAnnotationDescriptorDeserializer(annotationDescriptorDeserializer);
annotationDescriptorDeserializer.setClassResolver(javaDescriptorResolver); annotationDescriptorDeserializer.setClassResolver(javaDescriptorResolver);
annotationDescriptorDeserializer.setErrorReporter(traceBasedErrorReporter); annotationDescriptorDeserializer.setErrorReporter(traceBasedErrorReporter);
annotationDescriptorDeserializer.setKotlinClassFinder(virtualFileFinder); annotationDescriptorDeserializer.setKotlinClassFinder(virtualFileFinder);
annotationDescriptorDeserializer.setStorage(descriptorDeserializersStorage);
descriptorDeserializersStorage.setClassResolver(javaDescriptorResolver);
descriptorDeserializersStorage.setErrorReporter(traceBasedErrorReporter);
javaClassFinder.initialize(); javaClassFinder.initialize();
@@ -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.LazyJavaPackageFragmentProvider;
import org.jetbrains.jet.lang.resolve.java.lazy.GlobalJavaResolverContext; import org.jetbrains.jet.lang.resolve.java.lazy.GlobalJavaResolverContext;
import org.jetbrains.jet.lang.resolve.kotlin.DeserializedDescriptorResolver; 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.AnnotationDescriptorDeserializer;
import org.jetbrains.jet.lang.resolve.kotlin.DescriptorDeserializersStorage;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import javax.annotation.PreDestroy; import javax.annotation.PreDestroy;
@@ -96,7 +98,9 @@ public class InjectorForLazyResolveWithJava {
private final LazyJavaPackageFragmentProvider lazyJavaPackageFragmentProvider; private final LazyJavaPackageFragmentProvider lazyJavaPackageFragmentProvider;
private final GlobalJavaResolverContext globalJavaResolverContext; private final GlobalJavaResolverContext globalJavaResolverContext;
private final DeserializedDescriptorResolver deserializedDescriptorResolver; private final DeserializedDescriptorResolver deserializedDescriptorResolver;
private final DescriptorDeserializers descriptorDeserializers;
private final AnnotationDescriptorDeserializer annotationDescriptorDeserializer; private final AnnotationDescriptorDeserializer annotationDescriptorDeserializer;
private final DescriptorDeserializersStorage descriptorDeserializersStorage;
public InjectorForLazyResolveWithJava( public InjectorForLazyResolveWithJava(
@NotNull Project project, @NotNull Project project,
@@ -140,7 +144,9 @@ public class InjectorForLazyResolveWithJava {
this.candidateResolver = new CandidateResolver(); this.candidateResolver = new CandidateResolver();
this.jetImportsFactory = new JetImportsFactory(); this.jetImportsFactory = new JetImportsFactory();
this.scopeProvider = new ScopeProvider(getResolveSession()); 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.setAnnotationResolve(annotationResolver);
this.resolveSession.setDescriptorResolver(descriptorResolver); this.resolveSession.setDescriptorResolver(descriptorResolver);
@@ -211,15 +217,21 @@ public class InjectorForLazyResolveWithJava {
jetImportsFactory.setProject(project); jetImportsFactory.setProject(project);
deserializedDescriptorResolver.setAnnotationDeserializer(annotationDescriptorDeserializer); deserializedDescriptorResolver.setAnnotationDeserializer(descriptorDeserializers);
deserializedDescriptorResolver.setErrorReporter(traceBasedErrorReporter); deserializedDescriptorResolver.setErrorReporter(traceBasedErrorReporter);
deserializedDescriptorResolver.setJavaDescriptorResolver(javaDescriptorResolver); deserializedDescriptorResolver.setJavaDescriptorResolver(javaDescriptorResolver);
deserializedDescriptorResolver.setJavaPackageFragmentProvider(lazyJavaPackageFragmentProvider); deserializedDescriptorResolver.setJavaPackageFragmentProvider(lazyJavaPackageFragmentProvider);
deserializedDescriptorResolver.setStorageManager(lockBasedStorageManager); deserializedDescriptorResolver.setStorageManager(lockBasedStorageManager);
descriptorDeserializers.setAnnotationDescriptorDeserializer(annotationDescriptorDeserializer);
annotationDescriptorDeserializer.setClassResolver(javaDescriptorResolver); annotationDescriptorDeserializer.setClassResolver(javaDescriptorResolver);
annotationDescriptorDeserializer.setErrorReporter(traceBasedErrorReporter); annotationDescriptorDeserializer.setErrorReporter(traceBasedErrorReporter);
annotationDescriptorDeserializer.setKotlinClassFinder(virtualFileFinder); annotationDescriptorDeserializer.setKotlinClassFinder(virtualFileFinder);
annotationDescriptorDeserializer.setStorage(descriptorDeserializersStorage);
descriptorDeserializersStorage.setClassResolver(javaDescriptorResolver);
descriptorDeserializersStorage.setErrorReporter(traceBasedErrorReporter);
javaClassFinder.initialize(); javaClassFinder.initialize();
@@ -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.LazyJavaPackageFragmentProvider;
import org.jetbrains.jet.lang.resolve.java.lazy.GlobalJavaResolverContext; import org.jetbrains.jet.lang.resolve.java.lazy.GlobalJavaResolverContext;
import org.jetbrains.jet.lang.resolve.kotlin.DeserializedDescriptorResolver; 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.AnnotationDescriptorDeserializer;
import org.jetbrains.jet.lang.resolve.kotlin.DescriptorDeserializersStorage;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import javax.annotation.PreDestroy; import javax.annotation.PreDestroy;
@@ -116,7 +118,9 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly
private final LazyJavaPackageFragmentProvider lazyJavaPackageFragmentProvider; private final LazyJavaPackageFragmentProvider lazyJavaPackageFragmentProvider;
private final GlobalJavaResolverContext globalJavaResolverContext; private final GlobalJavaResolverContext globalJavaResolverContext;
private final DeserializedDescriptorResolver deserializedDescriptorResolver; private final DeserializedDescriptorResolver deserializedDescriptorResolver;
private final DescriptorDeserializers descriptorDeserializers;
private final AnnotationDescriptorDeserializer annotationDescriptorDeserializer; private final AnnotationDescriptorDeserializer annotationDescriptorDeserializer;
private final DescriptorDeserializersStorage descriptorDeserializersStorage;
public InjectorForTopDownAnalyzerForJvm( public InjectorForTopDownAnalyzerForJvm(
@NotNull Project project, @NotNull Project project,
@@ -170,7 +174,9 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly
this.overloadResolver = new OverloadResolver(); this.overloadResolver = new OverloadResolver();
this.overrideResolver = new OverrideResolver(); this.overrideResolver = new OverrideResolver();
this.typeHierarchyResolver = new TypeHierarchyResolver(); 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.setBodyResolver(bodyResolver);
this.topDownAnalyzer.setDeclarationResolver(declarationResolver); this.topDownAnalyzer.setDeclarationResolver(declarationResolver);
@@ -286,15 +292,21 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly
typeHierarchyResolver.setScriptHeaderResolver(scriptHeaderResolver); typeHierarchyResolver.setScriptHeaderResolver(scriptHeaderResolver);
typeHierarchyResolver.setTrace(bindingTrace); typeHierarchyResolver.setTrace(bindingTrace);
deserializedDescriptorResolver.setAnnotationDeserializer(annotationDescriptorDeserializer); deserializedDescriptorResolver.setAnnotationDeserializer(descriptorDeserializers);
deserializedDescriptorResolver.setErrorReporter(traceBasedErrorReporter); deserializedDescriptorResolver.setErrorReporter(traceBasedErrorReporter);
deserializedDescriptorResolver.setJavaDescriptorResolver(javaDescriptorResolver); deserializedDescriptorResolver.setJavaDescriptorResolver(javaDescriptorResolver);
deserializedDescriptorResolver.setJavaPackageFragmentProvider(lazyJavaPackageFragmentProvider); deserializedDescriptorResolver.setJavaPackageFragmentProvider(lazyJavaPackageFragmentProvider);
deserializedDescriptorResolver.setStorageManager(storageManager); deserializedDescriptorResolver.setStorageManager(storageManager);
descriptorDeserializers.setAnnotationDescriptorDeserializer(annotationDescriptorDeserializer);
annotationDescriptorDeserializer.setClassResolver(javaDescriptorResolver); annotationDescriptorDeserializer.setClassResolver(javaDescriptorResolver);
annotationDescriptorDeserializer.setErrorReporter(traceBasedErrorReporter); annotationDescriptorDeserializer.setErrorReporter(traceBasedErrorReporter);
annotationDescriptorDeserializer.setKotlinClassFinder(virtualFileFinder); annotationDescriptorDeserializer.setKotlinClassFinder(virtualFileFinder);
annotationDescriptorDeserializer.setStorage(descriptorDeserializersStorage);
descriptorDeserializersStorage.setClassResolver(javaDescriptorResolver);
descriptorDeserializersStorage.setErrorReporter(traceBasedErrorReporter);
javaClassFinder.initialize(); javaClassFinder.initialize();
@@ -19,7 +19,7 @@ package org.jetbrains.jet.descriptors.serialization;
import kotlin.Function1; import kotlin.Function1;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; 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.descriptors.serialization.descriptors.DeserializedClassDescriptor;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.PackageFragmentProvider; import org.jetbrains.jet.lang.descriptors.PackageFragmentProvider;
@@ -28,14 +28,14 @@ import org.jetbrains.jet.storage.StorageManager;
public abstract class AbstractDescriptorFinder implements DescriptorFinder { public abstract class AbstractDescriptorFinder implements DescriptorFinder {
private final MemoizedFunctionToNullable<ClassId, ClassDescriptor> findClass; private final MemoizedFunctionToNullable<ClassId, ClassDescriptor> findClass;
private final AnnotationDeserializer annotationDeserializer; private final Deserializers deserializers;
public AbstractDescriptorFinder( public AbstractDescriptorFinder(
@NotNull final StorageManager storageManager, @NotNull final StorageManager storageManager,
@NotNull AnnotationDeserializer annotationDeserializer, @NotNull Deserializers deserializers,
@NotNull final PackageFragmentProvider packageFragmentProvider @NotNull final PackageFragmentProvider packageFragmentProvider
) { ) {
this.annotationDeserializer = annotationDeserializer; this.deserializers = deserializers;
this.findClass = storageManager.createMemoizedFunctionWithNullableValues(new Function1<ClassId, ClassDescriptor>() { this.findClass = storageManager.createMemoizedFunctionWithNullableValues(new Function1<ClassId, ClassDescriptor>() {
@Override @Override
@@ -46,7 +46,7 @@ public abstract class AbstractDescriptorFinder implements DescriptorFinder {
} }
AbstractDescriptorFinder _this = AbstractDescriptorFinder.this; AbstractDescriptorFinder _this = AbstractDescriptorFinder.this;
return new DeserializedClassDescriptor(storageManager, _this.annotationDeserializer, _this, packageFragmentProvider, return new DeserializedClassDescriptor(storageManager, _this.deserializers, _this, packageFragmentProvider,
classData.getNameResolver(), classData.getClassProto()); classData.getNameResolver(), classData.getClassProto());
} }
}); });
@@ -60,4 +60,4 @@ public abstract class AbstractDescriptorFinder implements DescriptorFinder {
@Nullable @Nullable
protected abstract ClassData getClassData(@NotNull ClassId classId); protected abstract ClassData getClassData(@NotNull ClassId classId);
} }
@@ -21,10 +21,9 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.descriptors.serialization.descriptors.AnnotationDeserializer; import org.jetbrains.jet.descriptors.serialization.descriptors.AnnotationDeserializer;
import org.jetbrains.jet.descriptors.serialization.descriptors.DeserializedSimpleFunctionDescriptor; import org.jetbrains.jet.descriptors.serialization.descriptors.DeserializedSimpleFunctionDescriptor;
import org.jetbrains.jet.descriptors.serialization.descriptors.DeserializedTypeParameterDescriptor; 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.*;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.descriptors.annotations.Annotations; 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.descriptors.impl.*;
import org.jetbrains.jet.lang.resolve.DescriptorFactory; import org.jetbrains.jet.lang.resolve.DescriptorFactory;
import org.jetbrains.jet.lang.resolve.DescriptorUtils; 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.Callable;
import static org.jetbrains.jet.descriptors.serialization.ProtoBuf.TypeParameter; 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.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 { public class DescriptorDeserializer {
@@ -48,7 +47,7 @@ public class DescriptorDeserializer {
@NotNull DeclarationDescriptor containingDeclaration, @NotNull DeclarationDescriptor containingDeclaration,
@NotNull NameResolver nameResolver, @NotNull NameResolver nameResolver,
@NotNull DescriptorFinder descriptorFinder, @NotNull DescriptorFinder descriptorFinder,
@NotNull AnnotationDeserializer annotationDeserializer @NotNull Deserializers annotationDeserializer
) { ) {
return new DescriptorDeserializer(storageManager, return new DescriptorDeserializer(storageManager,
new TypeDeserializer(storageManager, null, nameResolver, descriptorFinder, new TypeDeserializer(storageManager, null, nameResolver, descriptorFinder,
@@ -62,7 +61,7 @@ public class DescriptorDeserializer {
@NotNull TypeDeserializer typeDeserializer, @NotNull TypeDeserializer typeDeserializer,
@NotNull DeclarationDescriptor containingDeclaration, @NotNull DeclarationDescriptor containingDeclaration,
@NotNull NameResolver nameResolver, @NotNull NameResolver nameResolver,
@NotNull AnnotationDeserializer annotationDeserializer @NotNull Deserializers annotationDeserializer
) { ) {
return new DescriptorDeserializer(storageManager, typeDeserializer, containingDeclaration, nameResolver, annotationDeserializer); return new DescriptorDeserializer(storageManager, typeDeserializer, containingDeclaration, nameResolver, annotationDeserializer);
} }
@@ -70,7 +69,7 @@ public class DescriptorDeserializer {
private final DeclarationDescriptor containingDeclaration; private final DeclarationDescriptor containingDeclaration;
private final NameResolver nameResolver; private final NameResolver nameResolver;
private final TypeDeserializer typeDeserializer; private final TypeDeserializer typeDeserializer;
private final AnnotationDeserializer annotationDeserializer; private final Deserializers deserializers;
private final StorageManager storageManager; private final StorageManager storageManager;
@@ -79,13 +78,13 @@ public class DescriptorDeserializer {
@NotNull TypeDeserializer typeDeserializer, @NotNull TypeDeserializer typeDeserializer,
@NotNull DeclarationDescriptor containingDeclaration, @NotNull DeclarationDescriptor containingDeclaration,
@NotNull NameResolver nameResolver, @NotNull NameResolver nameResolver,
@NotNull AnnotationDeserializer annotationDeserializer @NotNull Deserializers deserializers
) { ) {
this.storageManager = storageManager; this.storageManager = storageManager;
this.typeDeserializer = typeDeserializer; this.typeDeserializer = typeDeserializer;
this.containingDeclaration = containingDeclaration; this.containingDeclaration = containingDeclaration;
this.nameResolver = nameResolver; this.nameResolver = nameResolver;
this.annotationDeserializer = annotationDeserializer; this.deserializers = deserializers;
} }
@NotNull @NotNull
@@ -116,7 +115,7 @@ public class DescriptorDeserializer {
return descriptors; return descriptors;
} }
}); });
return create(storageManager, childTypeDeserializer, descriptor, nameResolver, annotationDeserializer); return create(storageManager, childTypeDeserializer, descriptor, nameResolver, deserializers);
} }
@NotNull @NotNull
@@ -206,7 +205,7 @@ public class DescriptorDeserializer {
int flags = proto.getFlags(); int flags = proto.getFlags();
DeserializedSimpleFunctionDescriptor function = new DeserializedSimpleFunctionDescriptor( DeserializedSimpleFunctionDescriptor function = new DeserializedSimpleFunctionDescriptor(
containingDeclaration, proto, containingDeclaration, proto,
annotationDeserializer, deserializers,
nameResolver nameResolver
); );
List<TypeParameterDescriptor> typeParameters = new ArrayList<TypeParameterDescriptor>(proto.getTypeParameterCount()); List<TypeParameterDescriptor> typeParameters = new ArrayList<TypeParameterDescriptor>(proto.getTypeParameterCount());
@@ -251,7 +250,7 @@ public class DescriptorDeserializer {
@NotNull @NotNull
private Annotations getAnnotations(@NotNull Callable proto, int flags, @NotNull AnnotatedCallableKind kind) { 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( public static Annotations getAnnotations(
@@ -402,7 +401,7 @@ public class DescriptorDeserializer {
@NotNull Callable.ValueParameter valueParameter @NotNull Callable.ValueParameter valueParameter
) { ) {
return Flags.HAS_ANNOTATIONS.get(valueParameter.getFlags()) return Flags.HAS_ANNOTATIONS.get(valueParameter.getFlags())
? annotationDeserializer.loadValueParameterAnnotations(classOrPackage, callable, nameResolver, kind, valueParameter) ? deserializers.getAnnotationDeserializer().loadValueParameterAnnotations(classOrPackage, callable, nameResolver, kind, valueParameter)
: Annotations.EMPTY; : Annotations.EMPTY;
} }
} }
@@ -23,6 +23,8 @@ import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.ClassOrPackageFragmentDescriptor; import org.jetbrains.jet.lang.descriptors.ClassOrPackageFragmentDescriptor;
import org.jetbrains.jet.lang.descriptors.annotations.Annotations; import org.jetbrains.jet.lang.descriptors.annotations.Annotations;
import static org.jetbrains.jet.descriptors.serialization.descriptors.Deserializers.AnnotatedCallableKind;
public interface AnnotationDeserializer { public interface AnnotationDeserializer {
AnnotationDeserializer UNSUPPORTED = new AnnotationDeserializer() { AnnotationDeserializer UNSUPPORTED = new AnnotationDeserializer() {
@NotNull @NotNull
@@ -60,13 +62,6 @@ public interface AnnotationDeserializer {
} }
}; };
enum AnnotatedCallableKind {
FUNCTION,
PROPERTY,
PROPERTY_GETTER,
PROPERTY_SETTER
}
@NotNull @NotNull
Annotations loadClassAnnotations(@NotNull ClassDescriptor descriptor, @NotNull ProtoBuf.Class classProto); Annotations loadClassAnnotations(@NotNull ClassDescriptor descriptor, @NotNull ProtoBuf.Class classProto);
@@ -58,7 +58,7 @@ public class DeserializedClassDescriptor extends AbstractClassDescriptor impleme
private final NullableLazyValue<ConstructorDescriptor> primaryConstructor; private final NullableLazyValue<ConstructorDescriptor> primaryConstructor;
private final AnnotationDeserializer annotationDeserializer; private final Deserializers deserializers;
private final NotNullLazyValue<Annotations> annotations; private final NotNullLazyValue<Annotations> annotations;
private final NullableLazyValue<ClassDescriptor> classObjectDescriptor; private final NullableLazyValue<ClassDescriptor> classObjectDescriptor;
@@ -76,7 +76,7 @@ public class DeserializedClassDescriptor extends AbstractClassDescriptor impleme
public DeserializedClassDescriptor( public DeserializedClassDescriptor(
@NotNull StorageManager storageManager, @NotNull StorageManager storageManager,
@NotNull AnnotationDeserializer annotationResolver, @NotNull Deserializers deserializers,
@NotNull DescriptorFinder descriptorFinder, @NotNull DescriptorFinder descriptorFinder,
@NotNull PackageFragmentProvider packageFragmentProvider, @NotNull PackageFragmentProvider packageFragmentProvider,
@NotNull NameResolver nameResolver, @NotNull NameResolver nameResolver,
@@ -92,7 +92,7 @@ public class DeserializedClassDescriptor extends AbstractClassDescriptor impleme
TypeDeserializer notNullTypeDeserializer = new TypeDeserializer(storageManager, null, nameResolver, TypeDeserializer notNullTypeDeserializer = new TypeDeserializer(storageManager, null, nameResolver,
descriptorFinder, "Deserializer for class " + getName(), NONE); descriptorFinder, "Deserializer for class " + getName(), NONE);
DescriptorDeserializer outerDeserializer = DescriptorDeserializer.create(storageManager, notNullTypeDeserializer, DescriptorDeserializer outerDeserializer = DescriptorDeserializer.create(storageManager, notNullTypeDeserializer,
this, nameResolver, annotationResolver); this, nameResolver, deserializers);
List<TypeParameterDescriptor> typeParameters = new ArrayList<TypeParameterDescriptor>(classProto.getTypeParameterCount()); List<TypeParameterDescriptor> typeParameters = new ArrayList<TypeParameterDescriptor>(classProto.getTypeParameterCount());
this.deserializer = outerDeserializer.createChildDeserializer(this, classProto.getTypeParameterList(), typeParameters); this.deserializer = outerDeserializer.createChildDeserializer(this, classProto.getTypeParameterList(), typeParameters);
this.typeDeserializer = deserializer.getTypeDeserializer(); this.typeDeserializer = deserializer.getTypeDeserializer();
@@ -113,7 +113,7 @@ public class DeserializedClassDescriptor extends AbstractClassDescriptor impleme
this.kind = DescriptorDeserializer.classKind(Flags.CLASS_KIND.get(flags)); this.kind = DescriptorDeserializer.classKind(Flags.CLASS_KIND.get(flags));
this.isInner = Flags.INNER.get(flags); this.isInner = Flags.INNER.get(flags);
this.annotationDeserializer = annotationResolver; this.deserializers = deserializers;
this.annotations = storageManager.createLazyValue(new Function0<Annotations>() { this.annotations = storageManager.createLazyValue(new Function0<Annotations>() {
@Override @Override
public Annotations invoke() { public Annotations invoke() {
@@ -191,7 +191,7 @@ public class DeserializedClassDescriptor extends AbstractClassDescriptor impleme
if (!Flags.HAS_ANNOTATIONS.get(classProto.getFlags())) { if (!Flags.HAS_ANNOTATIONS.get(classProto.getFlags())) {
return Annotations.EMPTY; return Annotations.EMPTY;
} }
return annotationDeserializer.loadClassAnnotations(this, classProto); return deserializers.getAnnotationDeserializer().loadClassAnnotations(this, classProto);
} }
@NotNull @NotNull
@@ -253,7 +253,7 @@ public class DeserializedClassDescriptor extends AbstractClassDescriptor impleme
throw new IllegalStateException("Object should have a serialized class object: " + classId); 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()); deserializer.getNameResolver(), classObjectProto.getData());
} }
@@ -35,13 +35,13 @@ public class DeserializedPackageMemberScope extends DeserializedMemberScope {
public DeserializedPackageMemberScope( public DeserializedPackageMemberScope(
@NotNull StorageManager storageManager, @NotNull StorageManager storageManager,
@NotNull PackageFragmentDescriptor packageDescriptor, @NotNull PackageFragmentDescriptor packageDescriptor,
@NotNull AnnotationDeserializer annotationDeserializer, @NotNull Deserializers deserializers,
@NotNull DescriptorFinder descriptorFinder, @NotNull DescriptorFinder descriptorFinder,
@NotNull ProtoBuf.Package proto, @NotNull ProtoBuf.Package proto,
@NotNull NameResolver nameResolver @NotNull NameResolver nameResolver
) { ) {
super(storageManager, packageDescriptor, super(storageManager, packageDescriptor,
DescriptorDeserializer.create(storageManager, packageDescriptor, nameResolver, descriptorFinder, annotationDeserializer), DescriptorDeserializer.create(storageManager, packageDescriptor, nameResolver, descriptorFinder, deserializers),
proto.getMemberList()); proto.getMemberList());
this.descriptorFinder = descriptorFinder; this.descriptorFinder = descriptorFinder;
this.packageFqName = packageDescriptor.getFqName(); this.packageFqName = packageDescriptor.getFqName();
@@ -50,11 +50,11 @@ public class DeserializedPackageMemberScope extends DeserializedMemberScope {
public DeserializedPackageMemberScope( public DeserializedPackageMemberScope(
@NotNull StorageManager storageManager, @NotNull StorageManager storageManager,
@NotNull PackageFragmentDescriptor packageDescriptor, @NotNull PackageFragmentDescriptor packageDescriptor,
@NotNull AnnotationDeserializer annotationDeserializer, @NotNull Deserializers deserializers,
@NotNull DescriptorFinder descriptorFinder, @NotNull DescriptorFinder descriptorFinder,
@NotNull PackageData packageData @NotNull PackageData packageData
) { ) {
this(storageManager, packageDescriptor, annotationDeserializer, descriptorFinder, packageData.getPackageProto(), this(storageManager, packageDescriptor, deserializers, descriptorFinder, packageData.getPackageProto(),
packageData.getNameResolver()); packageData.getNameResolver());
} }
@@ -62,12 +62,12 @@ public class DeserializedSimpleFunctionDescriptor extends SimpleFunctionDescript
public DeserializedSimpleFunctionDescriptor( public DeserializedSimpleFunctionDescriptor(
@NotNull DeclarationDescriptor containingDeclaration, @NotNull DeclarationDescriptor containingDeclaration,
@NotNull ProtoBuf.Callable functionProto, @NotNull ProtoBuf.Callable functionProto,
@NotNull AnnotationDeserializer annotationDeserializer, @NotNull Deserializers deserializers,
@NotNull NameResolver nameResolver @NotNull NameResolver nameResolver
) { ) {
this(containingDeclaration, this(containingDeclaration,
DescriptorDeserializer.getAnnotations(containingDeclaration, functionProto, functionProto.getFlags(), DescriptorDeserializer.getAnnotations(containingDeclaration, functionProto, functionProto.getFlags(),
AnnotationDeserializer.AnnotatedCallableKind.FUNCTION, annotationDeserializer, Deserializers.AnnotatedCallableKind.FUNCTION, deserializers.getAnnotationDeserializer(),
nameResolver), nameResolver),
nameResolver.getName(functionProto.getName()), nameResolver.getName(functionProto.getName()),
DescriptorDeserializer.memberKind(Flags.MEMBER_KIND.get(functionProto.getFlags())), DescriptorDeserializer.memberKind(Flags.MEMBER_KIND.get(functionProto.getFlags())),
@@ -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
}
}
@@ -16,7 +16,6 @@
package org.jetbrains.jet.lang.resolve.kotlin; package org.jetbrains.jet.lang.resolve.kotlin;
import kotlin.Function1;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.descriptors.serialization.JavaProtoBuf; 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.AnnotationDescriptorImpl;
import org.jetbrains.jet.lang.descriptors.annotations.Annotations; import org.jetbrains.jet.lang.descriptors.annotations.Annotations;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationsImpl; 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.CompileTimeConstant;
import org.jetbrains.jet.lang.resolve.constants.EnumValue; import org.jetbrains.jet.lang.resolve.constants.EnumValue;
import org.jetbrains.jet.lang.resolve.constants.ErrorValue; 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.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.DescriptorResolverUtils;
import org.jetbrains.jet.lang.resolve.java.resolver.ErrorReporter; import org.jetbrains.jet.lang.resolve.java.resolver.ErrorReporter;
import org.jetbrains.jet.lang.resolve.java.resolver.ResolverPackage; 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.resolve.name.Name;
import org.jetbrains.jet.lang.types.DependencyClassByQualifiedNameResolver; import org.jetbrains.jet.lang.types.DependencyClassByQualifiedNameResolver;
import org.jetbrains.jet.lang.types.ErrorUtils; import org.jetbrains.jet.lang.types.ErrorUtils;
import org.jetbrains.jet.storage.MemoizedFunctionToNotNull;
import org.jetbrains.jet.storage.StorageManager;
import javax.inject.Inject; import javax.inject.Inject;
import java.io.IOException; 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.descriptors.serialization.descriptors.Deserializers.AnnotatedCallableKind;
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.java.JvmAnnotationNames.*;
import static org.jetbrains.jet.lang.resolve.kotlin.DeserializedResolverUtils.kotlinFqNameToJavaFqName;
import static org.jetbrains.jet.lang.resolve.kotlin.DeserializedResolverUtils.naiveKotlinFqName;
public class AnnotationDescriptorDeserializer implements AnnotationDeserializer { public class AnnotationDescriptorDeserializer extends BaseDescriptorDeserializer implements AnnotationDeserializer {
private DependencyClassByQualifiedNameResolver classResolver; @Inject
private KotlinClassFinder kotlinClassFinder; @Override
private ErrorReporter errorReporter; public void setStorage(@NotNull DescriptorDeserializersStorage storage) {
this.storage = storage;
private final MemoizedFunctionToNotNull<KotlinJvmBinaryClass, Map<MemberSignature, List<AnnotationDescriptor>>> memberAnnotations;
public AnnotationDescriptorDeserializer(@NotNull StorageManager storageManager) {
this.memberAnnotations = storageManager.createMemoizedFunction(
new Function1<KotlinJvmBinaryClass, Map<MemberSignature, List<AnnotationDescriptor>>>() {
@NotNull
@Override
public Map<MemberSignature, List<AnnotationDescriptor>> 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 @Inject
public void setClassResolver(DependencyClassByQualifiedNameResolver classResolver) { @Override
public void setClassResolver(@NotNull DependencyClassByQualifiedNameResolver classResolver) {
this.classResolver = classResolver; this.classResolver = classResolver;
} }
@Inject @Inject
public void setKotlinClassFinder(KotlinClassFinder kotlinClassFinder) { @Override
public void setKotlinClassFinder(@NotNull KotlinClassFinder kotlinClassFinder) {
this.kotlinClassFinder = kotlinClassFinder; this.kotlinClassFinder = kotlinClassFinder;
} }
@Inject @Inject
public void setErrorReporter(ErrorReporter errorReporter) { @Override
public void setErrorReporter(@NotNull ErrorReporter errorReporter) {
this.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 @NotNull
private Annotations loadClassAnnotationsFromClass(@NotNull KotlinJvmBinaryClass kotlinClass) throws IOException { private Annotations loadClassAnnotationsFromClass(@NotNull KotlinJvmBinaryClass kotlinClass) throws IOException {
final List<AnnotationDescriptor> result = new ArrayList<AnnotationDescriptor>(); final List<AnnotationDescriptor> result = new ArrayList<AnnotationDescriptor>();
@@ -135,7 +99,7 @@ public class AnnotationDescriptorDeserializer implements AnnotationDeserializer
@Nullable @Nullable
@Override @Override
public KotlinJvmBinaryClass.AnnotationArgumentVisitor visitAnnotation(@NotNull JvmClassName className) { public KotlinJvmBinaryClass.AnnotationArgumentVisitor visitAnnotation(@NotNull JvmClassName className) {
return resolveAnnotation(className, result); return resolveAnnotation(className, result, classResolver);
} }
@Override @Override
@@ -147,21 +111,22 @@ public class AnnotationDescriptorDeserializer implements AnnotationDeserializer
} }
private static boolean ignoreAnnotation(@NotNull JvmClassName className) { private static boolean ignoreAnnotation(@NotNull JvmClassName className) {
return className.equals(JvmClassName.byFqNameWithoutInnerClasses(KOTLIN_CLASS)) return className.equals(JvmClassName.byFqNameWithoutInnerClasses(JvmAnnotationNames.KOTLIN_CLASS))
|| className.equals(JvmClassName.byFqNameWithoutInnerClasses(KOTLIN_PACKAGE)) || className.equals(JvmClassName.byFqNameWithoutInnerClasses(JvmAnnotationNames.KOTLIN_PACKAGE))
|| className.equals(JvmClassName.byFqNameWithoutInnerClasses(JETBRAINS_NOT_NULL_ANNOTATION)) || className.equals(JvmClassName.byFqNameWithoutInnerClasses(JvmAnnotationNames.JETBRAINS_NOT_NULL_ANNOTATION))
|| className.equals(JvmClassName.byFqNameWithoutInnerClasses(JETBRAINS_NULLABLE_ANNOTATION)) || className.equals(JvmClassName.byFqNameWithoutInnerClasses(JvmAnnotationNames.JETBRAINS_NULLABLE_ANNOTATION))
|| className.getInternalName().startsWith("jet/runtime/typeinfo/"); || className.getInternalName().startsWith("jet/runtime/typeinfo/");
} }
@Nullable @Nullable
private KotlinJvmBinaryClass.AnnotationArgumentVisitor resolveAnnotation( public static KotlinJvmBinaryClass.AnnotationArgumentVisitor resolveAnnotation(
@NotNull JvmClassName className, @NotNull JvmClassName className,
@NotNull final List<AnnotationDescriptor> result @NotNull final List<AnnotationDescriptor> result,
@NotNull final DependencyClassByQualifiedNameResolver classResolver
) { ) {
if (ignoreAnnotation(className)) return null; if (ignoreAnnotation(className)) return null;
final ClassDescriptor annotationClass = resolveClass(className); final ClassDescriptor annotationClass = resolveClass(className, classResolver);
final AnnotationDescriptorImpl annotation = new AnnotationDescriptorImpl(); final AnnotationDescriptorImpl annotation = new AnnotationDescriptorImpl();
annotation.setAnnotationType(annotationClass.getDefaultType()); annotation.setAnnotationType(annotationClass.getDefaultType());
@@ -188,7 +153,7 @@ public class AnnotationDescriptorDeserializer implements AnnotationDeserializer
@NotNull @NotNull
private CompileTimeConstant<?> enumEntryValue(@NotNull JvmClassName enumClassName, @NotNull Name name) { private CompileTimeConstant<?> enumEntryValue(@NotNull JvmClassName enumClassName, @NotNull Name name) {
ClassDescriptor enumClass = resolveClass(enumClassName); ClassDescriptor enumClass = resolveClass(enumClassName, classResolver);
if (enumClass.getKind() == ClassKind.ENUM_CLASS) { if (enumClass.getKind() == ClassKind.ENUM_CLASS) {
ClassifierDescriptor classifier = enumClass.getUnsubstitutedInnerClassesScope().getClassifier(name); ClassifierDescriptor classifier = enumClass.getUnsubstitutedInnerClassesScope().getClassifier(name);
if (classifier instanceof ClassDescriptor) { if (classifier instanceof ClassDescriptor) {
@@ -213,7 +178,7 @@ public class AnnotationDescriptorDeserializer implements AnnotationDeserializer
} }
@NotNull @NotNull
private ClassDescriptor resolveClass(@NotNull JvmClassName className) { private static ClassDescriptor resolveClass(@NotNull JvmClassName className, DependencyClassByQualifiedNameResolver classResolver) {
ClassDescriptor annotationClass = classResolver.resolveClass(className.getFqNameForClassNameWithoutDollars()); ClassDescriptor annotationClass = classResolver.resolveClass(className.getFqNameForClassNameWithoutDollars());
return annotationClass != null ? annotationClass : ErrorUtils.getErrorClass(); return annotationClass != null ? annotationClass : ErrorUtils.getErrorClass();
} }
@@ -246,257 +211,10 @@ public class AnnotationDescriptorDeserializer implements AnnotationDeserializer
return Annotations.EMPTY; return Annotations.EMPTY;
} }
List<AnnotationDescriptor> annotations = memberAnnotations.invoke(kotlinClass).get(signature); List<AnnotationDescriptor> annotations = storage.getMemberAnnotations().invoke(kotlinClass).get(signature);
return annotations == null ? Annotations.EMPTY : new AnnotationsImpl(annotations); 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<MemberSignature, List<AnnotationDescriptor>> loadMemberAnnotationsFromClass(@NotNull KotlinJvmBinaryClass kotlinClass)
throws IOException {
final Map<MemberSignature, List<AnnotationDescriptor>> memberAnnotations =
new HashMap<MemberSignature, List<AnnotationDescriptor>>();
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<AnnotationDescriptor> result = memberAnnotations.get(paramSignature);
if (result == null) {
result = new ArrayList<AnnotationDescriptor>();
memberAnnotations.put(paramSignature, result);
}
return resolveAnnotation(className, result);
}
}
class MemberAnnotationVisitor implements KotlinJvmBinaryClass.AnnotationVisitor {
private final List<AnnotationDescriptor> result = new ArrayList<AnnotationDescriptor>();
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 @NotNull
@Override @Override
public Annotations loadValueParameterAnnotations( public Annotations loadValueParameterAnnotations(
@@ -517,4 +235,4 @@ public class AnnotationDescriptorDeserializer implements AnnotationDeserializer
return Annotations.EMPTY; return Annotations.EMPTY;
} }
} }
@@ -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('.', '/');
}
}
}
@@ -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;
}
}
@@ -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<KotlinJvmBinaryClass, Map<MemberSignature, List<AnnotationDescriptor>>> memberAnnotations;
public DescriptorDeserializersStorage(@NotNull StorageManager storageManager) {
this.memberAnnotations = storageManager.createMemoizedFunction(
new Function1<KotlinJvmBinaryClass, Map<MemberSignature, List<AnnotationDescriptor>>>() {
@NotNull
@Override
public Map<MemberSignature, List<AnnotationDescriptor>> 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<KotlinJvmBinaryClass, Map<MemberSignature, List<AnnotationDescriptor>>> getMemberAnnotations() {
return memberAnnotations;
}
@NotNull
protected Map<MemberSignature, List<AnnotationDescriptor>> loadMemberAnnotationsFromClass(@NotNull KotlinJvmBinaryClass kotlinClass)
throws IOException {
final Map<MemberSignature, List<AnnotationDescriptor>> memberAnnotations =
new HashMap<MemberSignature, List<AnnotationDescriptor>>();
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<AnnotationDescriptor> result = memberAnnotations.get(paramSignature);
if (result == null) {
result = new ArrayList<AnnotationDescriptor>();
memberAnnotations.put(paramSignature, result);
}
return AnnotationDescriptorDeserializer.resolveAnnotation(className, result, classResolver);
}
}
class MemberAnnotationVisitor implements KotlinJvmBinaryClass.AnnotationVisitor {
private final List<AnnotationDescriptor> result = new ArrayList<AnnotationDescriptor>();
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;
}
}
}
@@ -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; import static org.jetbrains.jet.lang.resolve.kotlin.header.KotlinClassHeader.Kind.PACKAGE_FACADE;
public final class DeserializedDescriptorResolver { public final class DeserializedDescriptorResolver {
private AnnotationDescriptorDeserializer annotationDeserializer; private DescriptorDeserializers annotationDeserializer;
private StorageManager storageManager; private StorageManager storageManager;
@@ -69,7 +69,7 @@ public final class DeserializedDescriptorResolver {
}; };
@Inject @Inject
public void setAnnotationDeserializer(AnnotationDescriptorDeserializer annotationDeserializer) { public void setAnnotationDeserializer(DescriptorDeserializers annotationDeserializer) {
this.annotationDeserializer = annotationDeserializer; this.annotationDeserializer = annotationDeserializer;
} }
@@ -4,7 +4,7 @@ import kotlin.Function0;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.descriptors.serialization.*; 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.descriptors.serialization.descriptors.DeserializedPackageMemberScope;
import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.annotations.Annotations; import org.jetbrains.jet.lang.descriptors.annotations.Annotations;
@@ -39,7 +39,7 @@ class BuiltinsPackageFragment extends DeclarationDescriptorImpl implements Packa
packageFragmentProvider = new BuiltinsPackageFragmentProvider(); packageFragmentProvider = new BuiltinsPackageFragmentProvider();
// TODO: support annotations // TODO: support annotations
members = new DeserializedPackageMemberScope(storageManager, this, AnnotationDeserializer.UNSUPPORTED, members = new DeserializedPackageMemberScope(storageManager, this, Deserializers.UNSUPPORTED,
new BuiltInsDescriptorFinder(storageManager), loadPackage(), nameResolver); new BuiltInsDescriptorFinder(storageManager), loadPackage(), nameResolver);
} }
@@ -133,7 +133,7 @@ class BuiltinsPackageFragment extends DeclarationDescriptorImpl implements Packa
public BuiltInsDescriptorFinder(@NotNull StorageManager storageManager) { public BuiltInsDescriptorFinder(@NotNull StorageManager storageManager) {
// TODO: support annotations // TODO: support annotations
super(storageManager, AnnotationDeserializer.UNSUPPORTED, packageFragmentProvider); super(storageManager, Deserializers.UNSUPPORTED, packageFragmentProvider);
classNames = storageManager.createLazyValue(new Function0<Collection<Name>>() { classNames = storageManager.createLazyValue(new Function0<Collection<Name>>() {
@Override @Override
@@ -194,4 +194,4 @@ class BuiltinsPackageFragment extends DeclarationDescriptorImpl implements Packa
return packageName.equals(KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME) ? classNames.invoke() : Collections.<Name>emptyList(); return packageName.equals(KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME) ? classNames.invoke() : Collections.<Name>emptyList();
} }
} }
} }
@@ -40,6 +40,8 @@ import org.jetbrains.jet.lang.resolve.java.PackageClassUtils
import com.intellij.openapi.diagnostic.Logger import com.intellij.openapi.diagnostic.Logger
import org.jetbrains.jet.lang.resolve.kotlin.KotlinClassFinder import org.jetbrains.jet.lang.resolve.kotlin.KotlinClassFinder
import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe 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 { public fun DeserializerForDecompiler(classFile: VirtualFile): DeserializerForDecompiler {
val kotlinClass = KotlinBinaryClassCache.getKotlinBinaryClass(classFile) val kotlinClass = KotlinBinaryClassCache.getKotlinBinaryClass(classFile)
@@ -64,7 +66,7 @@ public class DeserializerForDecompiler(val packageDirectory: VirtualFile, val di
val membersScope = DeserializedPackageMemberScope( val membersScope = DeserializedPackageMemberScope(
storageManager, storageManager,
createDummyPackageFragment(packageFqName), createDummyPackageFragment(packageFqName),
annotationDeserializer, deserializers,
descriptorFinder, descriptorFinder,
JavaProtoBufUtil.readPackageDataFrom(annotationData) JavaProtoBufUtil.readPackageDataFrom(annotationData)
) )
@@ -93,7 +95,16 @@ public class DeserializerForDecompiler(val packageDirectory: VirtualFile, val di
resolveClassByClassId(classId) 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 { annotationDeserializer.setClassResolver {
fqName -> fqName ->
@@ -101,6 +112,12 @@ public class DeserializerForDecompiler(val packageDirectory: VirtualFile, val di
} }
annotationDeserializer.setKotlinClassFinder(localClassFinder) annotationDeserializer.setKotlinClassFinder(localClassFinder)
annotationDeserializer.setErrorReporter(LOGGING_REPORTER) annotationDeserializer.setErrorReporter(LOGGING_REPORTER)
annotationDeserializer.setStorage(deserializerStorage)
}
private val deserializers = DescriptorDeserializers();
{
deserializers.setAnnotationDescriptorDeserializer(annotationDeserializer)
} }
private val descriptorFinder = object : DescriptorFinder { 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()}") LOG.error("Annotation data missing for ${kotlinClass.getClassName()}")
} }
val classData = JavaProtoBufUtil.readClassDataFrom(data!!) val classData = JavaProtoBufUtil.readClassDataFrom(data!!)
return DeserializedClassDescriptor(storageManager, annotationDeserializer, descriptorFinder, packageFragmentProvider, return DeserializedClassDescriptor(storageManager, deserializers, descriptorFinder, packageFragmentProvider,
classData.getNameResolver(), classData.getClassProto()) classData.getNameResolver(), classData.getClassProto())
} }