JVM_IR: refactor MoveCompanionObjectFieldsLowering

* Extract replacement of IrGetField/IrSetField into a separate
   file-level lowering (should reduce the amount of work to linear in
   the number of classes rather than potentially quadratic)

 * Extract static backing field construction into JvmDeclarationFactory
   and move that lowering after PropertiesToFields lowering to reduce
   code duplication
This commit is contained in:
pyos
2019-11-19 11:52:38 +01:00
committed by Alexander Udalov
parent afd59f0d46
commit d221c1f242
13 changed files with 181 additions and 171 deletions
@@ -225,6 +225,7 @@ private val jvmFilePhases =
propertyReferencePhase then propertyReferencePhase then
constPhase then constPhase then
propertiesToFieldsPhase then propertiesToFieldsPhase then
remapObjectFieldAccesses then
propertiesPhase then propertiesPhase then
renameFieldsPhase then renameFieldsPhase then
anonymousObjectSuperConstructorPhase then anonymousObjectSuperConstructorPhase then
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.backend.common.ir.*
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
import org.jetbrains.kotlin.backend.jvm.codegen.MethodSignatureMapper import org.jetbrains.kotlin.backend.jvm.codegen.MethodSignatureMapper
import org.jetbrains.kotlin.backend.jvm.codegen.isJvmInterface import org.jetbrains.kotlin.backend.jvm.codegen.isJvmInterface
import org.jetbrains.kotlin.backend.jvm.ir.replaceThisByStaticReference
import org.jetbrains.kotlin.builtins.CompanionObjectMapping.isMappedIntrinsicCompanionObject import org.jetbrains.kotlin.builtins.CompanionObjectMapping.isMappedIntrinsicCompanionObject
import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Modality
@@ -22,6 +23,7 @@ import org.jetbrains.kotlin.ir.declarations.impl.*
import org.jetbrains.kotlin.ir.descriptors.WrappedClassConstructorDescriptor import org.jetbrains.kotlin.ir.descriptors.WrappedClassConstructorDescriptor
import org.jetbrains.kotlin.ir.descriptors.WrappedClassDescriptor import org.jetbrains.kotlin.ir.descriptors.WrappedClassDescriptor
import org.jetbrains.kotlin.ir.descriptors.WrappedValueParameterDescriptor import org.jetbrains.kotlin.ir.descriptors.WrappedValueParameterDescriptor
import org.jetbrains.kotlin.ir.expressions.IrExpressionBody
import org.jetbrains.kotlin.ir.symbols.impl.* import org.jetbrains.kotlin.ir.symbols.impl.*
import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.util.*
@@ -37,6 +39,7 @@ class JvmDeclarationFactory(
private val interfaceCompanionFieldDeclarations = HashMap<IrSymbolOwner, IrField>() private val interfaceCompanionFieldDeclarations = HashMap<IrSymbolOwner, IrField>()
private val outerThisDeclarations = HashMap<IrClass, IrField>() private val outerThisDeclarations = HashMap<IrClass, IrField>()
private val innerClassConstructors = HashMap<IrConstructor, IrConstructor>() private val innerClassConstructors = HashMap<IrConstructor, IrConstructor>()
private val staticBackingFields = HashMap<IrProperty, IrField>()
private val defaultImplsMethods = HashMap<IrSimpleFunction, IrSimpleFunction>() private val defaultImplsMethods = HashMap<IrSimpleFunction, IrSimpleFunction>()
private val defaultImplsClasses = HashMap<IrClass, IrClass>() private val defaultImplsClasses = HashMap<IrClass, IrClass>()
@@ -152,6 +155,36 @@ class JvmDeclarationFactory(
else else
getFieldForObjectInstance(singleton) getFieldForObjectInstance(singleton)
fun getStaticBackingField(irProperty: IrProperty): IrField? {
// Only fields defined directly in objects should be made static.
// Fake overrides never point to those, as objects are final.
if (irProperty.origin == IrDeclarationOrigin.FAKE_OVERRIDE) return null
val oldField = irProperty.backingField ?: return null
val oldParent = irProperty.parent as? IrClass ?: return null
if (!oldParent.isObject) return null
return staticBackingFields.getOrPut(irProperty) {
buildField {
updateFrom(oldField)
name = oldField.name
isStatic = true
}.apply {
// We don't move fields to interfaces unless all fields are annotated with @JvmField.
// It is an error to annotate only some of the fields of an interface companion with
// @JvmField, so checking the current field only should be enough.
val hasJvmField = oldField.hasAnnotation(JvmAbi.JVM_FIELD_ANNOTATION_FQ_NAME)
parent = if (oldParent.isCompanion && (!oldParent.parentAsClass.isJvmInterface || hasJvmField))
oldParent.parentAsClass
else
oldParent
annotations += oldField.annotations
initializer = oldField.initializer
?.replaceThisByStaticReference(this@JvmDeclarationFactory, oldParent, oldParent.thisReceiver!!)
?.deepCopyWithSymbols(this) as IrExpressionBody?
(this as IrFieldImpl).metadata = oldField.metadata
}
}
}
fun getDefaultImplsFunction(interfaceFun: IrSimpleFunction): IrSimpleFunction { fun getDefaultImplsFunction(interfaceFun: IrSimpleFunction): IrSimpleFunction {
val parent = interfaceFun.parentAsClass val parent = interfaceFun.parentAsClass
assert(parent.isJvmInterface) { "Parent of ${interfaceFun.dump()} should be interface" } assert(parent.isJvmInterface) { "Parent of ${interfaceFun.dump()} should be interface" }
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.backend.common.lower.IrLoweringContext
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.JvmSymbols import org.jetbrains.kotlin.backend.jvm.JvmSymbols
import org.jetbrains.kotlin.backend.jvm.codegen.isJvmInterface import org.jetbrains.kotlin.backend.jvm.codegen.isJvmInterface
import org.jetbrains.kotlin.backend.jvm.descriptors.JvmDeclarationFactory
import org.jetbrains.kotlin.backend.jvm.lower.inlineclasses.hasMangledParameters import org.jetbrains.kotlin.backend.jvm.lower.inlineclasses.hasMangledParameters
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.descriptors.Visibilities
@@ -152,14 +153,14 @@ fun IrExpression.isSmartcastFromHigherThanNullable(context: JvmBackendContext) =
!this.argument.type.isSubtypeOf(type.makeNullable(), context.irBuiltIns) !this.argument.type.isSubtypeOf(type.makeNullable(), context.irBuiltIns)
fun IrBody.replaceThisByStaticReference( fun IrBody.replaceThisByStaticReference(
context: JvmBackendContext, declarationFactory: JvmDeclarationFactory,
irClass: IrClass, irClass: IrClass,
oldThisReceiverParameter: IrValueParameter oldThisReceiverParameter: IrValueParameter
): IrBody = ): IrBody =
transform(object : IrElementTransformerVoid() { transform(object : IrElementTransformerVoid() {
override fun visitGetValue(expression: IrGetValue): IrExpression { override fun visitGetValue(expression: IrGetValue): IrExpression {
if (expression.symbol == oldThisReceiverParameter.symbol) { if (expression.symbol == oldThisReceiverParameter.symbol) {
val instanceField = context.declarationFactory.getPrivateFieldForObjectInstance(irClass) val instanceField = declarationFactory.getPrivateFieldForObjectInstance(irClass)
return IrGetFieldImpl( return IrGetFieldImpl(
expression.startOffset, expression.startOffset,
expression.endOffset, expression.endOffset,
@@ -181,7 +181,7 @@ private class SingletonObjectJvmStaticLowering(
} }
fun modifyBody(irFunction: IrFunction, irClass: IrClass, oldDispatchReceiverParameter: IrValueParameter) { fun modifyBody(irFunction: IrFunction, irClass: IrClass, oldDispatchReceiverParameter: IrValueParameter) {
irFunction.body = irFunction.body?.replaceThisByStaticReference(context, irClass, oldDispatchReceiverParameter) irFunction.body = irFunction.body?.replaceThisByStaticReference(context.declarationFactory, irClass, oldDispatchReceiverParameter)
} }
} }
@@ -6,34 +6,20 @@
package org.jetbrains.kotlin.backend.jvm.lower package org.jetbrains.kotlin.backend.jvm.lower
import org.jetbrains.kotlin.backend.common.ClassLoweringPass import org.jetbrains.kotlin.backend.common.ClassLoweringPass
import org.jetbrains.kotlin.backend.common.FileLoweringPass
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.codegen.isJvmInterface
import org.jetbrains.kotlin.backend.jvm.ir.replaceThisByStaticReference import org.jetbrains.kotlin.backend.jvm.ir.replaceThisByStaticReference
import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.builders.declarations.addField
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.IrAnonymousInitializerImpl import org.jetbrains.kotlin.ir.declarations.impl.IrAnonymousInitializerImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrFieldImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrVariableImpl
import org.jetbrains.kotlin.ir.descriptors.WrappedFieldDescriptor
import org.jetbrains.kotlin.ir.descriptors.WrappedVariableDescriptor
import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.IrGetFieldImpl import org.jetbrains.kotlin.ir.expressions.impl.IrGetFieldImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrSetFieldImpl import org.jetbrains.kotlin.ir.expressions.impl.IrSetFieldImpl
import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol
import org.jetbrains.kotlin.ir.symbols.impl.IrAnonymousInitializerSymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.IrAnonymousInitializerSymbolImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrFieldSymbolImpl import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.ir.symbols.impl.IrVariableSymbolImpl
import org.jetbrains.kotlin.ir.util.deepCopyWithSymbols
import org.jetbrains.kotlin.ir.util.hasAnnotation
import org.jetbrains.kotlin.ir.util.isObject
import org.jetbrains.kotlin.ir.util.patchDeclarationParents
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid 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 moveOrCopyCompanionObjectFieldsPhase = makeIrFilePhase( internal val moveOrCopyCompanionObjectFieldsPhase = makeIrFilePhase(
::MoveOrCopyCompanionObjectFieldsLowering, ::MoveOrCopyCompanionObjectFieldsLowering,
@@ -41,186 +27,110 @@ internal val moveOrCopyCompanionObjectFieldsPhase = makeIrFilePhase(
description = "Move and/or copy companion object fields to static fields of companion's owner" description = "Move and/or copy companion object fields to static fields of companion's owner"
) )
internal val remapObjectFieldAccesses = makeIrFilePhase(
::RemapObjectFieldAccesses,
name = "RemapObjectFieldAccesses",
description = "Make IrGetField/IrSetField to objects' fields point to the static versions",
prerequisite = setOf(propertiesToFieldsPhase)
)
private class MoveOrCopyCompanionObjectFieldsLowering(val context: JvmBackendContext) : ClassLoweringPass { private class MoveOrCopyCompanionObjectFieldsLowering(val context: JvmBackendContext) : ClassLoweringPass {
override fun lower(irClass: IrClass) { override fun lower(irClass: IrClass) {
val fieldReplacementMap = mutableMapOf<IrFieldSymbol, IrFieldSymbol>() if (irClass.isObject && !irClass.isCompanion) {
if (irClass.isObject && !irClass.isCompanion && irClass.visibility != Visibilities.LOCAL) { irClass.handle()
handleObject(irClass, fieldReplacementMap)
} else { } else {
handleClass(irClass, fieldReplacementMap) (irClass.declarations.singleOrNull { it is IrClass && it.isCompanion } as IrClass?)?.handle()
if (irClass.isJvmInterface)
copyConsts(irClass)
} }
irClass.replaceFieldReferences(fieldReplacementMap)
} }
private fun handleObject(irObject: IrClass, fieldReplacementMap: MutableMap<IrFieldSymbol, IrFieldSymbol>) { private fun IrClass.handle() {
irObject.declarations.replaceAll { val newDeclarations = declarations.map {
when (it) { when (it) {
is IrProperty -> { is IrProperty -> context.declarationFactory.getStaticBackingField(it)?.also { newField ->
// The field is not actually moved, just replaced by a static field it.backingField = newField
movePropertyFieldToStaticParent(it, irObject, irObject, fieldReplacementMap) newField.correspondingPropertySymbol = it.symbol
it
} }
is IrAnonymousInitializer -> moveAnonymousInitializerToStaticParent(it, irObject, irObject) else -> null
else -> it
}
}
}
private fun handleClass(irClass: IrClass, fieldReplacementMap: MutableMap<IrFieldSymbol, IrFieldSymbol>) {
val companion = irClass.declarations.find {
it is IrClass && it.isCompanion
} as IrClass? ?: return
// We don't move fields to interfaces unless all fields are annotated with @JvmField.
// It is an error to annotate only some of the fields of an interface companion with @JvmField.
val newParent = if (irClass.isJvmInterface && !companion.allFieldsAreJvmField()) companion else irClass
val newDeclarations = companion.declarations.map {
when (it) {
is IrProperty ->
movePropertyFieldToStaticParent(it, companion, newParent, fieldReplacementMap)
is IrAnonymousInitializer ->
moveAnonymousInitializerToStaticParent(it, companion, newParent)
else ->
null
} }
} }
if (newParent === companion) { val companionParent = if (isCompanion) parentAsClass else null
// Keep fields as children of `IrProperty`, but replace anonymous initializers with static ones, // In case a companion contains no fields, move the anonymous initializers to the parent
// preserving the relative ordering of anonymous initializers and property initializers. // anyway, as otherwise there will probably be no references to the companion class at all
for ((i, declaration) in newDeclarations.withIndex()) // and therefore its class initializer will never be invoked.
if (declaration is IrAnonymousInitializer) val newParent = newDeclarations.firstOrNull { it != null }?.parentAsClass ?: companionParent ?: this
companion.declarations[i] = declaration if (newParent === this) {
declarations.replaceAll {
// Anonymous initializers must be made static to correctly initialize the new static
// fields when the class is loaded.
if (it is IrAnonymousInitializer) makeAnonymousInitializerStatic(it, newParent) else it
}
if (companionParent != null) {
for (declaration in declarations) {
if (declaration is IrProperty && declaration.isConst && declaration.hasPublicVisibility) {
copyConstField(declaration.backingField!!, companionParent)
}
}
}
} else { } else {
// Move all touched declarations to the parent. // Anonymous initializers must also be moved and their ordering relative to the fields
companion.declarations.removeAll { it is IrAnonymousInitializer } // must be preserved, as the fields can have expression initializers themselves.
newDeclarations.filterNotNullTo(newParent.declarations) for ((i, newField) in newDeclarations.withIndex()) {
if (newField != null)
newParent.declarations += newField
if (declarations[i] is IrAnonymousInitializer)
newParent.declarations += makeAnonymousInitializerStatic(declarations[i] as IrAnonymousInitializer, newParent)
}
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 && it.hasPublicVisibility }
.mapNotNullTo(irClass.declarations) { copyPropertyFieldToStaticParent(it as IrProperty, companion, irClass) }
}
private val IrProperty.hasPublicVisibility: Boolean private val IrProperty.hasPublicVisibility: Boolean
get() = !Visibilities.isPrivate(visibility) && visibility != Visibilities.PROTECTED get() = !Visibilities.isPrivate(visibility) && visibility != Visibilities.PROTECTED
private fun IrClass.allFieldsAreJvmField() = private fun makeAnonymousInitializerStatic(oldInitializer: IrAnonymousInitializer, newParent: IrClass) =
declarations.filterIsInstance<IrProperty>()
.mapNotNull { it.backingField }.all { it.hasAnnotation(JVM_FIELD_ANNOTATION_FQ_NAME) }
// 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<IrFieldSymbol, IrFieldSymbol>? = null
): IrField? {
if (irProperty.origin == IrDeclarationOrigin.FAKE_OVERRIDE) return null
val oldField = irProperty.backingField ?: return null
val newField = createStaticBackingField(oldField, propertyParent, fieldParent)
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<IrFieldSymbol, IrFieldSymbol>? = 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,
newParent: IrClass
): IrAnonymousInitializer =
with(oldInitializer) { with(oldInitializer) {
IrAnonymousInitializerImpl( val oldParent = parentAsClass
startOffset, endOffset, origin, IrAnonymousInitializerSymbolImpl(newParent.symbol), val newSymbol = IrAnonymousInitializerSymbolImpl(newParent.symbol)
isStatic = true IrAnonymousInitializerImpl(startOffset, endOffset, origin, newSymbol, isStatic = true).apply {
).apply {
parent = newParent parent = newParent
body = oldInitializer.body body = this@with.body
.replaceThisByStaticReference(context, oldParent, oldParent.thisReceiver!!) .replaceThisByStaticReference(context.declarationFactory, oldParent, oldParent.thisReceiver!!)
.patchDeclarationParents(newParent) as IrBlockBody .patchDeclarationParents(newParent) as IrBlockBody
} }
} }
private fun createStaticBackingField(oldField: IrField, propertyParent: IrClass, fieldParent: IrClass): IrField { private fun copyConstField(oldField: IrField, newParent: IrClass) =
val descriptor = WrappedFieldDescriptor(oldField.descriptor.annotations, oldField.descriptor.source) newParent.addField {
val field = IrFieldImpl( updateFrom(oldField)
oldField.startOffset, oldField.endOffset, name = oldField.name
IrDeclarationOrigin.PROPERTY_BACKING_FIELD, isStatic = true
IrFieldSymbolImpl(descriptor), }.apply {
oldField.name, oldField.type, oldField.visibility, parent = newParent
isFinal = oldField.isFinal, annotations += oldField.annotations
isExternal = oldField.isExternal, initializer = oldField.initializer?.deepCopyWithSymbols(this)
isStatic = true,
isFakeOverride = false
).apply {
descriptor.bind(this)
parent = fieldParent
annotations.addAll(oldField.annotations)
metadata = oldField.metadata
} }
val oldInitializer = oldField.initializer
if (oldInitializer != null) {
field.initializer = oldInitializer
.replaceThisByStaticReference(context, propertyParent, propertyParent.thisReceiver!!)
.deepCopyWithSymbols(field) as IrExpressionBody
}
return field
}
} }
private fun IrElement.replaceFieldReferences(replacementMap: Map<IrFieldSymbol, IrFieldSymbol>) { private class RemapObjectFieldAccesses(val context: JvmBackendContext) : FileLoweringPass, IrElementTransformerVoid() {
transformChildrenVoid(FieldReplacer(replacementMap)) override fun lower(irFile: IrFile) = irFile.transformChildrenVoid()
}
private fun IrField.remap(): IrField? =
correspondingPropertySymbol?.owner?.let(context.declarationFactory::getStaticBackingField)
private class FieldReplacer(val replacementMap: Map<IrFieldSymbol, IrFieldSymbol>) : IrElementTransformerVoid() {
override fun visitGetField(expression: IrGetField): IrExpression = override fun visitGetField(expression: IrGetField): IrExpression =
replacementMap[expression.symbol]?.let { newSymbol -> expression.symbol.owner.remap()?.let {
IrGetFieldImpl( with(expression) {
expression.startOffset, expression.endOffset, IrGetFieldImpl(startOffset, endOffset, it.symbol, type, /* receiver = */ null, origin, superQualifierSymbol)
newSymbol, }
expression.type,
/* receiver = */ null,
expression.origin,
expression.superQualifierSymbol
)
} ?: super.visitGetField(expression) } ?: super.visitGetField(expression)
override fun visitSetField(expression: IrSetField): IrExpression = override fun visitSetField(expression: IrSetField): IrExpression =
replacementMap[expression.symbol]?.let { _ -> expression.symbol.owner.remap()?.let {
IrSetFieldImpl( with(expression) {
expression.startOffset, expression.endOffset, val newValue = value.transform(this@RemapObjectFieldAccesses, null)
replacementMap.getValue(expression.symbol), IrSetFieldImpl(startOffset, endOffset, it.symbol, /* receiver = */ null, newValue, type, origin, superQualifierSymbol)
/* receiver = */ null, }
visitExpression(expression.value),
expression.type,
expression.origin,
expression.superQualifierSymbol
)
} ?: super.visitSetField(expression) } ?: super.visitSetField(expression)
} }
+10
View File
@@ -0,0 +1,10 @@
// TARGET_BACKEND: JVM
// WITH_RUNTIME
// FILE: box.kt
fun box(): String = Z.result
// FILE: z.kt
object Z {
@JvmField
val result: String = "OK"
}
@@ -0,0 +1,17 @@
// TARGET_BACKEND: JVM
// WITH_RUNTIME
// FILE: box.kt
fun box(): String = A.result
object A {
@JvmField
val result: String
init { result = Z.result }
}
// FILE: z.kt
object Z {
@JvmField
val result: String = "OK"
}
@@ -1,5 +1,4 @@
// !LANGUAGE: +JvmFieldInInterface +NestedClassesInAnnotations // !LANGUAGE: +JvmFieldInInterface +NestedClassesInAnnotations
// IGNORE_BACKEND: JVM_IR
// TARGET_BACKEND: JVM // TARGET_BACKEND: JVM
// WITH_RUNTIME // WITH_RUNTIME
@@ -1,5 +1,4 @@
// !LANGUAGE: +JvmFieldInInterface // !LANGUAGE: +JvmFieldInInterface
// IGNORE_BACKEND: JVM_IR
// TARGET_BACKEND: JVM // TARGET_BACKEND: JVM
// WITH_RUNTIME // WITH_RUNTIME
@@ -15058,6 +15058,16 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
runTest("compiler/testData/codegen/box/jvmField/constructorProperty.kt"); runTest("compiler/testData/codegen/box/jvmField/constructorProperty.kt");
} }
@TestMetadata("fileOrder.kt")
public void testFileOrder() throws Exception {
runTest("compiler/testData/codegen/box/jvmField/fileOrder.kt");
}
@TestMetadata("fileOrderWithCopying.kt")
public void testFileOrderWithCopying() throws Exception {
runTest("compiler/testData/codegen/box/jvmField/fileOrderWithCopying.kt");
}
@TestMetadata("initializersOrder.kt") @TestMetadata("initializersOrder.kt")
public void testInitializersOrder() throws Exception { public void testInitializersOrder() throws Exception {
runTest("compiler/testData/codegen/box/jvmField/initializersOrder.kt"); runTest("compiler/testData/codegen/box/jvmField/initializersOrder.kt");
@@ -15058,6 +15058,16 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
runTest("compiler/testData/codegen/box/jvmField/constructorProperty.kt"); runTest("compiler/testData/codegen/box/jvmField/constructorProperty.kt");
} }
@TestMetadata("fileOrder.kt")
public void testFileOrder() throws Exception {
runTest("compiler/testData/codegen/box/jvmField/fileOrder.kt");
}
@TestMetadata("fileOrderWithCopying.kt")
public void testFileOrderWithCopying() throws Exception {
runTest("compiler/testData/codegen/box/jvmField/fileOrderWithCopying.kt");
}
@TestMetadata("initializersOrder.kt") @TestMetadata("initializersOrder.kt")
public void testInitializersOrder() throws Exception { public void testInitializersOrder() throws Exception {
runTest("compiler/testData/codegen/box/jvmField/initializersOrder.kt"); runTest("compiler/testData/codegen/box/jvmField/initializersOrder.kt");
@@ -13913,6 +13913,16 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/jvmField/constructorProperty.kt"); runTest("compiler/testData/codegen/box/jvmField/constructorProperty.kt");
} }
@TestMetadata("fileOrder.kt")
public void testFileOrder() throws Exception {
runTest("compiler/testData/codegen/box/jvmField/fileOrder.kt");
}
@TestMetadata("fileOrderWithCopying.kt")
public void testFileOrderWithCopying() throws Exception {
runTest("compiler/testData/codegen/box/jvmField/fileOrderWithCopying.kt");
}
@TestMetadata("initializersOrder.kt") @TestMetadata("initializersOrder.kt")
public void testInitializersOrder() throws Exception { public void testInitializersOrder() throws Exception {
runTest("compiler/testData/codegen/box/jvmField/initializersOrder.kt"); runTest("compiler/testData/codegen/box/jvmField/initializersOrder.kt");
@@ -13913,6 +13913,16 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/jvmField/constructorProperty.kt"); runTest("compiler/testData/codegen/box/jvmField/constructorProperty.kt");
} }
@TestMetadata("fileOrder.kt")
public void testFileOrder() throws Exception {
runTest("compiler/testData/codegen/box/jvmField/fileOrder.kt");
}
@TestMetadata("fileOrderWithCopying.kt")
public void testFileOrderWithCopying() throws Exception {
runTest("compiler/testData/codegen/box/jvmField/fileOrderWithCopying.kt");
}
@TestMetadata("initializersOrder.kt") @TestMetadata("initializersOrder.kt")
public void testInitializersOrder() throws Exception { public void testInitializersOrder() throws Exception {
runTest("compiler/testData/codegen/box/jvmField/initializersOrder.kt"); runTest("compiler/testData/codegen/box/jvmField/initializersOrder.kt");