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