diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ClassCodegen.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ClassCodegen.kt index a8be923ec2a..467c33ce554 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ClassCodegen.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ClassCodegen.kt @@ -24,7 +24,10 @@ import org.jetbrains.kotlin.codegen.inline.DefaultSourceMapper import org.jetbrains.kotlin.codegen.inline.SourceMapper import org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings import org.jetbrains.kotlin.codegen.serialization.JvmSerializerExtension -import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.descriptors.ClassDescriptor +import org.jetbrains.kotlin.descriptors.DeclarationDescriptor +import org.jetbrains.kotlin.descriptors.Modality +import org.jetbrains.kotlin.descriptors.Visibility import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.load.java.JvmAbi @@ -155,6 +158,7 @@ open class ClassCodegen protected constructor( private fun done() { writeInnerClasses() + writeOuterClassAndEnclosingMethod() sourceMapper?.let { SourceMapper.flushToClassBuilder(it, visitor) @@ -300,6 +304,27 @@ open class ClassCodegen protected constructor( } } + private fun writeOuterClassAndEnclosingMethod() { + // JVMS7 (4.7.7): A class must have an EnclosingMethod attribute if and only if + // it is a local class or an anonymous class. + // + // The attribute contains the innermost class that encloses the declaration of + // the current class. If the current class is immediately enclosed by a method + // or constructor, the name and type of the function is recorded as well. + if (parentClassCodegen != null) { + val outerClassName = parentClassCodegen.type.internalName + // TODO: Since the class could have been reparented in lowerings, this could + // be a class instead of the actual function that the class is nested inside + // in the source. + val containingDeclaration = irClass.symbol.owner.parent + if (containingDeclaration is IrFunction) { + val method = typeMapper.mapAsmMethod(containingDeclaration.descriptor) + visitor.visitOuterClass(outerClassName, method.name, method.descriptor) + } else { + visitor.visitOuterClass(outerClassName, null, null) + } + } + } fun getOrCreateSourceMapper(): DefaultSourceMapper { if (sourceMapper == null) { @@ -307,7 +332,6 @@ open class ClassCodegen protected constructor( } return sourceMapper!! } - } private val IrClass.flags: Int diff --git a/compiler/testData/codegen/box/polymorphicSignature/varargOfObjects_before.kt b/compiler/testData/codegen/box/polymorphicSignature/varargOfObjects_before.kt index 8b173a2259e..114b3833178 100644 --- a/compiler/testData/codegen/box/polymorphicSignature/varargOfObjects_before.kt +++ b/compiler/testData/codegen/box/polymorphicSignature/varargOfObjects_before.kt @@ -1,5 +1,4 @@ // TARGET_BACKEND: JVM -// IGNORE_BACKEND: JVM_IR // FULL_JDK // SKIP_JDK6 // WITH_RUNTIME diff --git a/compiler/testData/codegen/box/reflection/enclosing/functionExpressionInProperty.kt b/compiler/testData/codegen/box/reflection/enclosing/functionExpressionInProperty.kt index 3f026091fb1..9d8f92903af 100644 --- a/compiler/testData/codegen/box/reflection/enclosing/functionExpressionInProperty.kt +++ b/compiler/testData/codegen/box/reflection/enclosing/functionExpressionInProperty.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // TARGET_BACKEND: JVM // WITH_REFLECT diff --git a/compiler/testData/codegen/box/reflection/enclosing/lambdaInClassObject.kt b/compiler/testData/codegen/box/reflection/enclosing/lambdaInClassObject.kt index 163d1eeda4d..fb95e90b88b 100644 --- a/compiler/testData/codegen/box/reflection/enclosing/lambdaInClassObject.kt +++ b/compiler/testData/codegen/box/reflection/enclosing/lambdaInClassObject.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // TARGET_BACKEND: JVM // WITH_REFLECT diff --git a/compiler/testData/codegen/box/reflection/enclosing/lambdaInConstructor.kt b/compiler/testData/codegen/box/reflection/enclosing/lambdaInConstructor.kt index 7e7bf3a2240..e952222a76a 100644 --- a/compiler/testData/codegen/box/reflection/enclosing/lambdaInConstructor.kt +++ b/compiler/testData/codegen/box/reflection/enclosing/lambdaInConstructor.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // TARGET_BACKEND: JVM // WITH_REFLECT diff --git a/compiler/testData/codegen/box/reflection/enclosing/lambdaInFunction.kt b/compiler/testData/codegen/box/reflection/enclosing/lambdaInFunction.kt index a1cb398fb5e..8cf63fb13fe 100644 --- a/compiler/testData/codegen/box/reflection/enclosing/lambdaInFunction.kt +++ b/compiler/testData/codegen/box/reflection/enclosing/lambdaInFunction.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // TARGET_BACKEND: JVM // WITH_REFLECT diff --git a/compiler/testData/codegen/box/reflection/enclosing/lambdaInLocalClassConstructor.kt b/compiler/testData/codegen/box/reflection/enclosing/lambdaInLocalClassConstructor.kt index c68160b088e..4565581ec9c 100644 --- a/compiler/testData/codegen/box/reflection/enclosing/lambdaInLocalClassConstructor.kt +++ b/compiler/testData/codegen/box/reflection/enclosing/lambdaInLocalClassConstructor.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // TARGET_BACKEND: JVM // WITH_REFLECT diff --git a/compiler/testData/codegen/box/reflection/enclosing/lambdaInLocalClassSuperCall.kt b/compiler/testData/codegen/box/reflection/enclosing/lambdaInLocalClassSuperCall.kt index 5d64b48e123..42fa223bf7a 100644 --- a/compiler/testData/codegen/box/reflection/enclosing/lambdaInLocalClassSuperCall.kt +++ b/compiler/testData/codegen/box/reflection/enclosing/lambdaInLocalClassSuperCall.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // TARGET_BACKEND: JVM // WITH_REFLECT diff --git a/compiler/testData/codegen/box/reflection/enclosing/lambdaInMemberFunction.kt b/compiler/testData/codegen/box/reflection/enclosing/lambdaInMemberFunction.kt index bcbc8d4feda..78281274643 100644 --- a/compiler/testData/codegen/box/reflection/enclosing/lambdaInMemberFunction.kt +++ b/compiler/testData/codegen/box/reflection/enclosing/lambdaInMemberFunction.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // TARGET_BACKEND: JVM // WITH_REFLECT diff --git a/compiler/testData/codegen/box/reflection/enclosing/lambdaInMemberFunctionInLocalClass.kt b/compiler/testData/codegen/box/reflection/enclosing/lambdaInMemberFunctionInLocalClass.kt index d9f2e11ea17..b323b6c4bca 100644 --- a/compiler/testData/codegen/box/reflection/enclosing/lambdaInMemberFunctionInLocalClass.kt +++ b/compiler/testData/codegen/box/reflection/enclosing/lambdaInMemberFunctionInLocalClass.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // TARGET_BACKEND: JVM // WITH_REFLECT diff --git a/compiler/testData/codegen/box/reflection/enclosing/lambdaInMemberFunctionInNestedClass.kt b/compiler/testData/codegen/box/reflection/enclosing/lambdaInMemberFunctionInNestedClass.kt index 7ea5be31c3e..9f41d496659 100644 --- a/compiler/testData/codegen/box/reflection/enclosing/lambdaInMemberFunctionInNestedClass.kt +++ b/compiler/testData/codegen/box/reflection/enclosing/lambdaInMemberFunctionInNestedClass.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // TARGET_BACKEND: JVM // WITH_REFLECT diff --git a/compiler/testData/codegen/box/reflection/enclosing/lambdaInObjectDeclaration.kt b/compiler/testData/codegen/box/reflection/enclosing/lambdaInObjectDeclaration.kt index 7bf77c6b04b..0e3f71c0fb6 100644 --- a/compiler/testData/codegen/box/reflection/enclosing/lambdaInObjectDeclaration.kt +++ b/compiler/testData/codegen/box/reflection/enclosing/lambdaInObjectDeclaration.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // TARGET_BACKEND: JVM // WITH_REFLECT diff --git a/compiler/testData/codegen/box/reflection/enclosing/lambdaInObjectExpression.kt b/compiler/testData/codegen/box/reflection/enclosing/lambdaInObjectExpression.kt index 43443fa1d2e..314ea979d6b 100644 --- a/compiler/testData/codegen/box/reflection/enclosing/lambdaInObjectExpression.kt +++ b/compiler/testData/codegen/box/reflection/enclosing/lambdaInObjectExpression.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // TARGET_BACKEND: JVM // WITH_REFLECT diff --git a/compiler/testData/codegen/box/reflection/enclosing/lambdaInPackage.kt b/compiler/testData/codegen/box/reflection/enclosing/lambdaInPackage.kt index 083512abb1c..8f9b44166c0 100644 --- a/compiler/testData/codegen/box/reflection/enclosing/lambdaInPackage.kt +++ b/compiler/testData/codegen/box/reflection/enclosing/lambdaInPackage.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // TARGET_BACKEND: JVM // WITH_REFLECT diff --git a/compiler/testData/codegen/box/reflection/enclosing/lambdaInPropertyGetter.kt b/compiler/testData/codegen/box/reflection/enclosing/lambdaInPropertyGetter.kt index 8aeea6593ec..0a65f28a4ba 100644 --- a/compiler/testData/codegen/box/reflection/enclosing/lambdaInPropertyGetter.kt +++ b/compiler/testData/codegen/box/reflection/enclosing/lambdaInPropertyGetter.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // TARGET_BACKEND: JVM // WITH_REFLECT diff --git a/compiler/testData/codegen/box/reflection/enclosing/lambdaInPropertySetter.kt b/compiler/testData/codegen/box/reflection/enclosing/lambdaInPropertySetter.kt index 2b9a391ec94..575de45e021 100644 --- a/compiler/testData/codegen/box/reflection/enclosing/lambdaInPropertySetter.kt +++ b/compiler/testData/codegen/box/reflection/enclosing/lambdaInPropertySetter.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // TARGET_BACKEND: JVM // WITH_REFLECT diff --git a/compiler/testData/codegen/box/reflection/enclosing/localClassInTopLevelFunction.kt b/compiler/testData/codegen/box/reflection/enclosing/localClassInTopLevelFunction.kt index 5822be741fa..4356824e685 100644 --- a/compiler/testData/codegen/box/reflection/enclosing/localClassInTopLevelFunction.kt +++ b/compiler/testData/codegen/box/reflection/enclosing/localClassInTopLevelFunction.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // TARGET_BACKEND: JVM // WITH_REFLECT diff --git a/compiler/testData/codegen/box/reflection/mapping/extensionProperty.kt b/compiler/testData/codegen/box/reflection/mapping/extensionProperty.kt index 56b397a2b45..a27df99d6f8 100644 --- a/compiler/testData/codegen/box/reflection/mapping/extensionProperty.kt +++ b/compiler/testData/codegen/box/reflection/mapping/extensionProperty.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // TARGET_BACKEND: JVM // WITH_REFLECT diff --git a/compiler/testData/codegen/box/reflection/mapping/topLevelProperty.kt b/compiler/testData/codegen/box/reflection/mapping/topLevelProperty.kt index a06fbc8e7c8..8ec14eeb37a 100644 --- a/compiler/testData/codegen/box/reflection/mapping/topLevelProperty.kt +++ b/compiler/testData/codegen/box/reflection/mapping/topLevelProperty.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // TARGET_BACKEND: JVM // WITH_REFLECT