From c224394dfce7099f9192c85784269049879f1d3c Mon Sep 17 00:00:00 2001 From: Ilya Goncharov Date: Fri, 13 Nov 2020 11:25:01 +0300 Subject: [PATCH] [JS IR] Return with createdOn hack ^KT-43222 fixed [JS IR] Not create initialisation function for file if there were attempt to create it earlier ^KT-43222 fixed [JS IR] Pureness for PIR and memoize file fields pureness ^KT-43222 fixed --- .../ir/backend/js/JsIrBackendContext.kt | 3 +- .../js/lower/PropertyLazyInitLowering.kt | 68 ++++++++++++------- 2 files changed, 45 insertions(+), 26 deletions(-) diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsIrBackendContext.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsIrBackendContext.kt index 840628e12c3..d4ba2a1b836 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsIrBackendContext.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsIrBackendContext.kt @@ -45,7 +45,8 @@ class JsIrBackendContext( override val scriptMode: Boolean = false, override val es6mode: Boolean = false ) : JsCommonBackendContext { - val fileToInitialisationFuns: MutableMap = mutableMapOf() + val fileToInitialisationFuns: MutableMap = mutableMapOf() + val fileToPurenessInitializers: MutableMap = mutableMapOf() override val extractedLocalClasses: MutableSet = hashSetOf() diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/PropertyLazyInitLowering.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/PropertyLazyInitLowering.kt index 8ee9c1194cd..61e682e40cc 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/PropertyLazyInitLowering.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/PropertyLazyInitLowering.kt @@ -12,14 +12,13 @@ import org.jetbrains.kotlin.descriptors.DescriptorVisibilities.INTERNAL import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext -import org.jetbrains.kotlin.ir.backend.js.JsLoweredDeclarationOrigin import org.jetbrains.kotlin.ir.backend.js.ir.JsIrArithBuilder import org.jetbrains.kotlin.ir.backend.js.ir.JsIrBuilder import org.jetbrains.kotlin.ir.backend.js.utils.isPure import org.jetbrains.kotlin.ir.builders.declarations.addFunction import org.jetbrains.kotlin.ir.builders.declarations.buildField import org.jetbrains.kotlin.ir.declarations.* -import org.jetbrains.kotlin.ir.declarations.persistent.carriers.DeclarationCarrier +import org.jetbrains.kotlin.ir.declarations.persistent.PersistentIrElementBase import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.name.Name import kotlin.collections.component1 @@ -40,6 +39,9 @@ class PropertyLazyInitLowering( val fileToInitialisationFuns get() = context.fileToInitialisationFuns + val fileToPurenessInitializers + get() = context.fileToPurenessInitializers + override fun lower(irBody: IrBody, container: IrDeclaration) { if (container !is IrSimpleFunction && container !is IrField && container !is IrProperty) return @@ -49,9 +51,13 @@ class PropertyLazyInitLowering( val file = container.parent as? IrFile ?: return - val initFun = fileToInitialisationFuns[file] - ?: createInitialisationFunction(file)?.also { fileToInitialisationFuns[file] = it } - ?: return + val initFun = (if (file in fileToInitialisationFuns) { + fileToInitialisationFuns[file] + } else { + createInitialisationFunction(file).also { + fileToInitialisationFuns[file] = it + } + }) ?: return val initialisationCall = JsIrBuilder.buildCall( target = initFun.symbol, @@ -80,7 +86,7 @@ class PropertyLazyInitLowering( ): IrSimpleFunction? { val fileName = file.name - val declarations = ArrayList(file.declarations) + val declarations = file.declarations.toList() val fieldToInitializer = calculateFieldToExpression( declarations @@ -88,9 +94,10 @@ class PropertyLazyInitLowering( if (fieldToInitializer.isEmpty()) return null -// if (allFieldsInFilePure(fieldToInitializer.values)) { -// return null -// } + val allFieldsInFilePure = allFieldsInFilePure(fieldToInitializer.values) + if (allFieldsInFilePure) { + return null + } val initialisedField = irFactory.createInitialisationField(fileName) .apply { @@ -202,18 +209,22 @@ class RemoveInitializersForLazyProperties( private val context: JsIrBackendContext ) : DeclarationTransformer { - val fileToInitialisationFuns - get() = context.fileToInitialisationFuns + val fileToPurenessInitializers + get() = context.fileToPurenessInitializers override fun transformFlat(declaration: IrDeclaration): List? { -// val file = declaration.parent as? IrFile ?: return null -// val declarations = ArrayList(file.declarations) -// -// val fields = calculateFieldToExpression(declarations).values -// -// if (allFieldsInFilePure(fields)) { -// return null -// } + if (declaration !is IrField) return null + + val file = declaration.parent as? IrFile ?: return null + + if (fileToPurenessInitializers[file] == true) return null + + val allFieldsInFilePure = fileToPurenessInitializers[file] + ?: calculateFileFieldsPureness(file) + + if (allFieldsInFilePure) { + return null + } declaration.correspondingProperty ?.takeIf { it.isForLazyInit() } @@ -222,6 +233,16 @@ class RemoveInitializersForLazyProperties( return null } + + private fun calculateFileFieldsPureness(file: IrFile): Boolean { + val declarations = file.declarations.toList() + val expressions = calculateFieldToExpression(declarations) + .values + + val allFieldsInFilePure = allFieldsInFilePure(expressions) + fileToPurenessInitializers[file] = allFieldsInFilePure + return allFieldsInFilePure + } } private fun calculateFieldToExpression(declarations: Collection): Map = @@ -243,11 +264,6 @@ private val IrDeclaration.correspondingProperty: IrProperty? if (this !is IrSimpleFunction && this !is IrField && this !is IrProperty) return null - // Objects are in fact fields and we need to ignore them - val originField = (this as? DeclarationCarrier)?.originField - if (originField == JsLoweredDeclarationOrigin.OBJECT_GET_INSTANCE_FUNCTION || originField == IrDeclarationOrigin.FIELD_FOR_OBJECT_INSTANCE) - return null - return when (this) { is IrProperty -> this is IrSimpleFunction -> propertyWithPersistentSafe { @@ -261,4 +277,6 @@ private val IrDeclaration.correspondingProperty: IrProperty? } private fun IrDeclaration.propertyWithPersistentSafe(transform: IrDeclaration.() -> IrProperty?): IrProperty? = - transform() \ No newline at end of file + if (((this as? PersistentIrElementBase<*>)?.createdOn ?: 0) <= stageController.currentStage) { + transform() + } else null \ No newline at end of file