[JS IR] - Remove file lowering declarations from lowering phases
- rename fileToPurenessInitializers onto fileToInitializerPureness - remove redundant check on top-level property [JS IR] Rename initialis* to initializ* for consistency [JS IR] Move propertyLazyInitialization property to context from configuration [JS IR] Add test on lazy initialization properties order [JS IR] Add multi module for lazy initialization of properties [JS IR] Move tests onto js.translator [JS IR] Rename fileToInitializerPureness according to context name ^KT-43222 fixed
This commit is contained in:
+2
-2
@@ -125,8 +125,8 @@ class K2JSCompilerArguments : CommonCompilerArguments() {
|
||||
@Argument(value = "-Xir-dce-print-reachability-info", description = "Print declarations' reachability info to stdout during performing DCE")
|
||||
var irDcePrintReachabilityInfo: Boolean by FreezableVar(false)
|
||||
|
||||
@Argument(value = "-Xir-property-lazy-initialisation", description = "Perform lazy initialisation for properties")
|
||||
var irPropertyLazyInitialisation: Boolean by FreezableVar(false)
|
||||
@Argument(value = "-Xir-property-lazy-initialization", description = "Perform lazy initialization for properties")
|
||||
var irPropertyLazyInitialization: Boolean by FreezableVar(false)
|
||||
|
||||
@Argument(value = "-Xir-only", description = "Disables pre-IR backend")
|
||||
var irOnly: Boolean by FreezableVar(false)
|
||||
|
||||
@@ -159,11 +159,6 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
|
||||
arguments.irModuleName ?: FileUtil.getNameWithoutExtension(outputFile)
|
||||
)
|
||||
|
||||
configurationJs.put(
|
||||
JSConfigurationKeys.PROPERTY_LAZY_INITIALISATION,
|
||||
arguments.irPropertyLazyInitialisation
|
||||
)
|
||||
|
||||
// TODO: in this method at least 3 different compiler configurations are used (original, env.configuration, jsConfig.configuration)
|
||||
// Such situation seems a bit buggy...
|
||||
val config = JsConfig(projectJs, configurationJs)
|
||||
@@ -269,7 +264,8 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
|
||||
generateDceJs = arguments.irDce,
|
||||
dceDriven = arguments.irDceDriven,
|
||||
multiModule = arguments.irPerModule,
|
||||
relativeRequirePath = true
|
||||
relativeRequirePath = true,
|
||||
propertyLazyInitialization = arguments.irPropertyLazyInitialization,
|
||||
)
|
||||
} catch (e: JsIrCompilationError) {
|
||||
return COMPILATION_ERROR
|
||||
|
||||
Generated
-5
@@ -21373,11 +21373,6 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/properties/kt9603.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("lazyInitialization.kt")
|
||||
public void testLazyInitialization() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/properties/lazyInitialization.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("primitiveOverrideDefaultAccessor.kt")
|
||||
public void testPrimitiveOverrideDefaultAccessor() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/properties/primitiveOverrideDefaultAccessor.kt");
|
||||
|
||||
@@ -43,10 +43,11 @@ class JsIrBackendContext(
|
||||
val additionalExportedDeclarationNames: Set<FqName>,
|
||||
override val configuration: CompilerConfiguration, // TODO: remove configuration from backend context
|
||||
override val scriptMode: Boolean = false,
|
||||
override val es6mode: Boolean = false
|
||||
override val es6mode: Boolean = false,
|
||||
val propertyLazyInitialization: Boolean = false,
|
||||
) : JsCommonBackendContext {
|
||||
val fileToInitialisationFuns: MutableMap<IrFile, IrSimpleFunction?> = mutableMapOf()
|
||||
val fileToPurenessInitializers: MutableMap<IrFile, Boolean> = mutableMapOf()
|
||||
val fileToInitializationFuns: MutableMap<IrFile, IrSimpleFunction?> = mutableMapOf()
|
||||
val fileToInitializerPureness: MutableMap<IrFile, Boolean> = mutableMapOf()
|
||||
|
||||
override val extractedLocalClasses: MutableSet<IrClass> = hashSetOf()
|
||||
|
||||
|
||||
@@ -109,16 +109,6 @@ class ModuleLowering(
|
||||
override val modulePhase: NamedCompilerPhase<JsIrBackendContext, Iterable<IrModuleFragment>>
|
||||
) : Lowering(name)
|
||||
|
||||
class FileLowering(
|
||||
name: String,
|
||||
description: String,
|
||||
prerequisite: Set<NamedCompilerPhase<JsIrBackendContext, *>> = emptySet(),
|
||||
private val factory: (JsIrBackendContext) -> FileLoweringPass
|
||||
) : Lowering(name) {
|
||||
override val modulePhase: NamedCompilerPhase<JsIrBackendContext, Iterable<IrModuleFragment>> =
|
||||
makeJsModulePhase(factory, name, description, prerequisite)
|
||||
}
|
||||
|
||||
private fun makeDeclarationTransformerPhase(
|
||||
lowering: (JsIrBackendContext) -> DeclarationTransformer,
|
||||
name: String,
|
||||
@@ -133,13 +123,6 @@ private fun makeBodyLoweringPhase(
|
||||
prerequisite: Set<Lowering> = emptySet()
|
||||
) = BodyLowering(name, description, prerequisite.map { it.modulePhase }.toSet(), lowering)
|
||||
|
||||
private fun makeFileLoweringPhase(
|
||||
lowering: (JsIrBackendContext) -> FileLoweringPass,
|
||||
name: String,
|
||||
description: String,
|
||||
prerequisite: Set<Lowering> = emptySet()
|
||||
) = FileLowering(name, description, prerequisite.map { it.modulePhase }.toSet(), lowering)
|
||||
|
||||
fun NamedCompilerPhase<JsIrBackendContext, Iterable<IrModuleFragment>>.toModuleLowering() = ModuleLowering(this.name, this)
|
||||
|
||||
private val validateIrBeforeLowering = makeCustomJsModulePhase(
|
||||
@@ -378,7 +361,7 @@ private val propertyLazyInitLoweringPhase = makeBodyLoweringPhase(
|
||||
private val removeInitializersForLazyProperties = makeDeclarationTransformerPhase(
|
||||
::RemoveInitializersForLazyProperties,
|
||||
name = "RemoveInitializersForLazyProperties",
|
||||
description = "Remove property initializers if they was initialised lazily"
|
||||
description = "Remove property initializers if they was initialized lazily"
|
||||
)
|
||||
|
||||
private val propertyAccessorInlinerLoweringPhase = makeBodyLoweringPhase(
|
||||
|
||||
@@ -48,7 +48,8 @@ fun compile(
|
||||
dceDriven: Boolean = false,
|
||||
es6mode: Boolean = false,
|
||||
multiModule: Boolean = false,
|
||||
relativeRequirePath: Boolean = false
|
||||
relativeRequirePath: Boolean = false,
|
||||
propertyLazyInitialization: Boolean,
|
||||
): CompilerResult {
|
||||
stageController = StageController()
|
||||
|
||||
@@ -62,7 +63,16 @@ fun compile(
|
||||
is MainModule.Klib -> dependencyModules
|
||||
}
|
||||
|
||||
val context = JsIrBackendContext(moduleDescriptor, irBuiltIns, symbolTable, allModules.first(), exportedDeclarations, configuration, es6mode = es6mode)
|
||||
val context = JsIrBackendContext(
|
||||
moduleDescriptor,
|
||||
irBuiltIns,
|
||||
symbolTable,
|
||||
allModules.first(),
|
||||
exportedDeclarations,
|
||||
configuration,
|
||||
es6mode = es6mode,
|
||||
propertyLazyInitialization = propertyLazyInitialization,
|
||||
)
|
||||
|
||||
// Load declarations referenced during `context` initialization
|
||||
val irProviders = listOf(deserializer)
|
||||
|
||||
+30
-33
@@ -20,7 +20,6 @@ import org.jetbrains.kotlin.ir.builders.declarations.buildField
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.declarations.persistent.PersistentIrElementBase
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.js.config.JSConfigurationKeys.PROPERTY_LAZY_INITIALISATION
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import kotlin.collections.component1
|
||||
import kotlin.collections.component2
|
||||
@@ -37,43 +36,41 @@ class PropertyLazyInitLowering(
|
||||
private val irFactory
|
||||
get() = context.irFactory
|
||||
|
||||
val fileToInitialisationFuns
|
||||
get() = context.fileToInitialisationFuns
|
||||
private val fileToInitializationFuns
|
||||
get() = context.fileToInitializationFuns
|
||||
|
||||
val fileToPurenessInitializers
|
||||
get() = context.fileToPurenessInitializers
|
||||
private val fileToInitializerPureness
|
||||
get() = context.fileToInitializerPureness
|
||||
|
||||
override fun lower(irBody: IrBody, container: IrDeclaration) {
|
||||
if (context.configuration[PROPERTY_LAZY_INITIALISATION] != true) {
|
||||
if (!context.propertyLazyInitialization) {
|
||||
return
|
||||
}
|
||||
|
||||
if (container !is IrSimpleFunction && container !is IrField && container !is IrProperty)
|
||||
return
|
||||
|
||||
if (!container.isTopLevel) return
|
||||
|
||||
val file = container.parent as? IrFile
|
||||
?: return
|
||||
|
||||
val initFun = (when {
|
||||
file in fileToInitialisationFuns -> fileToInitialisationFuns[file]
|
||||
fileToPurenessInitializers[file] == true -> null
|
||||
file in fileToInitializationFuns -> fileToInitializationFuns[file]
|
||||
fileToInitializerPureness[file] == true -> null
|
||||
else -> {
|
||||
createInitialisationFunction(file).also {
|
||||
fileToInitialisationFuns[file] = it
|
||||
createInitializationFunction(file).also {
|
||||
fileToInitializationFuns[file] = it
|
||||
}
|
||||
}
|
||||
}) ?: return
|
||||
|
||||
val initialisationCall = JsIrBuilder.buildCall(
|
||||
val initializationCall = JsIrBuilder.buildCall(
|
||||
target = initFun.symbol,
|
||||
type = initFun.returnType
|
||||
)
|
||||
|
||||
when (container) {
|
||||
is IrSimpleFunction ->
|
||||
irBody.addInitialisation(initialisationCall, container)
|
||||
irBody.addInitialization(initializationCall, container)
|
||||
is IrField -> {
|
||||
container
|
||||
.correspondingProperty
|
||||
@@ -82,13 +79,13 @@ class PropertyLazyInitLowering(
|
||||
?.let { listOf(it.getter, it.setter) }
|
||||
?.filterNotNull()
|
||||
?.forEach {
|
||||
irBody.addInitialisation(initialisationCall, it)
|
||||
irBody.addInitialization(initializationCall, it)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun createInitialisationFunction(
|
||||
private fun createInitializationFunction(
|
||||
file: IrFile
|
||||
): IrSimpleFunction? {
|
||||
val fileName = file.name
|
||||
@@ -102,12 +99,12 @@ class PropertyLazyInitLowering(
|
||||
if (fieldToInitializer.isEmpty()) return null
|
||||
|
||||
val allFieldsInFilePure = allFieldsInFilePure(fieldToInitializer.values)
|
||||
fileToPurenessInitializers[file] = allFieldsInFilePure
|
||||
fileToInitializerPureness[file] = allFieldsInFilePure
|
||||
if (allFieldsInFilePure) {
|
||||
return null
|
||||
}
|
||||
|
||||
val initialisedField = irFactory.createInitialisationField(fileName)
|
||||
val initializedField = irFactory.createInitializationField(fileName)
|
||||
.apply {
|
||||
file.declarations.add(this)
|
||||
parent = file
|
||||
@@ -121,14 +118,14 @@ class PropertyLazyInitLowering(
|
||||
}.apply {
|
||||
buildPropertiesInitializationBody(
|
||||
fieldToInitializer,
|
||||
initialisedField
|
||||
initializedField
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun IrFactory.createInitialisationField(fileName: String): IrField =
|
||||
private fun IrFactory.createInitializationField(fileName: String): IrField =
|
||||
buildField {
|
||||
name = Name.identifier("properties initialised $fileName")
|
||||
name = Name.identifier("properties initialized $fileName")
|
||||
type = irBuiltIns.booleanType
|
||||
isStatic = true
|
||||
isFinal = true
|
||||
@@ -137,18 +134,18 @@ class PropertyLazyInitLowering(
|
||||
|
||||
private fun IrSimpleFunction.buildPropertiesInitializationBody(
|
||||
initializers: Map<IrField, IrExpression>,
|
||||
initialisedField: IrField
|
||||
initializedField: IrField
|
||||
) {
|
||||
body = irFactory.createBlockBody(
|
||||
UNDEFINED_OFFSET,
|
||||
UNDEFINED_OFFSET,
|
||||
buildBodyWithIfGuard(initializers, initialisedField)
|
||||
buildBodyWithIfGuard(initializers, initializedField)
|
||||
)
|
||||
}
|
||||
|
||||
private fun buildBodyWithIfGuard(
|
||||
initializers: Map<IrField, IrExpression>,
|
||||
initialisedField: IrField
|
||||
initializedField: IrField
|
||||
): List<IrStatement> {
|
||||
val statements = initializers
|
||||
.map { (field, expression) ->
|
||||
@@ -156,13 +153,13 @@ class PropertyLazyInitLowering(
|
||||
}
|
||||
|
||||
val upGuard = createIrSetField(
|
||||
initialisedField,
|
||||
initializedField,
|
||||
JsIrBuilder.buildBoolean(context.irBuiltIns.booleanType, true)
|
||||
)
|
||||
|
||||
return JsIrBuilder.buildIfElse(
|
||||
type = irBuiltIns.unitType,
|
||||
cond = calculator.not(createIrGetField(initialisedField)),
|
||||
cond = calculator.not(createIrGetField(initializedField)),
|
||||
thenBranch = JsIrBuilder.buildComposite(
|
||||
type = irBuiltIns.unitType,
|
||||
statements = mutableListOf(upGuard).apply { addAll(statements) }
|
||||
@@ -171,7 +168,7 @@ class PropertyLazyInitLowering(
|
||||
}
|
||||
}
|
||||
|
||||
private fun IrBody.addInitialisation(
|
||||
private fun IrBody.addInitialization(
|
||||
initCall: IrCall,
|
||||
container: IrSimpleFunction
|
||||
) {
|
||||
@@ -217,11 +214,11 @@ class RemoveInitializersForLazyProperties(
|
||||
private val context: JsIrBackendContext
|
||||
) : DeclarationTransformer {
|
||||
|
||||
val fileToPurenessInitializers
|
||||
get() = context.fileToPurenessInitializers
|
||||
private val fileToInitializerPureness
|
||||
get() = context.fileToInitializerPureness
|
||||
|
||||
override fun transformFlat(declaration: IrDeclaration): List<IrDeclaration>? {
|
||||
if (context.configuration[PROPERTY_LAZY_INITIALISATION] != true) {
|
||||
if (!context.propertyLazyInitialization) {
|
||||
return null
|
||||
}
|
||||
|
||||
@@ -229,9 +226,9 @@ class RemoveInitializersForLazyProperties(
|
||||
|
||||
val file = declaration.parent as? IrFile ?: return null
|
||||
|
||||
if (fileToPurenessInitializers[file] == true) return null
|
||||
if (fileToInitializerPureness[file] == true) return null
|
||||
|
||||
val allFieldsInFilePure = fileToPurenessInitializers[file]
|
||||
val allFieldsInFilePure = fileToInitializerPureness[file]
|
||||
?: calculateFileFieldsPureness(file)
|
||||
|
||||
if (allFieldsInFilePure) {
|
||||
@@ -252,7 +249,7 @@ class RemoveInitializersForLazyProperties(
|
||||
.values
|
||||
|
||||
val allFieldsInFilePure = allFieldsInFilePure(expressions)
|
||||
fileToPurenessInitializers[file] = allFieldsInFilePure
|
||||
fileToInitializerPureness[file] = allFieldsInFilePure
|
||||
return allFieldsInFilePure
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -18,8 +18,8 @@ where advanced options include:
|
||||
-Xir-produce-klib-dir Generate unpacked KLIB into parent directory of output JS file.
|
||||
In combination with -meta-info generates both IR and pre-IR versions of library.
|
||||
-Xir-produce-klib-file Generate packed klib into file specified by -output. Disables pre-IR backend
|
||||
-Xir-property-lazy-initialisation
|
||||
Perform lazy initialisation for properties
|
||||
-Xir-property-lazy-initialization
|
||||
Perform lazy initialization for properties
|
||||
-Xmetadata-only Generate *.meta.js and *.kjsm files only
|
||||
-Xtyped-arrays Translate primitive arrays to JS typed arrays
|
||||
-Xwasm Use experimental WebAssembly compiler backend
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
// IGNORE_BACKEND: JS, NATIVE
|
||||
// DONT_TARGET_EXACT_BACKEND: WASM
|
||||
// PROPERTY_LAZY_INITIALISATION
|
||||
|
||||
// FILE: A.kt
|
||||
|
||||
val o = "O"
|
||||
|
||||
// FILE: B.kt
|
||||
val ok = o + k
|
||||
|
||||
// FILE: C.kt
|
||||
|
||||
val k = "K"
|
||||
|
||||
// FILE: main.kt
|
||||
|
||||
fun box(): String = ok
|
||||
@@ -1,32 +0,0 @@
|
||||
// TARGET_BACKEND: JS_IR
|
||||
// PROPERTY_LAZY_INITIALISATION
|
||||
|
||||
// FILE: A.kt
|
||||
|
||||
val a = "A"
|
||||
|
||||
// FILE: B.kt
|
||||
val b = "B".apply {}
|
||||
|
||||
val c = b
|
||||
|
||||
// FILE: C.kt
|
||||
val d = "D".apply {}
|
||||
|
||||
val e = d
|
||||
|
||||
// FILE: main.kt
|
||||
|
||||
fun box(): String {
|
||||
d
|
||||
e
|
||||
return if (
|
||||
js("a") === "A" &&
|
||||
js("typeof b") == "undefined" &&
|
||||
js("typeof c") == "undefined" &&
|
||||
js("d") === "D" &&
|
||||
js("e") === "D"
|
||||
)
|
||||
"OK"
|
||||
else "a = ${js("a")}; typeof b = ${js("typeof b")}; typeof c = ${js("typeof c")}; d = ${js("d")}; e = ${js("e")}"
|
||||
}
|
||||
-5
@@ -23144,11 +23144,6 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
runTest("compiler/testData/codegen/box/properties/kt9603.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("lazyInitialization.kt")
|
||||
public void testLazyInitialization() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/properties/lazyInitialization.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("primitiveOverrideDefaultAccessor.kt")
|
||||
public void testPrimitiveOverrideDefaultAccessor() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/properties/primitiveOverrideDefaultAccessor.kt");
|
||||
|
||||
-5
@@ -23149,11 +23149,6 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
runTest("compiler/testData/codegen/box/properties/kt9603.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("lazyInitialization.kt")
|
||||
public void testLazyInitialization() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/properties/lazyInitialization.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("primitiveOverrideDefaultAccessor.kt")
|
||||
public void testPrimitiveOverrideDefaultAccessor() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/properties/primitiveOverrideDefaultAccessor.kt");
|
||||
|
||||
-5
@@ -21373,11 +21373,6 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
runTest("compiler/testData/codegen/box/properties/kt9603.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("lazyInitialization.kt")
|
||||
public void testLazyInitialization() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/properties/lazyInitialization.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("primitiveOverrideDefaultAccessor.kt")
|
||||
public void testPrimitiveOverrideDefaultAccessor() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/properties/primitiveOverrideDefaultAccessor.kt");
|
||||
|
||||
Reference in New Issue
Block a user