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 81369d41148..98ba90d5e79 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 @@ -47,7 +47,8 @@ class JvmLower(val context: JvmBackendContext) { NameUtils.sanitizeAsJavaIdentifier(super.localName(descriptor)) }).runOnFilePostfix(irFile) EnumClassLowering(context).runOnFilePostfix(irFile) - ObjectClassLowering(context).runOnFilePostfix(irFile) + //Should be before SyntheticAccessorLowering cause of synthetic accessor for companion constructor + ObjectClassLowering(context).lower(irFile) InitializersLowering(context).runOnFilePostfix(irFile) SingletonReferencesLowering(context).runOnFilePostfix(irFile) SyntheticAccessorLowering(context).lower(irFile) diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/SpecialDescriptorsFactory.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/SpecialDescriptorsFactory.kt index 14886f83c4f..09b7f99254c 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/SpecialDescriptorsFactory.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/SpecialDescriptorsFactory.kt @@ -125,10 +125,12 @@ class SpecialDescriptorsFactory( private fun createObjectInstanceFieldDescriptor(objectDescriptor: ClassDescriptor): PropertyDescriptor { assert(objectDescriptor.kind == ClassKind.OBJECT) { "Should be an object: $objectDescriptor" } + val name = if (objectDescriptor.isCompanionObject) objectDescriptor.name else Name.identifier("INSTANCE") + val containingDeclaration = if (objectDescriptor.isCompanionObject) objectDescriptor.containingDeclaration else objectDescriptor return PropertyDescriptorImpl.create( - objectDescriptor, + containingDeclaration, Annotations.EMPTY, Modality.FINAL, Visibilities.PUBLIC, false, - Name.identifier("INSTANCE"), + name, CallableMemberDescriptor.Kind.SYNTHESIZED, SourceElement.NO_SOURCE, /* lateInit = */ false, /* isConst = */ false, /* isExpect = */ false, /* isActual = */ false, /* isExternal = */ false, /* isDelegated = */ false ).initialize(objectDescriptor.defaultType) diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/ObjectClassLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/ObjectClassLowering.kt index 13c8b741d08..e94105f52c3 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/ObjectClassLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/ObjectClassLowering.kt @@ -16,32 +16,52 @@ package org.jetbrains.kotlin.backend.jvm.lower -import org.jetbrains.kotlin.backend.common.ClassLoweringPass +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.descriptors.ClassKind +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.IrFile import org.jetbrains.kotlin.ir.declarations.impl.IrFieldImpl import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl import org.jetbrains.kotlin.ir.expressions.impl.IrExpressionBodyImpl -class ObjectClassLowering(val context: JvmBackendContext) : ClassLoweringPass { - override fun lower(irClass: IrClass) { +class ObjectClassLowering(val context: JvmBackendContext) : IrElementTransformerVoidWithContext(), FileLoweringPass { + + private var pendingTransformations = mutableListOf>() + + override fun lower(irFile: IrFile) { + irFile.accept(this, null) + + pendingTransformations.forEach { it() } + } + + override fun visitClassNew(declaration: IrClass): IrStatement { + process(declaration) + return super.visitClassNew(declaration) + } + + + fun process(irClass: IrClass) { if (irClass.descriptor.kind != ClassKind.OBJECT) return val instanceFieldDescriptor = context.specialDescriptorsFactory.getFieldDescriptorForObjectInstance(irClass.descriptor) val constructor = irClass.descriptor.unsubstitutedPrimaryConstructor ?: throw AssertionError("Object should have a primary constructor: ${irClass.descriptor}") - val instanceInitializer = IrCallImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, constructor) + val instanceInitializer = IrCallImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, constructor) val instanceField = IrFieldImpl( UNDEFINED_OFFSET, UNDEFINED_OFFSET, JvmLoweredDeclarationOrigin.FIELD_FOR_OBJECT_INSTANCE, instanceFieldDescriptor, IrExpressionBodyImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, instanceInitializer) ) - irClass.declarations.add(instanceField) + val instanceOwner = if (irClass.descriptor.isCompanionObject) parentScope!!.irElement as IrDeclarationContainer else irClass + pendingTransformations.add { instanceOwner.declarations.add(instanceField) } } } \ No newline at end of file