diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmLower.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmLower.kt index 33dddb9c8dd..5b5d55c83c8 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmLower.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmLower.kt @@ -105,7 +105,7 @@ val jvmPhases = namedIrFilePhase( lateinitPhase then - moveCompanionObjectFieldsPhase then + moveOrCopyCompanionObjectFieldsPhase then propertyReferencePhase then constPhase then propertiesToFieldsPhase then diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/MoveCompanionObjectFieldsLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/MoveCompanionObjectFieldsLowering.kt index 1cad499d940..61bddb13f55 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/MoveCompanionObjectFieldsLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/MoveCompanionObjectFieldsLowering.kt @@ -11,6 +11,7 @@ import org.jetbrains.kotlin.backend.common.descriptors.WrappedFieldDescriptor import org.jetbrains.kotlin.backend.common.descriptors.WrappedVariableDescriptor import org.jetbrains.kotlin.backend.common.lower.replaceThisByStaticReference import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase +import org.jetbrains.kotlin.backend.jvm.codegen.isJvmInterface import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrStatement @@ -31,19 +32,21 @@ import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid import org.jetbrains.kotlin.load.java.JvmAbi.JVM_FIELD_ANNOTATION_FQ_NAME -internal val moveCompanionObjectFieldsPhase = makeIrFilePhase( - ::MoveCompanionObjectFieldsLowering, - name = "MoveCompanionObjectFields", - description = "Move companion object fields to static fields of companion's owner" +internal val moveOrCopyCompanionObjectFieldsPhase = makeIrFilePhase( + ::MoveOrCopyCompanionObjectFieldsLowering, + name = "MoveOrCopyCompanionObjectFields", + description = "Move and/or copy companion object fields to static fields of companion's owner" ) -private class MoveCompanionObjectFieldsLowering(val context: CommonBackendContext) : ClassLoweringPass { +private class MoveOrCopyCompanionObjectFieldsLowering(val context: CommonBackendContext) : ClassLoweringPass { override fun lower(irClass: IrClass) { val fieldReplacementMap = mutableMapOf() if (irClass.isObject && !irClass.isCompanion && irClass.visibility != Visibilities.LOCAL) { handleObject(irClass, fieldReplacementMap) } else { handleClass(irClass, fieldReplacementMap) + if (irClass.isJvmInterface) + copyConsts(irClass) } irClass.replaceFieldReferences(fieldReplacementMap) } @@ -83,28 +86,52 @@ private class MoveCompanionObjectFieldsLowering(val context: CommonBackendContex companion.declarations.removeAll { it is IrAnonymousInitializer } } + private fun copyConsts(irClass: IrClass) { + val companion = irClass.declarations.find { + it is IrClass && it.isCompanion + } as IrClass? ?: return + companion.declarations.filter { it is IrProperty && it.isConst }.mapNotNullTo(irClass.declarations) { + copyPropertyFieldToStaticParent(it as IrProperty, companion, irClass) + } + } + private fun IrClass.allFieldsAreJvmField() = declarations.filterIsInstance() .mapNotNull { it.backingField }.all { it.hasAnnotation(JVM_FIELD_ANNOTATION_FQ_NAME) } - private fun movePropertyFieldToStaticParent( + // If fieldReplacementMap is null / unspecified, keep the old field and don't update the references. + private fun moveOrCopyPropertyFieldToStaticParent( irProperty: IrProperty, propertyParent: IrClass, fieldParent: IrClass, - fieldReplacementMap: MutableMap + fieldReplacementMap: MutableMap? = null ): IrField? { if (irProperty.origin == IrDeclarationOrigin.FAKE_OVERRIDE) return null val oldField = irProperty.backingField ?: return null val newField = createStaticBackingField(oldField, propertyParent, fieldParent) - irProperty.backingField = newField - newField.correspondingPropertySymbol = irProperty.symbol - - fieldReplacementMap[oldField.symbol] = newField.symbol + fieldReplacementMap?.run { + irProperty.backingField = newField + newField.correspondingPropertySymbol = irProperty.symbol + put(oldField.symbol, newField.symbol) + } return newField } + private fun movePropertyFieldToStaticParent( + irProperty: IrProperty, + propertyParent: IrClass, + fieldParent: IrClass, + fieldReplacementMap: MutableMap? = null + ): IrField? = moveOrCopyPropertyFieldToStaticParent(irProperty, propertyParent, fieldParent, fieldReplacementMap) + + private fun copyPropertyFieldToStaticParent( + irProperty: IrProperty, + propertyParent: IrClass, + fieldParent: IrClass + ): IrField? = moveOrCopyPropertyFieldToStaticParent(irProperty, propertyParent, fieldParent) + private fun moveAnonymousInitializerToStaticParent( oldInitializer: IrAnonymousInitializer, oldParent: IrClass, diff --git a/compiler/testData/codegen/box/annotations/annotationWithKotlinPropertyFromInterfaceCompanion.kt b/compiler/testData/codegen/box/annotations/annotationWithKotlinPropertyFromInterfaceCompanion.kt index 75d4cd33608..16d33100022 100644 --- a/compiler/testData/codegen/box/annotations/annotationWithKotlinPropertyFromInterfaceCompanion.kt +++ b/compiler/testData/codegen/box/annotations/annotationWithKotlinPropertyFromInterfaceCompanion.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // TARGET_BACKEND: JVM // FILE: JavaClass.java diff --git a/compiler/testData/codegen/box/annotations/constValInAnnotation.kt b/compiler/testData/codegen/box/annotations/constValInAnnotation.kt index d9c06f6d4e0..af1eb239a42 100644 --- a/compiler/testData/codegen/box/annotations/constValInAnnotation.kt +++ b/compiler/testData/codegen/box/annotations/constValInAnnotation.kt @@ -1,5 +1,4 @@ // !LANGUAGE: +NestedClassesInAnnotations -// IGNORE_BACKEND: JVM_IR // WITH_RUNTIME // TARGET_BACKEND: JVM // FILE: Foo.java diff --git a/compiler/testData/codegen/box/classes/interfaceCompanionInitializationWithJava.kt b/compiler/testData/codegen/box/classes/interfaceCompanionInitializationWithJava.kt index d196df377e0..0db5f2d4372 100644 --- a/compiler/testData/codegen/box/classes/interfaceCompanionInitializationWithJava.kt +++ b/compiler/testData/codegen/box/classes/interfaceCompanionInitializationWithJava.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // TARGET_BACKEND: JVM // WITH_RUNTIME // FILE: CompanionInitialization.java diff --git a/compiler/testData/codegen/box/properties/companionObjectPropertiesFromJava.kt b/compiler/testData/codegen/box/properties/companionObjectPropertiesFromJava.kt index a5420ca4e74..db37345cc34 100644 --- a/compiler/testData/codegen/box/properties/companionObjectPropertiesFromJava.kt +++ b/compiler/testData/codegen/box/properties/companionObjectPropertiesFromJava.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // TARGET_BACKEND: JVM // WITH_RUNTIME diff --git a/compiler/testData/codegen/box/properties/const/interfaceCompanion.kt b/compiler/testData/codegen/box/properties/const/interfaceCompanion.kt index 2e67ad30ad1..f3d3c2b35be 100644 --- a/compiler/testData/codegen/box/properties/const/interfaceCompanion.kt +++ b/compiler/testData/codegen/box/properties/const/interfaceCompanion.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // TARGET_BACKEND: JVM // WITH_RUNTIME diff --git a/compiler/testData/compileJavaAgainstKotlin/staticFields/AnnotationTrait.kt b/compiler/testData/compileJavaAgainstKotlin/staticFields/AnnotationTrait.kt index 7ab4a2ffb77..a0791b008f4 100644 --- a/compiler/testData/compileJavaAgainstKotlin/staticFields/AnnotationTrait.kt +++ b/compiler/testData/compileJavaAgainstKotlin/staticFields/AnnotationTrait.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR package test annotation class AString(val value: String) diff --git a/compiler/testData/compileJavaAgainstKotlin/staticFields/staticTraitProperty.kt b/compiler/testData/compileJavaAgainstKotlin/staticFields/staticTraitProperty.kt index b106a8e5761..870d34e4b2c 100644 --- a/compiler/testData/compileJavaAgainstKotlin/staticFields/staticTraitProperty.kt +++ b/compiler/testData/compileJavaAgainstKotlin/staticFields/staticTraitProperty.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR package test interface Test {