Support class companion object lowering
This commit is contained in:
@@ -47,7 +47,8 @@ class JvmLower(val context: JvmBackendContext) {
|
|||||||
NameUtils.sanitizeAsJavaIdentifier(super.localName(descriptor))
|
NameUtils.sanitizeAsJavaIdentifier(super.localName(descriptor))
|
||||||
}).runOnFilePostfix(irFile)
|
}).runOnFilePostfix(irFile)
|
||||||
EnumClassLowering(context).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)
|
InitializersLowering(context).runOnFilePostfix(irFile)
|
||||||
SingletonReferencesLowering(context).runOnFilePostfix(irFile)
|
SingletonReferencesLowering(context).runOnFilePostfix(irFile)
|
||||||
SyntheticAccessorLowering(context).lower(irFile)
|
SyntheticAccessorLowering(context).lower(irFile)
|
||||||
|
|||||||
+4
-2
@@ -125,10 +125,12 @@ class SpecialDescriptorsFactory(
|
|||||||
private fun createObjectInstanceFieldDescriptor(objectDescriptor: ClassDescriptor): PropertyDescriptor {
|
private fun createObjectInstanceFieldDescriptor(objectDescriptor: ClassDescriptor): PropertyDescriptor {
|
||||||
assert(objectDescriptor.kind == ClassKind.OBJECT) { "Should be an object: $objectDescriptor" }
|
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(
|
return PropertyDescriptorImpl.create(
|
||||||
objectDescriptor,
|
containingDeclaration,
|
||||||
Annotations.EMPTY, Modality.FINAL, Visibilities.PUBLIC, false,
|
Annotations.EMPTY, Modality.FINAL, Visibilities.PUBLIC, false,
|
||||||
Name.identifier("INSTANCE"),
|
name,
|
||||||
CallableMemberDescriptor.Kind.SYNTHESIZED, SourceElement.NO_SOURCE, /* lateInit = */ false, /* isConst = */ false,
|
CallableMemberDescriptor.Kind.SYNTHESIZED, SourceElement.NO_SOURCE, /* lateInit = */ false, /* isConst = */ false,
|
||||||
/* isExpect = */ false, /* isActual = */ false, /* isExternal = */ false, /* isDelegated = */ false
|
/* isExpect = */ false, /* isActual = */ false, /* isExternal = */ false, /* isDelegated = */ false
|
||||||
).initialize(objectDescriptor.defaultType)
|
).initialize(objectDescriptor.defaultType)
|
||||||
|
|||||||
+25
-5
@@ -16,32 +16,52 @@
|
|||||||
|
|
||||||
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.FileLoweringPass
|
||||||
|
import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext
|
||||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||||
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
|
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
|
||||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||||
|
import org.jetbrains.kotlin.ir.IrStatement
|
||||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
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.declarations.impl.IrFieldImpl
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrExpressionBodyImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrExpressionBodyImpl
|
||||||
|
|
||||||
class ObjectClassLowering(val context: JvmBackendContext) : ClassLoweringPass {
|
class ObjectClassLowering(val context: JvmBackendContext) : IrElementTransformerVoidWithContext(), FileLoweringPass {
|
||||||
override fun lower(irClass: IrClass) {
|
|
||||||
|
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
|
if (irClass.descriptor.kind != ClassKind.OBJECT) return
|
||||||
|
|
||||||
val instanceFieldDescriptor = context.specialDescriptorsFactory.getFieldDescriptorForObjectInstance(irClass.descriptor)
|
val instanceFieldDescriptor = context.specialDescriptorsFactory.getFieldDescriptorForObjectInstance(irClass.descriptor)
|
||||||
|
|
||||||
val constructor = irClass.descriptor.unsubstitutedPrimaryConstructor ?:
|
val constructor = irClass.descriptor.unsubstitutedPrimaryConstructor ?:
|
||||||
throw AssertionError("Object should have a primary constructor: ${irClass.descriptor}")
|
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(
|
val instanceField = IrFieldImpl(
|
||||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET, JvmLoweredDeclarationOrigin.FIELD_FOR_OBJECT_INSTANCE,
|
UNDEFINED_OFFSET, UNDEFINED_OFFSET, JvmLoweredDeclarationOrigin.FIELD_FOR_OBJECT_INSTANCE,
|
||||||
instanceFieldDescriptor,
|
instanceFieldDescriptor,
|
||||||
IrExpressionBodyImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, instanceInitializer)
|
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