This commit is contained in:
Igor Chevdar
2021-09-28 15:08:57 +05:00
committed by Space
parent 6ee1599efa
commit 75d2757d3c
@@ -39,6 +39,7 @@ internal class InitializersLowering(val context: CommonBackendContext) : ClassLo
private inner class InitializersTransformer(val irClass: IrClass) {
val initializers = mutableListOf<IrStatement>()
val constInitializers = mutableListOf<IrStatement>()
fun lowerInitializers() {
collectAndRemoveInitializers()
@@ -65,30 +66,29 @@ internal class InitializersLowering(val context: CommonBackendContext) : ClassLo
val startOffset = initializer.startOffset
val endOffset = initializer.endOffset
val initExpression = initializer.expression
initializers.add(IrBlockImpl(startOffset, endOffset,
context.irBuiltIns.unitType,
IrStatementOrigin.INITIALIZE_FIELD,
listOf(
IrSetFieldImpl(startOffset, endOffset, declaration.symbol,
IrGetValueImpl(
startOffset, endOffset,
irClass.thisReceiver!!.type, irClass.thisReceiver!!.symbol
),
initExpression,
context.irBuiltIns.unitType,
IrStatementOrigin.INITIALIZE_FIELD)))
val isConst = declaration.correspondingPropertySymbol?.owner?.isConst == true
if (isConst)
require(initExpression is IrConst<*>) { "Const val can only be initialized with a const: ${declaration.render()}" }
(if (isConst) constInitializers else initializers).add(
IrBlockImpl(startOffset, endOffset,
context.irBuiltIns.unitType,
IrStatementOrigin.INITIALIZE_FIELD,
listOf(
IrSetFieldImpl(startOffset, endOffset, declaration.symbol,
IrGetValueImpl(
startOffset, endOffset,
irClass.thisReceiver!!.type, irClass.thisReceiver!!.symbol
),
initExpression,
context.irBuiltIns.unitType,
IrStatementOrigin.INITIALIZE_FIELD)))
)
// We shall keep initializer for constants for compile-time instantiation.
// We suppose that if the property is const, then its initializer is IrConst.
// If this requirement isn't satisfied, then PropertyAccessorInlineLowering can fail.
declaration.initializer =
if (initExpression is IrConst<*> &&
declaration.correspondingPropertySymbol?.owner?.isConst == true) {
IrExpressionBodyImpl(initExpression.shallowCopy())
} else {
null
}
declaration.initializer = if (isConst) IrExpressionBodyImpl(initExpression.shallowCopy()) else null
return declaration
}
})
@@ -104,6 +104,7 @@ internal class InitializersLowering(val context: CommonBackendContext) : ClassLo
if (irClass.declarations.any { it is IrConstructor && it.isPrimary })
return null // Place initializers in the primary constructor.
val allInitializers = constInitializers + initializers
val startOffset = irClass.startOffset
val endOffset = irClass.endOffset
val initializeFun =
@@ -129,10 +130,10 @@ internal class InitializersLowering(val context: CommonBackendContext) : ClassLo
createDispatchReceiverParameter()
body = IrBlockBodyImpl(startOffset, endOffset, initializers)
body = IrBlockBodyImpl(startOffset, endOffset, allInitializers)
}
for (initializer in initializers) {
for (initializer in allInitializers) {
initializer.transformChildrenVoid(object : IrElementTransformerVoid() {
override fun visitGetValue(expression: IrGetValue): IrExpression {
if (expression.symbol == irClass.thisReceiver!!.symbol) {
@@ -169,10 +170,11 @@ internal class InitializersLowering(val context: CommonBackendContext) : ClassLo
when {
it is IrInstanceInitializerCall -> {
if (initializeMethodSymbol == null) {
val allInitializers = constInitializers + initializers
assert(declaration.isPrimary)
for (initializer in initializers)
for (initializer in allInitializers)
initializer.setDeclarationsParent(declaration)
initializers
allInitializers
} else {
val startOffset = it.startOffset
val endOffset = it.endOffset