Convert AnnotationDescriptorLoader, ConstantDescriptorLoader and DescriptorLoadersStorage

This commit is contained in:
Pavel V. Talanov
2014-11-27 14:51:07 +03:00
parent 81ddd16df2
commit 09ff1128ea
3 changed files with 235 additions and 370 deletions
@@ -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())
}
} }
} }
@@ -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)
} }
} }
@@ -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;
} }
} }
} }