Support class companion object lowering
This commit is contained in:
@@ -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)
|
||||
|
||||
+4
-2
@@ -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)
|
||||
|
||||
+25
-5
@@ -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<Function0<Unit>>()
|
||||
|
||||
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) }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user