diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/AnnotationCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/AnnotationCodegen.java index 45bdebfb4aa..304fc6126ac 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/AnnotationCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/AnnotationCodegen.java @@ -67,10 +67,12 @@ public abstract class AnnotationCodegen { private static final AnnotationVisitor NO_ANNOTATION_VISITOR = new AnnotationVisitor(Opcodes.ASM5) {}; + private final MemberCodegen memberCodegen; private final KotlinTypeMapper typeMapper; - private AnnotationCodegen(KotlinTypeMapper mapper) { - typeMapper = mapper; + private AnnotationCodegen(@NotNull MemberCodegen memberCodegen, @NotNull KotlinTypeMapper mapper) { + this.memberCodegen = memberCodegen; + this.typeMapper = mapper; } /** @@ -284,6 +286,11 @@ public abstract class AnnotationCodegen { } String descriptor = typeMapper.mapType(annotationDescriptor.getType()).getDescriptor(); + + if (classifierDescriptor instanceof ClassDescriptor) { + memberCodegen.addInnerClassInfoFromAnnotation(((ClassDescriptor) classifierDescriptor)); + } + AnnotationVisitor annotationVisitor = visitAnnotation(descriptor, rp == RetentionPolicy.RUNTIME); genAnnotationArguments(annotationDescriptor, annotationVisitor); @@ -481,8 +488,12 @@ public abstract class AnnotationCodegen { @NotNull abstract AnnotationVisitor visitAnnotation(String descr, boolean visible); - public static AnnotationCodegen forClass(final ClassVisitor cv, KotlinTypeMapper mapper) { - return new AnnotationCodegen(mapper) { + public static AnnotationCodegen forClass( + final @NotNull ClassVisitor cv, + @NotNull MemberCodegen memberCodegen, + @NotNull KotlinTypeMapper mapper + ) { + return new AnnotationCodegen(memberCodegen, mapper) { @NotNull @Override AnnotationVisitor visitAnnotation(String descr, boolean visible) { @@ -491,8 +502,12 @@ public abstract class AnnotationCodegen { }; } - public static AnnotationCodegen forMethod(final MethodVisitor mv, KotlinTypeMapper mapper) { - return new AnnotationCodegen(mapper) { + public static AnnotationCodegen forMethod( + final @NotNull MethodVisitor mv, + @NotNull MemberCodegen memberCodegen, + @NotNull KotlinTypeMapper mapper + ) { + return new AnnotationCodegen(memberCodegen, mapper) { @NotNull @Override AnnotationVisitor visitAnnotation(String descr, boolean visible) { @@ -501,8 +516,12 @@ public abstract class AnnotationCodegen { }; } - public static AnnotationCodegen forField(final FieldVisitor fv, KotlinTypeMapper mapper) { - return new AnnotationCodegen(mapper) { + public static AnnotationCodegen forField( + final @NotNull FieldVisitor fv, + @NotNull MemberCodegen memberCodegen, + @NotNull KotlinTypeMapper mapper + ) { + return new AnnotationCodegen(memberCodegen, mapper) { @NotNull @Override AnnotationVisitor visitAnnotation(String descr, boolean visible) { @@ -511,8 +530,13 @@ public abstract class AnnotationCodegen { }; } - public static AnnotationCodegen forParameter(final int parameter, final MethodVisitor mv, KotlinTypeMapper mapper) { - return new AnnotationCodegen(mapper) { + public static AnnotationCodegen forParameter( + final int parameter, + final @NotNull MethodVisitor mv, + @NotNull MemberCodegen memberCodegen, + @NotNull KotlinTypeMapper mapper + ) { + return new AnnotationCodegen(memberCodegen, mapper) { @NotNull @Override AnnotationVisitor visitAnnotation(String descr, boolean visible) { @@ -521,8 +545,12 @@ public abstract class AnnotationCodegen { }; } - public static AnnotationCodegen forAnnotationDefaultValue(final MethodVisitor mv, KotlinTypeMapper mapper) { - return new AnnotationCodegen(mapper) { + public static AnnotationCodegen forAnnotationDefaultValue( + final @NotNull MethodVisitor mv, + @NotNull MemberCodegen memberCodegen, + @NotNull KotlinTypeMapper mapper + ) { + return new AnnotationCodegen(memberCodegen, mapper) { @NotNull @Override AnnotationVisitor visitAnnotation(String descr, boolean visible) { diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/DefaultParameterValueSubstitutor.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/DefaultParameterValueSubstitutor.kt index d8b9777ea32..d08dbe01e82 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/DefaultParameterValueSubstitutor.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/DefaultParameterValueSubstitutor.kt @@ -42,12 +42,13 @@ class DefaultParameterValueSubstitutor(val state: GenerationState) { fun generatePrimaryConstructorOverloadsIfNeeded( constructorDescriptor: ConstructorDescriptor, classBuilder: ClassBuilder, + memberCodegen: MemberCodegen<*>, contextKind: OwnerKind, classOrObject: KtClassOrObject ) { val methodElement = classOrObject.getPrimaryConstructor() ?: classOrObject - if (generateOverloadsIfNeeded(methodElement, constructorDescriptor, constructorDescriptor, contextKind, classBuilder)) { + if (generateOverloadsIfNeeded(methodElement, constructorDescriptor, constructorDescriptor, contextKind, classBuilder, memberCodegen)) { return } @@ -55,8 +56,9 @@ class DefaultParameterValueSubstitutor(val state: GenerationState) { return } - generateOverloadWithSubstitutedParameters(constructorDescriptor, constructorDescriptor, classBuilder, methodElement, contextKind, - constructorDescriptor.countDefaultParameters()) + generateOverloadWithSubstitutedParameters( + constructorDescriptor, constructorDescriptor, classBuilder, memberCodegen, methodElement, contextKind, + constructorDescriptor.countDefaultParameters()) } /** @@ -77,7 +79,8 @@ class DefaultParameterValueSubstitutor(val state: GenerationState) { functionDescriptor: FunctionDescriptor, delegateFunctionDescriptor: FunctionDescriptor, contextKind: OwnerKind, - classBuilder: ClassBuilder + classBuilder: ClassBuilder, + memberCodegen: MemberCodegen<*> ): Boolean { if (!functionDescriptor.hasJvmOverloadsAnnotation()) { return false @@ -87,7 +90,7 @@ class DefaultParameterValueSubstitutor(val state: GenerationState) { for (i in 1..count) { generateOverloadWithSubstitutedParameters( - functionDescriptor, delegateFunctionDescriptor, classBuilder, methodElement, contextKind, i + functionDescriptor, delegateFunctionDescriptor, classBuilder, memberCodegen, methodElement, contextKind, i ) } @@ -112,6 +115,7 @@ class DefaultParameterValueSubstitutor(val state: GenerationState) { functionDescriptor: FunctionDescriptor, delegateFunctionDescriptor: FunctionDescriptor, classBuilder: ClassBuilder, + memberCodegen: MemberCodegen<*>, methodElement: KtElement?, contextKind: OwnerKind, substituteCount: Int @@ -127,10 +131,10 @@ class DefaultParameterValueSubstitutor(val state: GenerationState) { signature.genericsSignature, FunctionCodegen.getThrownExceptions(functionDescriptor, typeMapper)) - AnnotationCodegen.forMethod(mv, typeMapper).genAnnotations(functionDescriptor, signature.returnType) + AnnotationCodegen.forMethod(mv, memberCodegen, typeMapper).genAnnotations(functionDescriptor, signature.returnType) remainingParameters.withIndex().forEach { - val annotationCodegen = AnnotationCodegen.forParameter(it.index, mv, typeMapper) + val annotationCodegen = AnnotationCodegen.forParameter(it.index, mv, memberCodegen, typeMapper) annotationCodegen.genAnnotations(it.value, signature.valueParameters[it.index].asmType) } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java index ea068617c73..892cada62a8 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java @@ -138,7 +138,7 @@ public class FunctionCodegen { @NotNull FunctionDescriptor delegateFunctionDescriptor ) { new DefaultParameterValueSubstitutor(state).generateOverloadsIfNeeded( - function, functionDescriptor, delegateFunctionDescriptor, owner.getContextKind(), v + function, functionDescriptor, delegateFunctionDescriptor, owner.getContextKind(), v, memberCodegen ); } @@ -235,7 +235,7 @@ public class FunctionCodegen { Method asmMethod, MethodVisitor mv ) { - AnnotationCodegen annotationCodegen = AnnotationCodegen.forMethod(mv, typeMapper); + AnnotationCodegen annotationCodegen = AnnotationCodegen.forMethod(mv, memberCodegen, typeMapper); if (functionDescriptor instanceof PropertyAccessorDescriptor) { AnnotationUseSiteTarget target = functionDescriptor instanceof PropertySetterDescriptor ? PROPERTY_SETTER : PROPERTY_GETTER; @@ -264,7 +264,7 @@ public class FunctionCodegen { if (kind == JvmMethodParameterKind.VALUE) { ValueParameterDescriptor parameter = iterator.next(); - AnnotationCodegen annotationCodegen = AnnotationCodegen.forParameter(i, mv, typeMapper); + AnnotationCodegen annotationCodegen = AnnotationCodegen.forParameter(i, mv, memberCodegen, typeMapper); if (functionDescriptor instanceof PropertySetterDescriptor) { PropertyDescriptor propertyDescriptor = ((PropertySetterDescriptor) functionDescriptor).getCorrespondingProperty(); @@ -283,7 +283,7 @@ public class FunctionCodegen { ReceiverParameterDescriptor receiver = JvmCodegenUtil.getDirectMember(functionDescriptor).getExtensionReceiverParameter(); if (receiver != null) { - AnnotationCodegen annotationCodegen = AnnotationCodegen.forParameter(i, mv, typeMapper); + AnnotationCodegen annotationCodegen = AnnotationCodegen.forParameter(i, mv, memberCodegen, typeMapper); Annotated targetedAnnotations = new AnnotatedWithOnlyTargetedAnnotations(receiver.getType()); annotationCodegen.genAnnotations(targetedAnnotations, parameterSignature.getAsmType(), RECEIVER); @@ -713,7 +713,7 @@ public class FunctionCodegen { // Only method annotations are copied to the $default method. Parameter annotations are not copied until there are valid use cases; // enum constructors have two additional synthetic parameters which somewhat complicate this task - AnnotationCodegen.forMethod(mv, typeMapper).genAnnotations(functionDescriptor, defaultMethod.getReturnType()); + AnnotationCodegen.forMethod(mv, memberCodegen, typeMapper).genAnnotations(functionDescriptor, defaultMethod.getReturnType()); if (state.getClassBuilderMode() == ClassBuilderMode.FULL) { if (this.owner instanceof MultifileClassFacadeContext) { diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ImplementationBodyCodegen.java index c1d2ba706ec..bea54cbb5e0 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ImplementationBodyCodegen.java @@ -224,7 +224,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { writeEnclosingMethod(); - AnnotationCodegen.forClass(v.getVisitor(), typeMapper).genAnnotations(descriptor, null); + AnnotationCodegen.forClass(v.getVisitor(), this, typeMapper).genAnnotations(descriptor, null); generateEnumEntries(); } @@ -871,7 +871,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { type.getDescriptor(), typeMapper.mapFieldSignature(property.getType(), property), info.defaultValue); - AnnotationCodegen.forField(fv, typeMapper).genAnnotations(property, type); + AnnotationCodegen.forField(fv, this, typeMapper).genAnnotations(property, type); //This field are always static and final so if it has constant initializer don't do anything in clinit, //field would be initialized via default value in v.newField(...) - see JVM SPEC Ch.4 @@ -939,7 +939,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { functionCodegen.generateDefaultIfNeeded(constructorContext, constructorDescriptor, OwnerKind.IMPLEMENTATION, DefaultParameterValueLoader.DEFAULT, null); - new DefaultParameterValueSubstitutor(state).generatePrimaryConstructorOverloadsIfNeeded(constructorDescriptor, v, kind, myClass); + new DefaultParameterValueSubstitutor(state).generatePrimaryConstructorOverloadsIfNeeded(constructorDescriptor, v, this, kind, myClass); } private void generateSecondaryConstructor(@NotNull final ConstructorDescriptor constructorDescriptor) { @@ -964,7 +964,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { DefaultParameterValueLoader.DEFAULT, null); new DefaultParameterValueSubstitutor(state).generateOverloadsIfNeeded( - constructor, constructorDescriptor, constructorDescriptor, kind, v + constructor, constructorDescriptor, constructorDescriptor, kind, v, this ); } @@ -1545,7 +1545,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { int isDeprecated = KotlinBuiltIns.isDeprecated(descriptor) ? ACC_DEPRECATED : 0; FieldVisitor fv = v.newField(JvmDeclarationOriginKt.OtherOrigin(enumEntry, descriptor), ACC_PUBLIC | ACC_ENUM | ACC_STATIC | ACC_FINAL | isDeprecated, descriptor.getName().asString(), classAsmType.getDescriptor(), null, null); - AnnotationCodegen.forField(fv, typeMapper).genAnnotations(descriptor, null); + AnnotationCodegen.forField(fv, this, typeMapper).genAnnotations(descriptor, null); } initializeEnumConstants(enumEntries); diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/MemberCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/MemberCodegen.java index 7c7f2eb24b0..1026735e729 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/MemberCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/MemberCodegen.java @@ -88,7 +88,7 @@ public abstract class MemberCodegen parentCodegen; private final ReifiedTypeParametersUsages reifiedTypeParametersUsages = new ReifiedTypeParametersUsages(); - protected final Collection innerClasses = new LinkedHashSet(); + private final Collection innerClasses = new LinkedHashSet(); protected ExpressionCodegen clInit; private NameGenerator inlineNameGenerator; @@ -273,6 +273,18 @@ public abstract class MemberCodegen { } } Annotated annotatedFile = new AnnotatedSimple(new AnnotationsImpl(fileAnnotationDescriptors)); - AnnotationCodegen.forClass(v.getVisitor(), state.getTypeMapper()).genAnnotations(annotatedFile, null); + AnnotationCodegen.forClass(v.getVisitor(), this, state.getTypeMapper()).genAnnotations(annotatedFile, null); } @Override diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/PropertyCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/PropertyCodegen.java index b8204f63196..46bf31d4e6e 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/PropertyCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/PropertyCodegen.java @@ -233,7 +233,7 @@ public class PropertyCodegen { assert state.getClassBuilderMode() != ClassBuilderMode.FULL || constant != null : "Default value for annotation parameter should be compile time value: " + defaultValue.getText(); if (constant != null) { - AnnotationCodegen annotationCodegen = AnnotationCodegen.forAnnotationDefaultValue(mv, typeMapper); + AnnotationCodegen annotationCodegen = AnnotationCodegen.forAnnotationDefaultValue(mv, memberCodegen, typeMapper); annotationCodegen.generateAnnotationDefaultValue(constant, descriptor.getType()); } } @@ -279,7 +279,7 @@ public class PropertyCodegen { Method syntheticMethod = getSyntheticMethodSignature(descriptor); MethodVisitor mv = v.newMethod(JvmDeclarationOriginKt.OtherOrigin(descriptor), flags, syntheticMethod.getName(), syntheticMethod.getDescriptor(), null, null); - AnnotationCodegen.forMethod(mv, typeMapper) + AnnotationCodegen.forMethod(mv, memberCodegen, typeMapper) .genAnnotations(new AnnotatedSimple(annotations), Type.VOID_TYPE, AnnotationUseSiteTarget.PROPERTY); mv.visitCode(); mv.visitInsn(Opcodes.RETURN); @@ -354,7 +354,7 @@ public class PropertyCodegen { ); Annotated fieldAnnotated = new AnnotatedWithFakeAnnotations(propertyDescriptor, annotations); - AnnotationCodegen.forField(fv, typeMapper).genAnnotations( + AnnotationCodegen.forField(fv, memberCodegen, typeMapper).genAnnotations( fieldAnnotated, type, isDelegate ? AnnotationUseSiteTarget.PROPERTY_DELEGATE_FIELD : AnnotationUseSiteTarget.FIELD); }