Move fields and init blocks of companions to their owners

This commit is contained in:
Georgy Bronnikov
2018-07-19 18:14:58 +03:00
parent 827494abbe
commit 605afbae90
42 changed files with 567 additions and 176 deletions
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.impl.ReceiverParameterDescriptorImpl
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.types.toKotlinType
import org.jetbrains.kotlin.ir.util.parentAsClass
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.constants.ConstantValue
import org.jetbrains.kotlin.resolve.descriptorUtil.module
@@ -200,6 +201,7 @@ open class WrappedVariableDescriptor(
override fun getContainingDeclaration() = (owner.parent as IrFunction).descriptor
override fun getType() = owner.type.toKotlinType()
override fun getReturnType() = getType()
override fun getName() = owner.name
override fun isConst() = owner.isConst
override fun isVar() = owner.isVar
@@ -489,7 +491,7 @@ open class WrappedPropertyDescriptor(
annotations: Annotations = Annotations.EMPTY,
private val sourceElement: SourceElement = SourceElement.NO_SOURCE
) : PropertyDescriptor, WrappedDeclarationDescriptor<IrField>(annotations) {
override fun getModality() = if (owner.isFinal) Modality.FINAL else Modality.OPEN
override fun getModality() = owner.correspondingProperty?.modality ?: Modality.FINAL
override fun setOverriddenDescriptors(overriddenDescriptors: MutableCollection<out CallableMemberDescriptor>) {
TODO("not implemented")
@@ -553,21 +555,18 @@ open class WrappedPropertyDescriptor(
override fun getType(): KotlinType = owner.type.toKotlinType()
override fun isVar() = owner.isFinal
override fun isVar() = !owner.isFinal
override fun getDispatchReceiverParameter(): ReceiverParameterDescriptor? {
TODO("not implemented")
}
override fun getDispatchReceiverParameter(): ReceiverParameterDescriptor? =
if (owner.isStatic) null else (owner.parentAsClass.thisReceiver?.descriptor as ReceiverParameterDescriptor)
override fun isConst() = false
override fun getContainingDeclaration() = (owner.parent as IrSymbolOwner).symbol.descriptor
override fun isLateInit() = false
override fun isLateInit() = owner.correspondingProperty?.isLateinit ?: false
override fun getExtensionReceiverParameter(): ReceiverParameterDescriptor? {
TODO("not implemented")
}
override fun getExtensionReceiverParameter(): ReceiverParameterDescriptor? = owner.correspondingProperty?.descriptor?.extensionReceiverParameter
override fun isExternal() = owner.isExternal
@@ -44,6 +44,7 @@ import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection
import org.jetbrains.kotlin.ir.util.DumpIrTreeVisitor
import org.jetbrains.kotlin.ir.util.defaultType
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.name.Name
import java.io.StringWriter
@@ -303,3 +304,21 @@ fun IrType.remapTypeParameters(source: IrTypeParametersContainer, target: IrType
else -> this
}
/* Copied from K/N */
fun IrDeclarationContainer.addChild(declaration: IrDeclaration) {
this.declarations += declaration
declaration.accept(SetDeclarationsParentVisitor, this)
}
object SetDeclarationsParentVisitor : IrElementVisitor<Unit, IrDeclarationParent> {
override fun visitElement(element: IrElement, data: IrDeclarationParent) {
if (element !is IrDeclarationParent) {
element.acceptChildren(this, data)
}
}
override fun visitDeclaration(declaration: IrDeclaration, data: IrDeclarationParent) {
declaration.parent = data
super.visitDeclaration(declaration, data)
}
}
@@ -7,34 +7,29 @@ package org.jetbrains.kotlin.backend.common.lower
import org.jetbrains.kotlin.backend.common.ClassLoweringPass
import org.jetbrains.kotlin.backend.common.CommonBackendContext
import org.jetbrains.kotlin.backend.common.ir.SetDeclarationsParentVisitor
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.SourceElement
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
import org.jetbrains.kotlin.ir.expressions.IrBlock
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrInstanceInitializerCall
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.IrBlockBodyImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrBlockImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrSetFieldImpl
import org.jetbrains.kotlin.ir.util.deepCopyWithSymbols
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
import java.util.*
object SYNTHESIZED_INIT_BLOCK: IrStatementOriginImpl("SYNTHESIZED_INIT_BLOCK")
class InitializersLowering(
val context: CommonBackendContext,
@@ -42,83 +37,101 @@ class InitializersLowering(
private val clinitNeeded: Boolean
) : ClassLoweringPass {
override fun lower(irClass: IrClass) {
val classInitializersBuilder = ClassInitializersBuilder(irClass)
irClass.acceptChildrenVoid(classInitializersBuilder)
val instanceInitializerStatements = handleNonStatics(irClass)
transformInstanceInitializerCallsInConstructors(irClass, instanceInitializerStatements)
classInitializersBuilder.transformInstanceInitializerCallsInConstructors(irClass)
if (clinitNeeded && classInitializersBuilder.staticInitializerStatements.isNotEmpty())
classInitializersBuilder.createStaticInitializationMethod(irClass)
val staticInitializerStatements = handleStatics(irClass)
if (clinitNeeded && staticInitializerStatements.isNotEmpty())
createStaticInitializationMethod(irClass, staticInitializerStatements)
}
private inner class ClassInitializersBuilder(val irClass: IrClass) : IrElementVisitorVoid {
val staticInitializerStatements = ArrayList<IrStatement>()
fun handleNonStatics(irClass: IrClass) =
irClass.declarations.filter {
(it is IrField && !it.isStatic) || (it is IrAnonymousInitializer && !it.isStatic)
}.mapNotNull { handleDeclaration(irClass, it) }
val instanceInitializerStatements = ArrayList<IrStatement>()
fun handleStatics(irClass: IrClass) =
// Hardcoded order of initializers
(irClass.declarations.filter { it is IrField && it.origin == IrDeclarationOrigin.FIELD_FOR_ENUM_ENTRY } +
irClass.declarations.filter { it is IrField && it.origin == IrDeclarationOrigin.FIELD_FOR_ENUM_VALUES } +
irClass.declarations.filter { it is IrField && it.origin == IrDeclarationOrigin.FIELD_FOR_OBJECT_INSTANCE } +
irClass.declarations.filter {
(it is IrField && it.isStatic && it.origin !in listOf(
IrDeclarationOrigin.FIELD_FOR_ENUM_ENTRY,
IrDeclarationOrigin.FIELD_FOR_ENUM_VALUES,
IrDeclarationOrigin.FIELD_FOR_OBJECT_INSTANCE
)) || (it is IrAnonymousInitializer && it.isStatic)
})
.mapNotNull { handleDeclaration(irClass, it) }
override fun visitElement(element: IrElement) {
// skip everything else
}
fun handleDeclaration(irClass: IrClass, declaration: IrDeclaration): IrStatement? = when(declaration) {
is IrField -> handleField(irClass, declaration)
is IrAnonymousInitializer -> handleAnonymousInitializer(declaration)
else -> null
}
override fun visitField(declaration: IrField) {
val irFieldInitializer = declaration.initializer?.expression ?: return
fun handleField(irClass: IrClass, declaration: IrField): IrStatement? {
val irFieldInitializer = declaration.initializer?.expression ?: return null
val receiver =
if (!declaration.isStatic) // TODO isStaticField
IrGetValueImpl(
irFieldInitializer.startOffset, irFieldInitializer.endOffset,
irClass.thisReceiver!!.type, irClass.thisReceiver!!.symbol
)
else null
val irSetField = IrSetFieldImpl(
irFieldInitializer.startOffset, irFieldInitializer.endOffset,
declaration.symbol,
receiver,
irFieldInitializer,
context.irBuiltIns.unitType,
null, null
)
if (declaration.isStatic) {
staticInitializerStatements.add(irSetField)
} else {
instanceInitializerStatements.add(irSetField)
}
}
override fun visitAnonymousInitializer(declaration: IrAnonymousInitializer) {
instanceInitializerStatements.addAll(declaration.body.statements)
}
fun transformInstanceInitializerCallsInConstructors(irClass: IrClass) {
irClass.transformChildrenVoid(object : IrElementTransformerVoid() {
override fun visitInstanceInitializerCall(expression: IrInstanceInitializerCall): IrExpression {
val copiedBlock = IrBlockImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, context.irBuiltIns.unitType, null, instanceInitializerStatements).copy(irClass) as IrBlock
return IrBlockImpl(irClass.startOffset, irClass.endOffset, context.irBuiltIns.unitType, null, copiedBlock.statements)
}
})
}
fun createStaticInitializationMethod(irClass: IrClass) {
val staticInitializerDescriptor = SimpleFunctionDescriptorImpl.create(
irClass.descriptor, Annotations.EMPTY, clinitName,
CallableMemberDescriptor.Kind.SYNTHESIZED,
SourceElement.NO_SOURCE
)
staticInitializerDescriptor.initialize(
null, null, emptyList(), emptyList(),
irClass.descriptor.builtIns.unitType,
Modality.FINAL, Visibilities.PUBLIC
)
irClass.declarations.add(
IrFunctionImpl(
irClass.startOffset, irClass.endOffset, declarationOrigin,
staticInitializerDescriptor,
IrBlockBodyImpl(irClass.startOffset, irClass.endOffset,
staticInitializerStatements.map { it.copy(irClass) })
val receiver =
if (!declaration.isStatic) // TODO isStaticField
IrGetValueImpl(
irFieldInitializer.startOffset, irFieldInitializer.endOffset,
irClass.thisReceiver!!.type, irClass.thisReceiver!!.symbol
)
)
}
else null
return IrSetFieldImpl(
irFieldInitializer.startOffset, irFieldInitializer.endOffset,
declaration.symbol,
receiver,
irFieldInitializer,
context.irBuiltIns.unitType,
null, null
)
}
fun handleAnonymousInitializer(declaration: IrAnonymousInitializer): IrStatement = IrBlockImpl(
declaration.startOffset, declaration.endOffset,
context.irBuiltIns.unitType,
SYNTHESIZED_INIT_BLOCK,
declaration.body.statements
)
fun transformInstanceInitializerCallsInConstructors(irClass: IrClass, instanceInitializerStatements: List<IrStatement>) {
irClass.transformChildrenVoid(object : IrElementTransformerVoid() {
override fun visitInstanceInitializerCall(expression: IrInstanceInitializerCall): IrExpression {
val copiedBlock =
IrBlockImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, context.irBuiltIns.unitType, null, instanceInitializerStatements).copy(
irClass
) as IrBlock
return IrBlockImpl(irClass.startOffset, irClass.endOffset, context.irBuiltIns.unitType, null, copiedBlock.statements)
}
})
}
fun createStaticInitializationMethod(irClass: IrClass, staticInitializerStatements: List<IrStatement>) {
val staticInitializerDescriptor = SimpleFunctionDescriptorImpl.create(
irClass.descriptor, Annotations.EMPTY, clinitName,
CallableMemberDescriptor.Kind.SYNTHESIZED,
SourceElement.NO_SOURCE
)
staticInitializerDescriptor.initialize(
null, null, emptyList(), emptyList(),
irClass.descriptor.builtIns.unitType,
Modality.FINAL, Visibilities.PUBLIC
)
irClass.declarations.add(
IrFunctionImpl(
irClass.startOffset, irClass.endOffset, declarationOrigin,
staticInitializerDescriptor,
IrBlockBodyImpl(irClass.startOffset, irClass.endOffset,
staticInitializerStatements.map { it.copy(irClass) })
).apply {
returnType = context.irBuiltIns.unitType
accept(SetDeclarationsParentVisitor, this)
}
)
}
companion object {
@@ -17,6 +17,7 @@
package org.jetbrains.kotlin.backend.common.lower
import org.jetbrains.kotlin.backend.common.BackendContext
import org.jetbrains.kotlin.backend.common.CommonBackendContext
import org.jetbrains.kotlin.backend.common.atMostOne
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
@@ -33,6 +34,8 @@ import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.types.IrSimpleType
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.classifierOrFail
import org.jetbrains.kotlin.ir.util.defaultType
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
@@ -235,3 +238,30 @@ fun ParameterDescriptor.copyAsValueParameter(newOwner: CallableDescriptor, index
)
else -> throw Error("Unexpected parameter descriptor: $this")
}
fun IrBody.replaceThisByStaticReference(
context: CommonBackendContext,
irClass: IrClass,
oldThisReceiverParameter: IrValueParameter
): IrBody =
transform(ReplaceThisByStaticReference(context, irClass, oldThisReceiverParameter), null)
private class ReplaceThisByStaticReference(
val context: CommonBackendContext,
val irClass: IrClass,
val oldThisReceiverParameter: IrValueParameter
) : IrElementTransformer<Nothing?> {
override fun visitGetValue(expression: IrGetValue, data: Nothing?): IrExpression {
val irGetValue = expression
if (irGetValue.symbol == oldThisReceiverParameter.symbol) {
val instanceField = context.declarationFactory.getFieldForObjectInstance(irClass)
return IrGetFieldImpl(
expression.startOffset,
expression.endOffset,
instanceField.symbol,
irClass.defaultType
)
}
return super.visitGetValue(irGetValue, data)
}
}
@@ -36,7 +36,8 @@ class PropertiesLowering : IrElementTransformerVoid(), FileLoweringPass {
private fun lowerProperty(declaration: IrDeclaration, kind: ClassKind): List<IrDeclaration>? =
if (declaration is IrProperty)
ArrayList<IrDeclaration>(3).apply {
if (kind != ClassKind.ANNOTATION_CLASS) {
// JvmFields in a companion object refer to companion's owners and should not be generated within companion.
if (kind != ClassKind.ANNOTATION_CLASS && declaration.backingField?.parent == declaration.parent) {
addIfNotNull(declaration.backingField)
}
addIfNotNull(declaration.getter)
@@ -24,9 +24,6 @@ import org.jetbrains.kotlin.ir.expressions.IrStatementOriginImpl
interface JvmLoweredDeclarationOrigin : IrDeclarationOrigin {
object CLASS_STATIC_INITIALIZER : IrDeclarationOriginImpl("CLASS_STATIC_INITIALIZER")
object DEFAULT_IMPLS : IrDeclarationOriginImpl("DEFAULT_IMPL")
object FIELD_FOR_ENUM_ENTRY : IrDeclarationOriginImpl("FIELD_FOR_ENUM_ENTRY")
object FIELD_FOR_ENUM_VALUES : IrDeclarationOriginImpl("FIELD_FOR_ENUM_VALUES")
object FIELD_FOR_OBJECT_INSTANCE : IrDeclarationOriginImpl("FIELD_FOR_OBJECT_INSTANCE")
object FIELD_FOR_OUTER_THIS : IrDeclarationOriginImpl("FIELD_FOR_OUTER_THIS")
object SYNTHETIC_ACCESSOR : IrDeclarationOriginImpl("SYNTHETIC_ACCESSOR")
object TO_ARRAY : IrDeclarationOriginImpl("TO_ARRAY")
@@ -40,6 +40,7 @@ class JvmLower(val context: JvmBackendContext) {
LateinitLowering(context, true).lower(irFile)
MoveCompanionObjectFieldsLowering(context).runOnFilePostfix(irFile)
ConstAndJvmFieldPropertiesLowering(context).lower(irFile)
PropertiesLowering().lower(irFile)
AnnotationLowering().runOnFilePostfix(irFile) //should be run before defaults lowering
@@ -17,7 +17,6 @@
package org.jetbrains.kotlin.backend.jvm.codegen
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
import org.jetbrains.kotlin.backend.jvm.descriptors.JvmDescriptorWithExtraFlags
import org.jetbrains.kotlin.codegen.*
import org.jetbrains.kotlin.codegen.binding.CodegenBinding
@@ -159,7 +158,7 @@ open class ClassCodegen protected constructor(
fieldSignature, null/*TODO support default values*/
)
if (field.origin == JvmLoweredDeclarationOrigin.FIELD_FOR_ENUM_ENTRY) {
if (field.origin == IrDeclarationOrigin.FIELD_FOR_ENUM_ENTRY) {
AnnotationCodegen.forField(fv, this, typeMapper).genAnnotations(field.descriptor, null)
} else {
@@ -254,7 +253,12 @@ fun MemberDescriptor.calculateCommonFlags(): Int {
private fun MemberDescriptor.calcModalityFlag(): Int {
var flags = 0
when (effectiveModality) {
if (this is PropertyDescriptor) {
// Modality for a field: set FINAL for vals
if (!isVar && !isLateInit) {
flags = flags.or(Opcodes.ACC_FINAL)
}
} else when (effectiveModality) {
Modality.ABSTRACT -> {
flags = flags.or(Opcodes.ACC_ABSTRACT)
}
@@ -61,7 +61,7 @@ class JvmDeclarationFactory(
IrFieldImpl(
enumEntry.startOffset,
enumEntry.endOffset,
JvmLoweredDeclarationOrigin.FIELD_FOR_ENUM_ENTRY,
IrDeclarationOrigin.FIELD_FOR_ENUM_ENTRY,
symbol,
type
)
@@ -181,7 +181,7 @@ class JvmDeclarationFactory(
return IrFieldImpl(
UNDEFINED_OFFSET,
UNDEFINED_OFFSET,
JvmLoweredDeclarationOrigin.FIELD_FOR_OBJECT_INSTANCE,
IrDeclarationOrigin.FIELD_FOR_OBJECT_INSTANCE,
symbol,
singleton.defaultType
)
@@ -5,30 +5,23 @@
package org.jetbrains.kotlin.backend.jvm.lower
import org.jetbrains.kotlin.backend.common.CommonBackendContext
import org.jetbrains.kotlin.backend.common.FileLoweringPass
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
import org.jetbrains.kotlin.backend.common.lower.irBlock
import org.jetbrains.kotlin.codegen.JvmCodegenUtil
import org.jetbrains.kotlin.descriptors.PropertyAccessorDescriptor
import org.jetbrains.kotlin.descriptors.PropertyGetterDescriptor
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.ir.declarations.IrProperty
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
import org.jetbrains.kotlin.ir.expressions.IrCall
import org.jetbrains.kotlin.ir.expressions.IrConst
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.impl.IrGetFieldImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrGetterCallImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrSetFieldImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrSetterCallImpl
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.types.classifierOrFail
import org.jetbrains.kotlin.ir.util.hasAnnotation
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
import org.jetbrains.kotlin.synthetic.SyntheticJavaPropertyDescriptor
class ConstAndJvmFieldPropertiesLowering(val context: JvmBackendContext) : IrElementTransformerVoid(), FileLoweringPass {
class ConstAndJvmFieldPropertiesLowering(val context: CommonBackendContext) : IrElementTransformerVoid(), FileLoweringPass {
override fun lower(irFile: IrFile) {
irFile.transformChildrenVoid(this)
}
@@ -43,7 +36,8 @@ class ConstAndJvmFieldPropertiesLowering(val context: JvmBackendContext) : IrEle
}
override fun visitCall(expression: IrCall): IrExpression {
val irProperty = (expression.symbol.owner as? IrSimpleFunction)?.correspondingProperty ?: return super.visitCall(expression)
val irSimpleFunction = (expression.symbol.owner as? IrSimpleFunction) ?: return super.visitCall(expression)
val irProperty = irSimpleFunction.correspondingProperty ?: return super.visitCall(expression)
if (irProperty.isConst) {
(irProperty.backingField?.initializer?.expression as? IrConst<*>)?.let { return it }
@@ -63,28 +57,60 @@ class ConstAndJvmFieldPropertiesLowering(val context: JvmBackendContext) : IrEle
return super.visitCall(expression)
}
private fun substituteSetter(irProperty: IrProperty, expression: IrCall): IrSetFieldImpl {
return IrSetFieldImpl(
private fun substituteSetter(irProperty: IrProperty, expression: IrCall): IrExpression {
val backingField = irProperty.backingField!!
val receiver = expression.dispatchReceiver?.let { super.visitExpression(it) }
val setExpr = IrSetFieldImpl(
expression.startOffset,
expression.endOffset,
irProperty.backingField!!.symbol,
expression.dispatchReceiver,
expression.getValueArgument(expression.symbol.owner.valueParameters.lastIndex)!!,
backingField.symbol,
receiver,
super.visitExpression(expression.getValueArgument(expression.valueArgumentsCount - 1)!!),
expression.type,
expression.origin,
expression.superQualifier?.let { context.ir.symbols.externalSymbolTable.referenceClass(it) }
expression.superQualifierSymbol
)
return buildSubstitution(backingField.isStaticField(), setExpr, receiver)
}
private fun substituteGetter(irProperty: IrProperty, expression: IrCall): IrExpression {
return IrGetFieldImpl(
val backingField = irProperty.backingField!!
val receiver = expression.dispatchReceiver?.let { super.visitExpression(it) }
val getExpr = IrGetFieldImpl(
expression.startOffset,
expression.endOffset,
irProperty.backingField!!.symbol,
backingField.symbol,
expression.type,
expression.dispatchReceiver,
receiver,
expression.origin,
expression.superQualifier?.let { context.ir.symbols.externalSymbolTable.referenceClass(it) }
expression.superQualifierSymbol
)
return buildSubstitution(backingField.isStaticField(), getExpr, receiver)
}
private fun buildSubstitution(needBlock: Boolean, setOrGetExpr: IrFieldAccessExpression, receiver: IrExpression?): IrExpression {
if (receiver != null && needBlock) {
// Evaluate `dispatchReceiver` for the sake of its side effects, then return `setOrGetExpr`.
return context.createIrBuilder(setOrGetExpr.symbol, setOrGetExpr.startOffset, setOrGetExpr.endOffset).irBlock(setOrGetExpr) {
// `coerceToUnit()` is private in InsertImplicitCasts, have to reproduce it here
val receiverVoid = IrTypeOperatorCallImpl(
receiver.startOffset, receiver.endOffset,
context.irBuiltIns.unitType,
IrTypeOperator.IMPLICIT_COERCION_TO_UNIT,
context.irBuiltIns.unitType, context.irBuiltIns.unitType.classifierOrFail,
receiver
)
+receiverVoid
setOrGetExpr.receiver = null
+setOrGetExpr
}
} else {
// Just `setOrGetExpr` (`dispatchReceiver` is evaluated as a subexpression thereof)
return setOrGetExpr
}
}
}
// Should probably be an utility function with a more direct implementation.
private fun IrField.isStaticField() = (descriptor.dispatchReceiverParameter == null)
@@ -8,7 +8,6 @@ package org.jetbrains.kotlin.backend.jvm.lower
import gnu.trove.TObjectIntHashMap
import org.jetbrains.kotlin.backend.common.ClassLoweringPass
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
import org.jetbrains.kotlin.backend.jvm.descriptors.JvmPropertyDescriptorImpl
import org.jetbrains.kotlin.backend.jvm.descriptors.createValueParameter
import org.jetbrains.kotlin.descriptors.*
@@ -221,7 +220,7 @@ class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringPass {
val irValuesInitializer = createSyntheticValuesFieldInitializerExpression()
return IrFieldImpl(
UNDEFINED_OFFSET, UNDEFINED_OFFSET, JvmLoweredDeclarationOrigin.FIELD_FOR_ENUM_VALUES,
UNDEFINED_OFFSET, UNDEFINED_OFFSET, IrDeclarationOrigin.FIELD_FOR_ENUM_VALUES,
createSyntheticValuesFieldDescriptor(valuesArrayType),
valuesArrayType.toIrType()!!,
IrExpressionBodyImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, irValuesInitializer)
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.backend.common.ClassLoweringPass
import org.jetbrains.kotlin.backend.common.FileLoweringPass
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
import org.jetbrains.kotlin.backend.common.lower.irBlock
import org.jetbrains.kotlin.backend.common.lower.replaceThisByStaticReference
import org.jetbrains.kotlin.backend.common.runOnFilePostfix
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
@@ -156,26 +157,7 @@ private class SingletonObjectJvmStaticLowering(
}
fun modifyBody(irFunction: IrFunction, irClass: IrClass, oldDispatchReceiverParameter: IrValueParameter) {
irFunction.body = irFunction.body?.transform(ReplaceThisByStaticReference(context, irClass, oldDispatchReceiverParameter), null)
}
}
private class ReplaceThisByStaticReference(
val context: JvmBackendContext,
val irClass: IrClass,
val oldThisReceiverParameter: IrValueParameter
) : IrElementTransformer<Nothing?> {
override fun visitGetValue(expression: IrGetValue, data: Nothing?): IrExpression {
if (expression.symbol == oldThisReceiverParameter.symbol) {
val instanceField = context.declarationFactory.getFieldForObjectInstance(irClass)
return IrGetFieldImpl(
expression.startOffset,
expression.endOffset,
instanceField.symbol,
irClass.defaultType
)
}
return super.visitGetValue(expression, data)
irFunction.body = irFunction.body?.replaceThisByStaticReference(context, irClass, oldDispatchReceiverParameter)
}
}
@@ -0,0 +1,226 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.backend.jvm.lower
import org.jetbrains.kotlin.backend.common.ClassLoweringPass
import org.jetbrains.kotlin.backend.common.CommonBackendContext
import org.jetbrains.kotlin.backend.common.descriptors.WrappedPropertyDescriptor
import org.jetbrains.kotlin.backend.common.descriptors.WrappedVariableDescriptor
import org.jetbrains.kotlin.backend.common.lower.replaceThisByStaticReference
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.declarations.*
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.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol
import org.jetbrains.kotlin.ir.symbols.impl.IrAnonymousInitializerSymbolImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrFieldSymbolImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrVariableSymbolImpl
import org.jetbrains.kotlin.ir.util.hasAnnotation
import org.jetbrains.kotlin.ir.util.isInterface
import org.jetbrains.kotlin.ir.util.isObject
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
import org.jetbrains.kotlin.name.Name
class MoveCompanionObjectFieldsLowering(val context: CommonBackendContext) : ClassLoweringPass {
override fun lower(irClass: IrClass) {
val fieldReplacementMap = mutableMapOf<IrFieldSymbol, IrFieldSymbol>()
if (irClass.isObject && !irClass.isCompanion && irClass.visibility != Visibilities.LOCAL) {
handleObject(irClass, fieldReplacementMap)
} else {
handleClass(irClass, fieldReplacementMap)
}
irClass.replaceFieldReferences(fieldReplacementMap)
}
private fun handleObject(irObject: IrClass, fieldReplacementMap: MutableMap<IrFieldSymbol, IrFieldSymbol>) {
irObject.declarations.replaceAll {
when (it) {
is IrProperty -> {
// The field is not actually moved, just replaced by a static field
movePropertyFieldToStaticParent(it, irObject, irObject, fieldReplacementMap)
it
}
is IrAnonymousInitializer -> moveAnonymousInitializerToStaticParent(it, irObject, irObject)
else -> it
}
}
}
private fun handleClass(irClass: IrClass, fieldReplacementMap: MutableMap<IrFieldSymbol, IrFieldSymbol>) {
val companion = irClass.declarations.find {
it is IrClass && it.isCompanion
} as IrClass? ?: return
if (irClass.isInterface && !companion.allFieldsAreJvmField()) return
companion.declarations.forEach {
when (it) {
is IrProperty -> {
val newField = movePropertyFieldToStaticParent(it, companion, irClass, fieldReplacementMap)
if (newField != null) irClass.declarations.add(newField)
}
is IrAnonymousInitializer -> {
val newInitializer = moveAnonymousInitializerToStaticParent(it, companion, irClass)
irClass.declarations.add(newInitializer)
}
else -> Unit
}
}
companion.declarations.removeAll { it is IrAnonymousInitializer }
}
private fun IrClass.allFieldsAreJvmField() =
declarations.filterIsInstance<IrProperty>()
.mapNotNull { it.backingField }.all { it.hasAnnotation(JVM_FIELD_ANNOTATION_FQ_NAME) }
private fun movePropertyFieldToStaticParent(
irProperty: IrProperty,
propertyParent: IrClass,
fieldParent: IrClass,
fieldReplacementMap: MutableMap<IrFieldSymbol, IrFieldSymbol>
): IrField? {
if (irProperty.origin == IrDeclarationOrigin.FAKE_OVERRIDE) return null
val oldField = irProperty.backingField ?: return null
val newField = createStaticBackingField(oldField, propertyParent, fieldParent)
irProperty.backingField = newField
fieldReplacementMap[oldField.symbol] = newField.symbol
return newField
}
private fun moveAnonymousInitializerToStaticParent(
oldInitializer: IrAnonymousInitializer,
oldParent: IrClass,
newParent: IrClass
): IrAnonymousInitializer =
with(oldInitializer) {
IrAnonymousInitializerImpl(
startOffset, endOffset, origin, IrAnonymousInitializerSymbolImpl(newParent.descriptor),
isStatic = true
).apply {
parent = newParent
body = oldInitializer.body.transferToNewParent(oldParent, newParent)
}
}
private fun IrBlockBody.transferToNewParent(oldParent: IrClass, newParent: IrClass): IrBlockBody {
val objectInstanceField = context.declarationFactory.getFieldForObjectInstance(oldParent)
return transform(
data = null,
transformer = object : IrElementTransformerVoid() {
val variableMap = mutableMapOf<IrVariable, IrVariable>()
override fun visitVariable(declaration: IrVariable): IrStatement {
val newDescriptor = WrappedVariableDescriptor(declaration.descriptor.annotations, declaration.descriptor.source)
if (declaration.parent == oldParent) {
val newVariable = IrVariableImpl(
declaration.startOffset, declaration.endOffset,
declaration.origin, IrVariableSymbolImpl(newDescriptor),
declaration.name, declaration.type, declaration.isVar, declaration.isConst, declaration.isLateinit
).apply {
newDescriptor.bind(this)
parent = newParent
initializer = declaration.initializer
}
variableMap[declaration] = newVariable
return super.visitVariable(newVariable)
}
return super.visitVariable(declaration)
}
override fun visitGetValue(expression: IrGetValue): IrExpression {
if (expression.symbol.owner == oldParent.thisReceiver) {
return IrGetFieldImpl(
expression.startOffset, expression.endOffset,
objectInstanceField.symbol,
expression.type
)
}
variableMap[expression.symbol.owner]?.let { newVariable ->
return IrGetValueImpl(
expression.startOffset, expression.endOffset,
expression.type,
newVariable.symbol,
expression.origin
)
}
return super.visitGetValue(expression)
}
}) as IrBlockBody
}
private fun createStaticBackingField(oldField: IrField, propertyParent: IrClass, fieldParent: IrClass): IrField {
val newName = if (fieldParent == propertyParent ||
oldField.hasAnnotation(JVM_FIELD_ANNOTATION_FQ_NAME) ||
oldField.correspondingProperty?.isConst == true
)
oldField.name
else
Name.identifier(oldField.name.toString() + "\$companion")
val descriptor = WrappedPropertyDescriptor(oldField.descriptor.annotations, oldField.descriptor.source)
val field = IrFieldImpl(
oldField.startOffset, oldField.endOffset,
IrDeclarationOrigin.PROPERTY_BACKING_FIELD,
IrFieldSymbolImpl(descriptor),
newName, oldField.type, oldField.visibility,
isFinal = oldField.isFinal,
isExternal = oldField.isExternal,
isStatic = true
).apply {
descriptor.bind(this)
parent = fieldParent
oldField.annotations.mapTo(annotations) { it }
}
val oldInitializer = oldField.initializer
if (oldInitializer != null) {
field.initializer = oldInitializer.replaceThisByStaticReference(
context,
propertyParent,
propertyParent.thisReceiver!!
) as IrExpressionBody
}
return field
}
}
private fun IrElement.replaceFieldReferences(replacementMap: Map<IrFieldSymbol, IrFieldSymbol>) {
transformChildrenVoid(FieldReplacer(replacementMap))
}
private class FieldReplacer(val replacementMap: Map<IrFieldSymbol, IrFieldSymbol>) : IrElementTransformerVoid() {
override fun visitGetField(expression: IrGetField): IrExpression =
replacementMap[expression.symbol]?.let { newSymbol ->
IrGetFieldImpl(
expression.startOffset, expression.endOffset,
newSymbol,
expression.type,
/* receiver = */ null,
expression.origin,
expression.superQualifierSymbol
)
} ?: super.visitGetField(expression)
override fun visitSetField(expression: IrSetField): IrExpression =
replacementMap[expression.symbol]?.let { newSymbol ->
IrSetFieldImpl(
expression.startOffset, expression.endOffset,
replacementMap[expression.symbol]!!,
/* receiver = */ null,
visitExpression(expression.value),
expression.type,
expression.origin,
expression.superQualifierSymbol
)
} ?: super.visitSetField(expression)
}
@@ -8,15 +8,11 @@ package org.jetbrains.kotlin.backend.jvm.lower
import org.jetbrains.kotlin.backend.common.FileLoweringPass
import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
import org.jetbrains.kotlin.codegen.JvmCodegenUtil.isCompanionObjectInInterfaceNotIntrinsic
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrDeclarationContainer
import org.jetbrains.kotlin.ir.declarations.IrField
import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.IrFieldImpl
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
@@ -24,7 +20,6 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrExpressionBodyImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrGetFieldImpl
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol
import org.jetbrains.kotlin.ir.symbols.impl.IrFieldSymbolImpl
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.util.defaultType
import org.jetbrains.kotlin.ir.util.isObject
@@ -80,7 +75,9 @@ class ObjectClassLowering(val context: JvmBackendContext) : IrElementTransformer
}
publicInstanceField.parent = publicInstanceOwner
pendingTransformations.add { publicInstanceOwner.declarations.add(publicInstanceField) }
pendingTransformations.add {
publicInstanceOwner.declarations.add(publicInstanceField)
}
}
private fun createInstanceFieldWithInitializer(
@@ -103,7 +100,7 @@ class ObjectClassLowering(val context: JvmBackendContext) : IrElementTransformer
objectType: IrType
): IrField =
IrFieldImpl(
UNDEFINED_OFFSET, UNDEFINED_OFFSET, JvmLoweredDeclarationOrigin.FIELD_FOR_OBJECT_INSTANCE,
UNDEFINED_OFFSET, UNDEFINED_OFFSET, IrDeclarationOrigin.FIELD_FOR_OBJECT_INSTANCE,
fieldSymbol, objectType
).also {
it.initializer = IrExpressionBodyImpl(instanceInitializer)
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.ir.symbols.IrAnonymousInitializerSymbol
interface IrAnonymousInitializer : IrSymbolDeclaration<IrAnonymousInitializerSymbol> {
override val descriptor: ClassDescriptor // TODO special descriptor for anonymous initializer blocks
val isStatic: Boolean
var body: IrBlockBody
}
@@ -38,6 +38,10 @@ interface IrDeclarationOrigin {
object IR_EXTERNAL_DECLARATION_STUB : IrDeclarationOriginImpl("IR_EXTERNAL_DECLARATION_STUB")
object IR_BUILTINS_STUB : IrDeclarationOriginImpl("IR_BUILTINS_STUB")
object BRIDGE : IrDeclarationOriginImpl("BRIDGE")
object FIELD_FOR_ENUM_ENTRY : IrDeclarationOriginImpl("FIELD_FOR_ENUM_ENTRY")
object FIELD_FOR_ENUM_VALUES : IrDeclarationOriginImpl("FIELD_FOR_ENUM_VALUES")
object FIELD_FOR_OBJECT_INSTANCE : IrDeclarationOriginImpl("FIELD_FOR_OBJECT_INSTANCE")
}
abstract class IrDeclarationOriginImpl(val name: String) : IrDeclarationOrigin {
@@ -29,7 +29,8 @@ class IrAnonymousInitializerImpl(
startOffset: Int,
endOffset: Int,
origin: IrDeclarationOrigin,
override val symbol: IrAnonymousInitializerSymbol
override val symbol: IrAnonymousInitializerSymbol,
override val isStatic: Boolean = false
) : IrDeclarationBase(startOffset, endOffset, origin),
IrAnonymousInitializer {
@@ -37,17 +38,19 @@ class IrAnonymousInitializerImpl(
startOffset: Int,
endOffset: Int,
origin: IrDeclarationOrigin,
descriptor: ClassDescriptor
descriptor: ClassDescriptor,
isStatic: Boolean = false
) :
this(startOffset, endOffset, origin, IrAnonymousInitializerSymbolImpl(descriptor))
this(startOffset, endOffset, origin, IrAnonymousInitializerSymbolImpl(descriptor), isStatic)
constructor(
startOffset: Int,
endOffset: Int,
origin: IrDeclarationOrigin,
descriptor: ClassDescriptor,
body: IrBlockBody
) : this(startOffset, endOffset, origin, descriptor) {
body: IrBlockBody,
isStatic: Boolean = false
) : this(startOffset, endOffset, origin, descriptor, isStatic) {
this.body = body
}
@@ -0,0 +1,36 @@
// TARGET_BACKEND: JVM
// WITH_RUNTIME
import kotlin.test.assertEquals
class WithCompanion {
companion object {
var a = 0
init {
a++
}
@JvmField var b = a
init {
b++
}
val c = b
}
}
object Object {
var a = 0
init {
a++
}
@JvmField var b = a
init {
b++
}
val c = b
}
fun box(): String {
assertEquals<Int>(2, WithCompanion.c, "Field WithCompanion.c")
assertEquals<Int>(2, Object.c, "Field Object")
return "OK"
}
@@ -1,5 +1,4 @@
// !LANGUAGE: +JvmFieldInInterface
// IGNORE_BACKEND: JVM_IR
// TARGET_BACKEND: JVM
// WITH_RUNTIME
@@ -0,0 +1,43 @@
// TARGET_BACKEND: JVM
// WITH_RUNTIME
// FILE: Test.java
public class Test {
public static String getField()
{
return new A().field;
}
public static String getCField()
{
return A.cfield;
}
public static String getObjectField()
{
return Object.field;
}
}
// FILE: publicFieldJava.kt
class A {
@JvmField public val field = "OK";
companion object {
@JvmField public val cfield = "OK";
}
}
object Object {
@JvmField public val field = "OK";
}
fun box(): String {
if (Test.getField() != "OK") return "fail 1: ${Test.getField()}"
if (Test.getCField() != "OK") return "fail 2: ${Test.getCField()}"
if (Test.getObjectField() != "OK") return "fail 3: ${Test.getObjectField()}"
return "OK"
}
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
// IGNORE_BACKEND: JS_IR
// TODO: muted automatically, investigate should it be ran for JS or not
// IGNORE_BACKEND: JS, NATIVE
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
object O {
val mmmap = HashMap<String, Int>();
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
object A {
val a = "OK"
val b = A.a
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
class A(val result: String)
fun a(body: A.() -> String): String {
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
interface T
object Foo {
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
class Test {
companion object {
fun ok() = "OK"
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
object Test {
fun ok() = "OK"
val x = run { Test.ok() }
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
class My {
var my: String = "U"
get() = { field }()
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
// IGNORE_BACKEND: JS_IR
// TODO: muted automatically, investigate should it be ran for JS or not
// IGNORE_BACKEND: JS, NATIVE
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
// IGNORE_BACKEND: JS_IR
// TODO: muted automatically, investigate should it be ran for JS or not
// IGNORE_BACKEND: JS, NATIVE
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
// IGNORE_BACKEND: JS_IR
// TODO: muted automatically, investigate should it be ran for JS or not
// IGNORE_BACKEND: JS, NATIVE
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
// IGNORE_BACKEND: JS_IR
// TODO: muted automatically, investigate should it be ran for JS or not
// IGNORE_BACKEND: JS, NATIVE
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
// IGNORE_BACKEND: JS_IR
// TODO: muted automatically, investigate should it be ran for JS or not
// IGNORE_BACKEND: JS, NATIVE
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
// IGNORE_BACKEND: JS_IR
// TODO: muted automatically, investigate should it be ran for JS or not
// IGNORE_BACKEND: JS, NATIVE
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
// IGNORE_BACKEND: JS_IR
// TODO: muted automatically, investigate should it be ran for JS or not
// IGNORE_BACKEND: JS, NATIVE
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
// IGNORE_BACKEND: JS_IR
// TODO: muted automatically, investigate should it be ran for JS or not
// IGNORE_BACKEND: JS, NATIVE
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
// IGNORE_BACKEND: JS_IR
// TODO: muted automatically, investigate should it be ran for JS or not
// IGNORE_BACKEND: JS, NATIVE
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
open class Bar<T>(val prop: String)
class Foo {
companion object : Bar<Foo>("OK") {
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
open class Bar<T>(val prop: String)
object Foo : Bar<Foo>("OK") {
@@ -13435,6 +13435,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
runTest("compiler/testData/codegen/box/jvmField/constructorProperty.kt");
}
@TestMetadata("initializersOrder.kt")
public void testInitializersOrder() throws Exception {
runTest("compiler/testData/codegen/box/jvmField/initializersOrder.kt");
}
@TestMetadata("interfaceCompanion.kt")
public void testInterfaceCompanion() throws Exception {
runTest("compiler/testData/codegen/box/jvmField/interfaceCompanion.kt");
@@ -13450,6 +13455,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
runTest("compiler/testData/codegen/box/jvmField/publicField.kt");
}
@TestMetadata("publicFieldJava.kt")
public void testPublicFieldJava() throws Exception {
runTest("compiler/testData/codegen/box/jvmField/publicFieldJava.kt");
}
@TestMetadata("simpleMemberProperty.kt")
public void testSimpleMemberProperty() throws Exception {
runTest("compiler/testData/codegen/box/jvmField/simpleMemberProperty.kt");
@@ -13435,6 +13435,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
runTest("compiler/testData/codegen/box/jvmField/constructorProperty.kt");
}
@TestMetadata("initializersOrder.kt")
public void testInitializersOrder() throws Exception {
runTest("compiler/testData/codegen/box/jvmField/initializersOrder.kt");
}
@TestMetadata("interfaceCompanion.kt")
public void testInterfaceCompanion() throws Exception {
runTest("compiler/testData/codegen/box/jvmField/interfaceCompanion.kt");
@@ -13450,6 +13455,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
runTest("compiler/testData/codegen/box/jvmField/publicField.kt");
}
@TestMetadata("publicFieldJava.kt")
public void testPublicFieldJava() throws Exception {
runTest("compiler/testData/codegen/box/jvmField/publicFieldJava.kt");
}
@TestMetadata("simpleMemberProperty.kt")
public void testSimpleMemberProperty() throws Exception {
runTest("compiler/testData/codegen/box/jvmField/simpleMemberProperty.kt");
@@ -13440,6 +13440,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/jvmField/constructorProperty.kt");
}
@TestMetadata("initializersOrder.kt")
public void testInitializersOrder() throws Exception {
runTest("compiler/testData/codegen/box/jvmField/initializersOrder.kt");
}
@TestMetadata("interfaceCompanion.kt")
public void testInterfaceCompanion() throws Exception {
runTest("compiler/testData/codegen/box/jvmField/interfaceCompanion.kt");
@@ -13455,6 +13460,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/jvmField/publicField.kt");
}
@TestMetadata("publicFieldJava.kt")
public void testPublicFieldJava() throws Exception {
runTest("compiler/testData/codegen/box/jvmField/publicFieldJava.kt");
}
@TestMetadata("simpleMemberProperty.kt")
public void testSimpleMemberProperty() throws Exception {
runTest("compiler/testData/codegen/box/jvmField/simpleMemberProperty.kt");