Convert AnnotationDescriptorLoader, ConstantDescriptorLoader and DescriptorLoadersStorage
This commit is contained in:
+125
-185
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2013 JetBrains s.r.o.
|
* Copyright 2010-2014 JetBrains s.r.o.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -14,223 +14,163 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.jetbrains.jet.lang.resolve.kotlin;
|
package org.jetbrains.jet.lang.resolve.kotlin
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.jet.descriptors.serialization.JavaProtoBuf
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.jet.descriptors.serialization.NameResolver
|
||||||
import org.jetbrains.jet.descriptors.serialization.JavaProtoBuf;
|
import org.jetbrains.jet.descriptors.serialization.ProtoBuf
|
||||||
import org.jetbrains.jet.descriptors.serialization.NameResolver;
|
import org.jetbrains.jet.descriptors.serialization.*
|
||||||
import org.jetbrains.jet.descriptors.serialization.ProtoBuf;
|
import org.jetbrains.jet.descriptors.serialization.descriptors.AnnotatedCallableKind
|
||||||
import org.jetbrains.jet.descriptors.serialization.SerializationPackage;
|
import org.jetbrains.jet.descriptors.serialization.descriptors.AnnotationLoader
|
||||||
import org.jetbrains.jet.descriptors.serialization.descriptors.AnnotatedCallableKind;
|
import org.jetbrains.jet.descriptors.serialization.descriptors.ProtoContainer
|
||||||
import org.jetbrains.jet.descriptors.serialization.descriptors.AnnotationLoader;
|
import org.jetbrains.jet.lang.descriptors.*
|
||||||
import org.jetbrains.jet.descriptors.serialization.descriptors.ProtoContainer;
|
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor
|
||||||
import org.jetbrains.jet.lang.descriptors.*;
|
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptorImpl
|
||||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
import org.jetbrains.jet.lang.resolve.constants.*
|
||||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptorImpl;
|
import org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames
|
||||||
import org.jetbrains.jet.lang.resolve.constants.*;
|
import org.jetbrains.jet.lang.resolve.java.resolver.DescriptorResolverUtils
|
||||||
import org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames;
|
import org.jetbrains.jet.lang.resolve.java.resolver.ErrorReporter
|
||||||
import org.jetbrains.jet.lang.resolve.java.resolver.DescriptorResolverUtils;
|
import org.jetbrains.jet.lang.resolve.kotlin.KotlinJvmBinaryClass.AnnotationArrayArgumentVisitor
|
||||||
import org.jetbrains.jet.lang.resolve.java.resolver.ErrorReporter;
|
import org.jetbrains.jet.lang.resolve.name.ClassId
|
||||||
import org.jetbrains.jet.lang.resolve.kotlin.KotlinJvmBinaryClass.AnnotationArrayArgumentVisitor;
|
import org.jetbrains.jet.lang.resolve.name.Name
|
||||||
import org.jetbrains.jet.lang.resolve.name.ClassId;
|
import org.jetbrains.jet.lang.types.ErrorUtils
|
||||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
|
||||||
import org.jetbrains.jet.lang.types.ErrorUtils;
|
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*
|
||||||
|
|
||||||
import static org.jetbrains.jet.lang.resolve.kotlin.DescriptorLoadersStorage.MemberSignature;
|
import org.jetbrains.jet.lang.resolve.kotlin.DescriptorLoadersStorage.MemberSignature
|
||||||
import static org.jetbrains.jet.lang.resolve.kotlin.DeserializedResolverUtils.javaClassIdToKotlinClassId;
|
import org.jetbrains.jet.lang.resolve.kotlin.DeserializedResolverUtils.javaClassIdToKotlinClassId
|
||||||
|
|
||||||
public class AnnotationDescriptorLoader extends BaseDescriptorLoader implements AnnotationLoader {
|
public class AnnotationDescriptorLoader(private val module: ModuleDescriptor, storage: DescriptorLoadersStorage, kotlinClassFinder: KotlinClassFinder, errorReporter: ErrorReporter) : BaseDescriptorLoader(kotlinClassFinder, errorReporter, storage), AnnotationLoader {
|
||||||
private final ModuleDescriptor module;
|
|
||||||
|
|
||||||
public AnnotationDescriptorLoader(
|
override fun loadClassAnnotations(classProto: ProtoBuf.Class, nameResolver: NameResolver): List<AnnotationDescriptor> {
|
||||||
@NotNull ModuleDescriptor module,
|
val classId = nameResolver.getClassId(classProto.getFqName())
|
||||||
@NotNull DescriptorLoadersStorage storage,
|
val kotlinClass = findKotlinClassById(classId)
|
||||||
@NotNull KotlinClassFinder kotlinClassFinder,
|
|
||||||
@NotNull ErrorReporter errorReporter
|
|
||||||
) {
|
|
||||||
super(kotlinClassFinder, errorReporter, storage);
|
|
||||||
this.module = module;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Override
|
|
||||||
public List<AnnotationDescriptor> loadClassAnnotations(
|
|
||||||
@NotNull ProtoBuf.Class classProto,
|
|
||||||
@NotNull NameResolver nameResolver
|
|
||||||
) {
|
|
||||||
ClassId classId = nameResolver.getClassId(classProto.getFqName());
|
|
||||||
KotlinJvmBinaryClass kotlinClass = findKotlinClassById(classId);
|
|
||||||
if (kotlinClass == null) {
|
if (kotlinClass == null) {
|
||||||
// This means that the resource we're constructing the descriptor from is no longer present: KotlinClassFinder had found the
|
// This means that the resource we're constructing the descriptor from is no longer present: KotlinClassFinder had found the
|
||||||
// class earlier, but it can't now
|
// class earlier, but it can't now
|
||||||
getErrorReporter().reportLoadingError("Kotlin class for loading class annotations is not found: " + classId.asSingleFqName(), null);
|
errorReporter.reportLoadingError("Kotlin class for loading class annotations is not found: " + classId.asSingleFqName(), null)
|
||||||
return Collections.emptyList();
|
return listOf()
|
||||||
}
|
}
|
||||||
|
|
||||||
final List<AnnotationDescriptor> result = new ArrayList<AnnotationDescriptor>(1);
|
val result = ArrayList<AnnotationDescriptor>(1)
|
||||||
|
|
||||||
kotlinClass.loadClassAnnotations(new KotlinJvmBinaryClass.AnnotationVisitor() {
|
kotlinClass.loadClassAnnotations(object : KotlinJvmBinaryClass.AnnotationVisitor {
|
||||||
@Nullable
|
override fun visitAnnotation(classId: ClassId): KotlinJvmBinaryClass.AnnotationArgumentVisitor? {
|
||||||
@Override
|
return resolveAnnotation(classId, result, module)
|
||||||
public KotlinJvmBinaryClass.AnnotationArgumentVisitor visitAnnotation(@NotNull ClassId classId) {
|
|
||||||
return resolveAnnotation(classId, result, module);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun visitEnd() {
|
||||||
public void visitEnd() {
|
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
|
|
||||||
return result;
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
override fun loadCallableAnnotations(container: ProtoContainer, proto: ProtoBuf.Callable, nameResolver: NameResolver, kind: AnnotatedCallableKind): List<AnnotationDescriptor> {
|
||||||
public static KotlinJvmBinaryClass.AnnotationArgumentVisitor resolveAnnotation(
|
val signature = getCallableSignature(proto, nameResolver, kind)
|
||||||
@NotNull ClassId classId,
|
if (signature == null) return listOf()
|
||||||
@NotNull final List<AnnotationDescriptor> result,
|
|
||||||
@NotNull final ModuleDescriptor moduleDescriptor
|
|
||||||
) {
|
|
||||||
if (JvmAnnotationNames.isSpecialAnnotation(classId, true)) return null;
|
|
||||||
|
|
||||||
final ClassDescriptor annotationClass = resolveClass(classId, moduleDescriptor);
|
return findClassAndLoadMemberAnnotations(container, proto, nameResolver, kind, signature)
|
||||||
|
}
|
||||||
|
|
||||||
return new KotlinJvmBinaryClass.AnnotationArgumentVisitor() {
|
private fun findClassAndLoadMemberAnnotations(container: ProtoContainer, proto: ProtoBuf.Callable, nameResolver: NameResolver, kind: AnnotatedCallableKind, signature: MemberSignature): List<AnnotationDescriptor> {
|
||||||
private final Map<ValueParameterDescriptor, CompileTimeConstant<?>> arguments = new HashMap<ValueParameterDescriptor, CompileTimeConstant<?>>();
|
val kotlinClass = findClassWithAnnotationsAndInitializers(container, proto, nameResolver, kind)
|
||||||
|
if (kotlinClass == null) {
|
||||||
|
errorReporter.reportLoadingError("Kotlin class for loading member annotations is not found: " + container, null)
|
||||||
|
return listOf()
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
val descriptors = storage.getStorageForClass(kotlinClass).memberAnnotations.get(signature)
|
||||||
public void visit(@Nullable Name name, @Nullable Object value) {
|
return if (descriptors == null) listOf<AnnotationDescriptor>() else descriptors
|
||||||
if (name != null) {
|
}
|
||||||
setArgumentValueByName(name, createConstant(name, value));
|
|
||||||
|
override fun loadValueParameterAnnotations(container: ProtoContainer, callable: ProtoBuf.Callable, nameResolver: NameResolver, kind: AnnotatedCallableKind, proto: ProtoBuf.Callable.ValueParameter): List<AnnotationDescriptor> {
|
||||||
|
val methodSignature = getCallableSignature(callable, nameResolver, kind)
|
||||||
|
if (methodSignature != null) {
|
||||||
|
if (proto.hasExtension<Int>(JavaProtoBuf.index)) {
|
||||||
|
val paramSignature = MemberSignature.fromMethodSignatureAndParameterIndex(methodSignature, proto.getExtension<Int>(JavaProtoBuf.index))
|
||||||
|
return findClassAndLoadMemberAnnotations(container, callable, nameResolver, kind, paramSignature)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return listOf()
|
||||||
|
}
|
||||||
|
|
||||||
|
class object {
|
||||||
|
|
||||||
|
public fun resolveAnnotation(classId: ClassId, result: MutableList<AnnotationDescriptor>, moduleDescriptor: ModuleDescriptor): KotlinJvmBinaryClass.AnnotationArgumentVisitor? {
|
||||||
|
if (JvmAnnotationNames.isSpecialAnnotation(classId, true)) return null
|
||||||
|
|
||||||
|
val annotationClass = resolveClass(classId, moduleDescriptor)
|
||||||
|
|
||||||
|
return object : KotlinJvmBinaryClass.AnnotationArgumentVisitor {
|
||||||
|
private val arguments = HashMap<ValueParameterDescriptor, CompileTimeConstant<*>>()
|
||||||
|
|
||||||
|
override fun visit(name: Name?, value: Any?) {
|
||||||
|
if (name != null) {
|
||||||
|
setArgumentValueByName(name, createConstant(name, value))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
override fun visitEnum(name: Name, enumClassId: ClassId, enumEntryName: Name) {
|
||||||
public void visitEnum(@NotNull Name name, @NotNull ClassId enumClassId, @NotNull Name enumEntryName) {
|
setArgumentValueByName(name, enumEntryValue(enumClassId, enumEntryName))
|
||||||
setArgumentValueByName(name, enumEntryValue(enumClassId, enumEntryName));
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
override fun visitArray(name: Name): AnnotationArrayArgumentVisitor? {
|
||||||
@Override
|
return object : KotlinJvmBinaryClass.AnnotationArrayArgumentVisitor {
|
||||||
public AnnotationArrayArgumentVisitor visitArray(@NotNull final Name name) {
|
private val elements = ArrayList<CompileTimeConstant<*>>()
|
||||||
return new KotlinJvmBinaryClass.AnnotationArrayArgumentVisitor() {
|
|
||||||
private final ArrayList<CompileTimeConstant<?>> elements = new ArrayList<CompileTimeConstant<?>>();
|
|
||||||
|
|
||||||
@Override
|
override fun visit(value: Any?) {
|
||||||
public void visit(@Nullable Object value) {
|
elements.add(createConstant(name, value))
|
||||||
elements.add(createConstant(name, value));
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
override fun visitEnum(enumClassId: ClassId, enumEntryName: Name) {
|
||||||
public void visitEnum(@NotNull ClassId enumClassId, @NotNull Name enumEntryName) {
|
elements.add(enumEntryValue(enumClassId, enumEntryName))
|
||||||
elements.add(enumEntryValue(enumClassId, enumEntryName));
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
override fun visitEnd() {
|
||||||
public void visitEnd() {
|
val parameter = DescriptorResolverUtils.getAnnotationParameterByName(name, annotationClass)
|
||||||
ValueParameterDescriptor parameter = DescriptorResolverUtils.getAnnotationParameterByName(name, annotationClass);
|
if (parameter != null) {
|
||||||
if (parameter != null) {
|
elements.trimToSize()
|
||||||
elements.trimToSize();
|
arguments.put(parameter, ArrayValue(elements, parameter.getType(), true, false))
|
||||||
arguments.put(parameter, new ArrayValue(elements, parameter.getType(), true, false));
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
private fun enumEntryValue(enumClassId: ClassId, name: Name): CompileTimeConstant<*> {
|
||||||
private CompileTimeConstant<?> enumEntryValue(@NotNull ClassId enumClassId, @NotNull Name name) {
|
val enumClass = resolveClass(enumClassId, moduleDescriptor)
|
||||||
ClassDescriptor enumClass = resolveClass(enumClassId, moduleDescriptor);
|
if (enumClass.getKind() == ClassKind.ENUM_CLASS) {
|
||||||
if (enumClass.getKind() == ClassKind.ENUM_CLASS) {
|
val classifier = enumClass.getUnsubstitutedInnerClassesScope().getClassifier(name)
|
||||||
ClassifierDescriptor classifier = enumClass.getUnsubstitutedInnerClassesScope().getClassifier(name);
|
if (classifier is ClassDescriptor) {
|
||||||
if (classifier instanceof ClassDescriptor) {
|
return EnumValue(classifier as ClassDescriptor, false)
|
||||||
return new EnumValue((ClassDescriptor) classifier, false);
|
}
|
||||||
|
}
|
||||||
|
return ErrorValue.create("Unresolved enum entry: " + enumClassId + "." + name)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitEnd() {
|
||||||
|
result.add(AnnotationDescriptorImpl(annotationClass.getDefaultType(), arguments))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createConstant(name: Name?, value: Any?): CompileTimeConstant<*> {
|
||||||
|
val argument = createCompileTimeConstant(value, true, false, false, null)
|
||||||
|
return if (argument != null) argument else ErrorValue.create("Unsupported annotation argument: " + name)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setArgumentValueByName(name: Name, argumentValue: CompileTimeConstant<*>) {
|
||||||
|
val parameter = DescriptorResolverUtils.getAnnotationParameterByName(name, annotationClass)
|
||||||
|
if (parameter != null) {
|
||||||
|
arguments.put(parameter, argumentValue)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ErrorValue.create("Unresolved enum entry: " + enumClassId + "." + name);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitEnd() {
|
|
||||||
result.add(new AnnotationDescriptorImpl(
|
|
||||||
annotationClass.getDefaultType(),
|
|
||||||
arguments
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private CompileTimeConstant<?> createConstant(@Nullable Name name, @Nullable Object value) {
|
|
||||||
CompileTimeConstant<?> argument = ConstantsPackage.createCompileTimeConstant(value, true, false, false, null);
|
|
||||||
return argument != null ? argument : ErrorValue.create("Unsupported annotation argument: " + name);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setArgumentValueByName(@NotNull Name name, @NotNull CompileTimeConstant<?> argumentValue) {
|
|
||||||
ValueParameterDescriptor parameter = DescriptorResolverUtils.getAnnotationParameterByName(name, annotationClass);
|
|
||||||
if (parameter != null) {
|
|
||||||
arguments.put(parameter, argumentValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private static ClassDescriptor resolveClass(@NotNull ClassId javaClassId, @NotNull ModuleDescriptor moduleDescriptor) {
|
|
||||||
ClassId classId = javaClassIdToKotlinClassId(javaClassId);
|
|
||||||
ClassDescriptor classDescriptor = SerializationPackage.findClassAcrossModuleDependencies(moduleDescriptor, classId);
|
|
||||||
return classDescriptor != null ? classDescriptor : ErrorUtils.createErrorClass(classId.asSingleFqName().asString());
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Override
|
|
||||||
public List<AnnotationDescriptor> loadCallableAnnotations(
|
|
||||||
@NotNull ProtoContainer container,
|
|
||||||
@NotNull ProtoBuf.Callable proto,
|
|
||||||
@NotNull NameResolver nameResolver,
|
|
||||||
@NotNull AnnotatedCallableKind kind
|
|
||||||
) {
|
|
||||||
MemberSignature signature = getCallableSignature(proto, nameResolver, kind);
|
|
||||||
if (signature == null) return Collections.emptyList();
|
|
||||||
|
|
||||||
return findClassAndLoadMemberAnnotations(container, proto, nameResolver, kind, signature);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private List<AnnotationDescriptor> findClassAndLoadMemberAnnotations(
|
|
||||||
@NotNull ProtoContainer container,
|
|
||||||
@NotNull ProtoBuf.Callable proto,
|
|
||||||
@NotNull NameResolver nameResolver,
|
|
||||||
@NotNull AnnotatedCallableKind kind,
|
|
||||||
@NotNull MemberSignature signature
|
|
||||||
) {
|
|
||||||
KotlinJvmBinaryClass kotlinClass = findClassWithAnnotationsAndInitializers(container, proto, nameResolver, kind);
|
|
||||||
if (kotlinClass == null) {
|
|
||||||
getErrorReporter().reportLoadingError("Kotlin class for loading member annotations is not found: " + container, null);
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
|
|
||||||
List<AnnotationDescriptor> descriptors = getStorage().getStorageForClass(kotlinClass).getMemberAnnotations().get(signature);
|
|
||||||
return descriptors == null ? Collections.<AnnotationDescriptor>emptyList() : descriptors;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Override
|
|
||||||
public List<AnnotationDescriptor> loadValueParameterAnnotations(
|
|
||||||
@NotNull ProtoContainer container,
|
|
||||||
@NotNull ProtoBuf.Callable callable,
|
|
||||||
@NotNull NameResolver nameResolver,
|
|
||||||
@NotNull AnnotatedCallableKind kind,
|
|
||||||
@NotNull ProtoBuf.Callable.ValueParameter proto
|
|
||||||
) {
|
|
||||||
MemberSignature methodSignature = getCallableSignature(callable, nameResolver, kind);
|
|
||||||
if (methodSignature != null) {
|
|
||||||
if (proto.hasExtension(JavaProtoBuf.index)) {
|
|
||||||
MemberSignature paramSignature =
|
|
||||||
MemberSignature.fromMethodSignatureAndParameterIndex(methodSignature, proto.getExtension(JavaProtoBuf.index));
|
|
||||||
return findClassAndLoadMemberAnnotations(container, callable, nameResolver, kind, paramSignature);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Collections.emptyList();
|
private fun resolveClass(javaClassId: ClassId, moduleDescriptor: ModuleDescriptor): ClassDescriptor {
|
||||||
|
val classId = javaClassIdToKotlinClassId(javaClassId)
|
||||||
|
val classDescriptor = moduleDescriptor.findClassAcrossModuleDependencies(classId)
|
||||||
|
return if (classDescriptor != null) classDescriptor else ErrorUtils.createErrorClass(classId.asSingleFqName().asString())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+17
-33
@@ -14,46 +14,30 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.jetbrains.jet.lang.resolve.kotlin;
|
package org.jetbrains.jet.lang.resolve.kotlin
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.jet.descriptors.serialization.NameResolver
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.jet.descriptors.serialization.ProtoBuf
|
||||||
import org.jetbrains.jet.descriptors.serialization.NameResolver;
|
import org.jetbrains.jet.descriptors.serialization.descriptors.AnnotatedCallableKind
|
||||||
import org.jetbrains.jet.descriptors.serialization.ProtoBuf;
|
import org.jetbrains.jet.descriptors.serialization.descriptors.ConstantLoader
|
||||||
import org.jetbrains.jet.descriptors.serialization.descriptors.AnnotatedCallableKind;
|
import org.jetbrains.jet.descriptors.serialization.descriptors.ProtoContainer
|
||||||
import org.jetbrains.jet.descriptors.serialization.descriptors.ConstantLoader;
|
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant
|
||||||
import org.jetbrains.jet.descriptors.serialization.descriptors.ProtoContainer;
|
import org.jetbrains.jet.lang.resolve.java.resolver.ErrorReporter
|
||||||
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
|
|
||||||
import org.jetbrains.jet.lang.resolve.java.resolver.ErrorReporter;
|
|
||||||
|
|
||||||
import static org.jetbrains.jet.lang.resolve.kotlin.DescriptorLoadersStorage.MemberSignature;
|
import org.jetbrains.jet.lang.resolve.kotlin.DescriptorLoadersStorage.MemberSignature
|
||||||
|
|
||||||
public class ConstantDescriptorLoader extends BaseDescriptorLoader implements ConstantLoader {
|
public class ConstantDescriptorLoader(storage: DescriptorLoadersStorage, kotlinClassFinder: KotlinClassFinder, errorReporter: ErrorReporter) : BaseDescriptorLoader(kotlinClassFinder, errorReporter, storage), ConstantLoader {
|
||||||
public ConstantDescriptorLoader(
|
|
||||||
@NotNull DescriptorLoadersStorage storage,
|
|
||||||
@NotNull KotlinClassFinder kotlinClassFinder,
|
|
||||||
@NotNull ErrorReporter errorReporter
|
|
||||||
) {
|
|
||||||
super(kotlinClassFinder, errorReporter, storage);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
override fun loadPropertyConstant(container: ProtoContainer, proto: ProtoBuf.Callable, nameResolver: NameResolver, kind: AnnotatedCallableKind): CompileTimeConstant<*>? {
|
||||||
@Override
|
val signature = getCallableSignature(proto, nameResolver, kind)
|
||||||
public CompileTimeConstant<?> loadPropertyConstant(
|
if (signature == null) return null
|
||||||
@NotNull ProtoContainer container,
|
|
||||||
@NotNull ProtoBuf.Callable proto,
|
|
||||||
@NotNull NameResolver nameResolver,
|
|
||||||
@NotNull AnnotatedCallableKind kind
|
|
||||||
) {
|
|
||||||
MemberSignature signature = getCallableSignature(proto, nameResolver, kind);
|
|
||||||
if (signature == null) return null;
|
|
||||||
|
|
||||||
KotlinJvmBinaryClass kotlinClass = findClassWithAnnotationsAndInitializers(container, proto, nameResolver, kind);
|
val kotlinClass = findClassWithAnnotationsAndInitializers(container, proto, nameResolver, kind)
|
||||||
if (kotlinClass == null) {
|
if (kotlinClass == null) {
|
||||||
getErrorReporter().reportLoadingError("Kotlin class for loading property constant is not found: " + container, null);
|
errorReporter.reportLoadingError("Kotlin class for loading property constant is not found: " + container, null)
|
||||||
return null;
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
return getStorage().getStorageForClass(kotlinClass).getPropertyConstants().get(signature);
|
return storage.getStorageForClass(kotlinClass).propertyConstants.get(signature)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+93
-152
@@ -1,216 +1,157 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2014 JetBrains s.r.o.
|
* Copyright 2010-2014 JetBrains s.r.o.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.jetbrains.jet.lang.resolve.kotlin;
|
package org.jetbrains.jet.lang.resolve.kotlin
|
||||||
|
|
||||||
import kotlin.Function1;
|
import org.jetbrains.jet.lang.descriptors.ModuleDescriptor
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.jet.lang.resolve.constants.*
|
||||||
import org.jetbrains.jet.lang.descriptors.ModuleDescriptor;
|
import org.jetbrains.jet.lang.resolve.name.ClassId
|
||||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
import org.jetbrains.jet.lang.resolve.name.Name
|
||||||
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
|
import org.jetbrains.jet.storage.MemoizedFunctionToNotNull
|
||||||
import org.jetbrains.jet.lang.resolve.constants.ConstantsPackage;
|
import org.jetbrains.jet.storage.StorageManager
|
||||||
import org.jetbrains.jet.lang.resolve.name.ClassId;
|
|
||||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
|
||||||
import org.jetbrains.jet.storage.MemoizedFunctionToNotNull;
|
|
||||||
import org.jetbrains.jet.storage.StorageManager;
|
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*
|
||||||
|
import kotlin.platform.platformStatic
|
||||||
|
|
||||||
public class DescriptorLoadersStorage {
|
public class DescriptorLoadersStorage(storageManager: StorageManager, private val module: ModuleDescriptor) {
|
||||||
private final MemoizedFunctionToNotNull<KotlinJvmBinaryClass, Storage> storage;
|
private val storage: MemoizedFunctionToNotNull<KotlinJvmBinaryClass, Storage>
|
||||||
private final ModuleDescriptor module;
|
|
||||||
|
|
||||||
public DescriptorLoadersStorage(@NotNull StorageManager storageManager, @NotNull ModuleDescriptor module) {
|
{
|
||||||
this.storage = storageManager.createMemoizedFunction(
|
this.storage = storageManager.createMemoizedFunction<KotlinJvmBinaryClass, Storage>(object : Function1<KotlinJvmBinaryClass, Storage> {
|
||||||
new Function1<KotlinJvmBinaryClass, Storage>() {
|
override fun invoke(kotlinClass: KotlinJvmBinaryClass): Storage {
|
||||||
@NotNull
|
return loadAnnotationsAndInitializers(kotlinClass)
|
||||||
@Override
|
}
|
||||||
public Storage invoke(@NotNull KotlinJvmBinaryClass kotlinClass) {
|
})
|
||||||
return loadAnnotationsAndInitializers(kotlinClass);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
this.module = module;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
public fun getStorageForClass(kotlinClass: KotlinJvmBinaryClass): Storage {
|
||||||
protected Storage getStorageForClass(@NotNull KotlinJvmBinaryClass kotlinClass) {
|
return storage.invoke(kotlinClass)
|
||||||
return storage.invoke(kotlinClass);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
private fun loadAnnotationsAndInitializers(kotlinClass: KotlinJvmBinaryClass): Storage {
|
||||||
private Storage loadAnnotationsAndInitializers(@NotNull KotlinJvmBinaryClass kotlinClass) {
|
val memberAnnotations = HashMap<MemberSignature, MutableList<AnnotationDescriptor>>()
|
||||||
final Map<MemberSignature, List<AnnotationDescriptor>> memberAnnotations = new HashMap<MemberSignature, List<AnnotationDescriptor>>();
|
val propertyConstants = HashMap<MemberSignature, CompileTimeConstant<*>>()
|
||||||
final Map<MemberSignature, CompileTimeConstant<?>> propertyConstants = new HashMap<MemberSignature, CompileTimeConstant<?>>();
|
|
||||||
|
|
||||||
kotlinClass.visitMembers(new KotlinJvmBinaryClass.MemberVisitor() {
|
kotlinClass.visitMembers(object : KotlinJvmBinaryClass.MemberVisitor {
|
||||||
@Nullable
|
override fun visitMethod(name: Name, desc: String): KotlinJvmBinaryClass.MethodAnnotationVisitor? {
|
||||||
@Override
|
return AnnotationVisitorForMethod(MemberSignature.fromMethodNameAndDesc(name.asString() + desc))
|
||||||
public KotlinJvmBinaryClass.MethodAnnotationVisitor visitMethod(@NotNull Name name, @NotNull String desc) {
|
|
||||||
return new AnnotationVisitorForMethod(MemberSignature.fromMethodNameAndDesc(name.asString() + desc));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
override fun visitField(name: Name, desc: String, initializer: Any?): KotlinJvmBinaryClass.AnnotationVisitor? {
|
||||||
@Override
|
val signature = MemberSignature.fromFieldNameAndDesc(name, desc)
|
||||||
public KotlinJvmBinaryClass.AnnotationVisitor visitField(@NotNull Name name, @NotNull String desc, @Nullable Object initializer) {
|
|
||||||
MemberSignature signature = MemberSignature.fromFieldNameAndDesc(name, desc);
|
|
||||||
|
|
||||||
if (initializer != null) {
|
if (initializer != null) {
|
||||||
Object normalizedValue;
|
val normalizedValue: Any
|
||||||
if ("ZBCS".contains(desc)) {
|
if ("ZBCS".contains(desc)) {
|
||||||
int intValue = ((Integer) initializer).intValue();
|
val intValue = initializer as Int
|
||||||
if ("Z".equals(desc)) {
|
if ("Z" == desc) {
|
||||||
normalizedValue = intValue != 0;
|
normalizedValue = intValue != 0
|
||||||
}
|
}
|
||||||
else if ("B".equals(desc)) {
|
else if ("B" == desc) {
|
||||||
normalizedValue = ((byte) intValue);
|
normalizedValue = (intValue.toByte())
|
||||||
}
|
}
|
||||||
else if ("C".equals(desc)) {
|
else if ("C" == desc) {
|
||||||
normalizedValue = ((char) intValue);
|
normalizedValue = (intValue.toChar())
|
||||||
}
|
}
|
||||||
else if ("S".equals(desc)) {
|
else if ("S" == desc) {
|
||||||
normalizedValue = ((short) intValue);
|
normalizedValue = (intValue.toShort())
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw new AssertionError(desc);
|
throw AssertionError(desc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
normalizedValue = initializer;
|
normalizedValue = initializer
|
||||||
}
|
}
|
||||||
|
|
||||||
propertyConstants.put(signature, ConstantsPackage.createCompileTimeConstant(
|
propertyConstants.put(signature, createCompileTimeConstant(normalizedValue, /* canBeUsedInAnnotation */ true, /* isPureIntConstant */ true, /* usesVariableAsConstant */ true, /* expectedType */ null))
|
||||||
normalizedValue,
|
|
||||||
/* canBeUsedInAnnotation */ true,
|
|
||||||
/* isPureIntConstant */ true,
|
|
||||||
/* usesVariableAsConstant */ true,
|
|
||||||
/* expectedType */ null
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
return new MemberAnnotationVisitor(signature);
|
return MemberAnnotationVisitor(signature)
|
||||||
}
|
}
|
||||||
|
|
||||||
class AnnotationVisitorForMethod extends MemberAnnotationVisitor implements KotlinJvmBinaryClass.MethodAnnotationVisitor {
|
inner class AnnotationVisitorForMethod(signature: MemberSignature) : MemberAnnotationVisitor(signature), KotlinJvmBinaryClass.MethodAnnotationVisitor {
|
||||||
public AnnotationVisitorForMethod(@NotNull MemberSignature signature) {
|
|
||||||
super(signature);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
override fun visitParameterAnnotation(index: Int, classId: ClassId): KotlinJvmBinaryClass.AnnotationArgumentVisitor? {
|
||||||
@Override
|
val paramSignature = MemberSignature.fromMethodSignatureAndParameterIndex(signature, index)
|
||||||
public KotlinJvmBinaryClass.AnnotationArgumentVisitor visitParameterAnnotation(int index, @NotNull ClassId classId) {
|
var result = memberAnnotations.get(paramSignature)
|
||||||
MemberSignature paramSignature = MemberSignature.fromMethodSignatureAndParameterIndex(signature, index);
|
|
||||||
List<AnnotationDescriptor> result = memberAnnotations.get(paramSignature);
|
|
||||||
if (result == null) {
|
if (result == null) {
|
||||||
result = new ArrayList<AnnotationDescriptor>();
|
result = ArrayList<AnnotationDescriptor>()
|
||||||
memberAnnotations.put(paramSignature, result);
|
memberAnnotations.put(paramSignature, result)
|
||||||
}
|
}
|
||||||
return AnnotationDescriptorLoader.resolveAnnotation(classId, result, module);
|
return AnnotationDescriptorLoader.resolveAnnotation(classId, result, module)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class MemberAnnotationVisitor implements KotlinJvmBinaryClass.AnnotationVisitor {
|
open inner class MemberAnnotationVisitor(protected val signature: MemberSignature) : KotlinJvmBinaryClass.AnnotationVisitor {
|
||||||
private final List<AnnotationDescriptor> result = new ArrayList<AnnotationDescriptor>();
|
private val result = ArrayList<AnnotationDescriptor>()
|
||||||
protected final MemberSignature signature;
|
|
||||||
|
|
||||||
public MemberAnnotationVisitor(@NotNull MemberSignature signature) {
|
override fun visitAnnotation(classId: ClassId): KotlinJvmBinaryClass.AnnotationArgumentVisitor? {
|
||||||
this.signature = signature;
|
return AnnotationDescriptorLoader.resolveAnnotation(classId, result, module)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
override fun visitEnd() {
|
||||||
@Override
|
|
||||||
public KotlinJvmBinaryClass.AnnotationArgumentVisitor visitAnnotation(@NotNull ClassId classId) {
|
|
||||||
return AnnotationDescriptorLoader.resolveAnnotation(classId, result, module);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitEnd() {
|
|
||||||
if (!result.isEmpty()) {
|
if (!result.isEmpty()) {
|
||||||
memberAnnotations.put(signature, result);
|
memberAnnotations.put(signature, result)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
|
|
||||||
return new Storage(memberAnnotations, propertyConstants);
|
return Storage(memberAnnotations, propertyConstants)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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
|
// 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
|
// into a map indexed by these signatures
|
||||||
public static final class MemberSignature {
|
public class MemberSignature private(private val signature: String) {
|
||||||
private final String signature;
|
|
||||||
|
|
||||||
private MemberSignature(@NotNull String signature) {
|
override fun hashCode(): Int {
|
||||||
this.signature = signature;
|
return signature.hashCode()
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
override fun equals(o: Any?): Boolean {
|
||||||
public static MemberSignature fromMethodNameAndDesc(@NotNull String nameAndDesc) {
|
return o is MemberSignature && signature == (o as MemberSignature).signature
|
||||||
return new MemberSignature(nameAndDesc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
override fun toString(): String {
|
||||||
public static MemberSignature fromFieldNameAndDesc(@NotNull Name name, @NotNull String desc) {
|
return signature
|
||||||
return new MemberSignature(name.asString() + "#" + desc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
class object {
|
||||||
public static MemberSignature fromMethodSignatureAndParameterIndex(@NotNull MemberSignature signature, int index) {
|
|
||||||
return new MemberSignature(signature.signature + "@" + index);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
platformStatic public fun fromMethodNameAndDesc(nameAndDesc: String): MemberSignature {
|
||||||
public int hashCode() {
|
return MemberSignature(nameAndDesc)
|
||||||
return signature.hashCode();
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
platformStatic public fun fromFieldNameAndDesc(name: Name, desc: String): MemberSignature {
|
||||||
public boolean equals(Object o) {
|
return MemberSignature(name.asString() + "#" + desc)
|
||||||
return o instanceof MemberSignature && signature.equals(((MemberSignature) o).signature);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
platformStatic public fun fromMethodSignatureAndParameterIndex(signature: MemberSignature, index: Int): MemberSignature {
|
||||||
public String toString() {
|
return MemberSignature(signature.signature + "@" + index)
|
||||||
return signature;
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static class Storage {
|
class Storage(
|
||||||
private final Map<MemberSignature, List<AnnotationDescriptor>> memberAnnotations;
|
public val memberAnnotations: Map<MemberSignature, List<AnnotationDescriptor>>,
|
||||||
private final Map<MemberSignature, CompileTimeConstant<?>> propertyConstants;
|
public val propertyConstants: Map<MemberSignature, CompileTimeConstant<*>>) {
|
||||||
|
class object {
|
||||||
|
|
||||||
public static final Storage EMPTY = new Storage(
|
public val EMPTY: Storage = Storage(mapOf<MemberSignature, List<AnnotationDescriptor>>(), mapOf<MemberSignature, CompileTimeConstant<*>>())
|
||||||
Collections.<MemberSignature, List<AnnotationDescriptor>>emptyMap(),
|
|
||||||
Collections.<MemberSignature, CompileTimeConstant<?>>emptyMap()
|
|
||||||
);
|
|
||||||
|
|
||||||
public Storage(
|
|
||||||
@NotNull Map<MemberSignature, List<AnnotationDescriptor>> annotations,
|
|
||||||
@NotNull Map<MemberSignature, CompileTimeConstant<?>> constants
|
|
||||||
) {
|
|
||||||
this.memberAnnotations = annotations;
|
|
||||||
this.propertyConstants = constants;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<MemberSignature, List<AnnotationDescriptor>> getMemberAnnotations() {
|
|
||||||
return memberAnnotations;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<MemberSignature, CompileTimeConstant<?>> getPropertyConstants() {
|
|
||||||
return propertyConstants;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user