[JS IR] Add init properties call to top level functions

^KT-43222 fixed
This commit is contained in:
Ilya Goncharov
2020-10-28 13:15:04 +03:00
parent 5746a7c4fc
commit 841118a64d
@@ -33,19 +33,12 @@ class PropertyLazyInitLowering(private val context: JsIrBackendContext) : FileLo
get() = context.irFactory get() = context.irFactory
override fun lower(irFile: IrFile) { override fun lower(irFile: IrFile) {
val properties = PropertySearcher() val functions = TopLevelFunsSearcher()
.search(irFile) .search(irFile)
val fieldToInitializer = properties val fieldToInitializer = calculateFieldToExpression(
.asSequence() functions
.filterNot { it.isDelegated } ).onEach { it.key.initializer = null }
.mapNotNull { it.backingField }
.filter { it.initializer != null }
.map {
it to it.initializer!!.expression
}
.toMap()
.onEach { it.key.initializer = null }
if (fieldToInitializer.isEmpty()) return if (fieldToInitializer.isEmpty()) return
@@ -56,7 +49,7 @@ class PropertyLazyInitLowering(private val context: JsIrBackendContext) : FileLo
parent = irFile parent = irFile
} }
val initialiseFun = irFactory.addFunction(irFile) { val initialisationFun = irFactory.addFunction(irFile) {
name = Name.identifier("init properties $fileName") name = Name.identifier("init properties $fileName")
returnType = irBuiltIns.unitType returnType = irBuiltIns.unitType
origin = JsIrBuilder.SYNTHESIZED_DECLARATION origin = JsIrBuilder.SYNTHESIZED_DECLARATION
@@ -67,13 +60,12 @@ class PropertyLazyInitLowering(private val context: JsIrBackendContext) : FileLo
) )
} }
properties functions
.asSequence() .asSequence()
.flatMap { sequenceOf(it.getter, it.setter) }
.filterNotNull() .filterNotNull()
.forEach { function -> .forEach { function ->
val newBody = function.body?.let { body -> val newBody = function.body?.let { body ->
irFactory.bodyWithFunctionCall(body, initialiseFun) irFactory.bodyWithFunctionCall(body, initialisationFun)
} }
function.body = newBody function.body = newBody
} }
@@ -125,6 +117,20 @@ class PropertyLazyInitLowering(private val context: JsIrBackendContext) : FileLo
} }
} }
private fun calculateFieldToExpression(functions: Collection<IrSimpleFunction>): Map<IrField, IrExpression> =
functions
.asSequence()
.mapNotNull { it.correspondingPropertySymbol }
.map { it.owner }
.filter { it.isTopLevel }
.filterNot { it.isConst }
.distinct()
.filterNot { it.isDelegated }
.mapNotNull { it.backingField }
.filter { it.initializer != null }
.map { it to it.initializer!!.expression }
.toMap()
private fun createIrGetField(field: IrField): IrGetField { private fun createIrGetField(field: IrField): IrGetField {
return JsIrBuilder.buildGetField( return JsIrBuilder.buildGetField(
symbol = field.symbol, symbol = field.symbol,
@@ -155,25 +161,20 @@ private fun IrFactory.bodyWithFunctionCall(
).apply { addAll(body.statements) } ).apply { addAll(body.statements) }
) )
private class PropertySearcher : IrElementTransformerVoid() { private class TopLevelFunsSearcher : IrElementTransformerVoid() {
private val propertyToFunction = mutableSetOf<IrProperty>() private val topLevelFuns = mutableSetOf<IrSimpleFunction>()
fun search(irFile: IrFile): Set<IrProperty> { fun search(irFile: IrFile): Set<IrSimpleFunction> {
irFile.transformChildrenVoid(this) irFile.transformChildrenVoid(this)
return propertyToFunction return topLevelFuns
} }
override fun visitSimpleFunction(declaration: IrSimpleFunction): IrStatement { override fun visitSimpleFunction(declaration: IrSimpleFunction): IrStatement {
declaration.correspondingPropertySymbol if (declaration.isTopLevel) {
?.owner topLevelFuns.add(declaration)
?.takeIf { it.isTopLevel } }
?.takeIf { !it.isConst }
?.takeIf { it !in propertyToFunction }
?.let {
propertyToFunction.add(it)
}
return super.visitSimpleFunction(declaration) return super.visitSimpleFunction(declaration)
} }