[JS IR] Add init function for properties
^KT-43222 fixed
This commit is contained in:
@@ -109,6 +109,16 @@ class ModuleLowering(
|
|||||||
override val modulePhase: NamedCompilerPhase<JsIrBackendContext, Iterable<IrModuleFragment>>
|
override val modulePhase: NamedCompilerPhase<JsIrBackendContext, Iterable<IrModuleFragment>>
|
||||||
) : Lowering(name)
|
) : 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(
|
private fun makeDeclarationTransformerPhase(
|
||||||
lowering: (JsIrBackendContext) -> DeclarationTransformer,
|
lowering: (JsIrBackendContext) -> DeclarationTransformer,
|
||||||
name: String,
|
name: String,
|
||||||
@@ -123,6 +133,13 @@ private fun makeBodyLoweringPhase(
|
|||||||
prerequisite: Set<Lowering> = emptySet()
|
prerequisite: Set<Lowering> = emptySet()
|
||||||
) = BodyLowering(name, description, prerequisite.map { it.modulePhase }.toSet(), lowering)
|
) = 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)
|
fun NamedCompilerPhase<JsIrBackendContext, Iterable<IrModuleFragment>>.toModuleLowering() = ModuleLowering(this.name, this)
|
||||||
|
|
||||||
private val validateIrBeforeLowering = makeCustomJsModulePhase(
|
private val validateIrBeforeLowering = makeCustomJsModulePhase(
|
||||||
@@ -352,6 +369,12 @@ private val forLoopsLoweringPhase = makeBodyLoweringPhase(
|
|||||||
description = "[Optimization] For loops lowering"
|
description = "[Optimization] For loops lowering"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
private val propertyLazyInitLoweringPhase = makeFileLoweringPhase(
|
||||||
|
::PropertyLazyInitLowering,
|
||||||
|
name = "PropertyLazyInitLowering",
|
||||||
|
description = "Make property init as lazy"
|
||||||
|
)
|
||||||
|
|
||||||
private val propertyAccessorInlinerLoweringPhase = makeBodyLoweringPhase(
|
private val propertyAccessorInlinerLoweringPhase = makeBodyLoweringPhase(
|
||||||
::PropertyAccessorInlineLowering,
|
::PropertyAccessorInlineLowering,
|
||||||
name = "PropertyAccessorInlineLowering",
|
name = "PropertyAccessorInlineLowering",
|
||||||
@@ -727,6 +750,7 @@ val loweringList = listOf<Lowering>(
|
|||||||
rangeContainsLoweringPhase,
|
rangeContainsLoweringPhase,
|
||||||
forLoopsLoweringPhase,
|
forLoopsLoweringPhase,
|
||||||
primitiveCompanionLoweringPhase,
|
primitiveCompanionLoweringPhase,
|
||||||
|
propertyLazyInitLoweringPhase,
|
||||||
propertyAccessorInlinerLoweringPhase,
|
propertyAccessorInlinerLoweringPhase,
|
||||||
foldConstantLoweringPhase,
|
foldConstantLoweringPhase,
|
||||||
privateMembersLoweringPhase,
|
privateMembersLoweringPhase,
|
||||||
|
|||||||
+102
@@ -0,0 +1,102 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.ir.backend.js.lower
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
||||||
|
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.ir.JsIrBuilder
|
||||||
|
import org.jetbrains.kotlin.ir.builders.declarations.addFunction
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrField
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.IrBody
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.IrFieldAccessExpression
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.IrSetField
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.impl.IrSetFieldImpl
|
||||||
|
import org.jetbrains.kotlin.ir.util.kotlinFqName
|
||||||
|
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||||
|
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
|
||||||
|
class PropertyLazyInitLowering(private val context: JsIrBackendContext) : FileLoweringPass {
|
||||||
|
private val irBuiltIns
|
||||||
|
get() = context.irBuiltIns
|
||||||
|
|
||||||
|
override fun lower(irFile: IrFile) {
|
||||||
|
val initializers = PropertyInitializerMover(context).process(irFile)
|
||||||
|
val irFactory = context.irFactory
|
||||||
|
if (initializers.isNotEmpty()) {
|
||||||
|
irFactory.addFunction(irFile) {
|
||||||
|
name = Name.identifier("init properties ${irFile.kotlinFqName}")
|
||||||
|
returnType = irBuiltIns.unitType
|
||||||
|
origin = JsIrBuilder.SYNTHESIZED_DECLARATION
|
||||||
|
}.apply {
|
||||||
|
body = irFactory.createBlockBody(
|
||||||
|
UNDEFINED_OFFSET,
|
||||||
|
UNDEFINED_OFFSET,
|
||||||
|
initializers
|
||||||
|
.map { (field, expression) ->
|
||||||
|
createIrSetField(field, expression)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createIrSetField(field: IrField, expression: IrExpression): IrSetField {
|
||||||
|
return IrSetFieldImpl(
|
||||||
|
field.startOffset,
|
||||||
|
field.endOffset,
|
||||||
|
field.symbol,
|
||||||
|
null,
|
||||||
|
expression,
|
||||||
|
expression.type
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class PropertyInitializerMover(
|
||||||
|
private val context: JsIrBackendContext
|
||||||
|
) : IrElementTransformerVoid() {
|
||||||
|
|
||||||
|
private val fieldToInitializers = mutableListOf<Pair<IrField, IrExpression>>()
|
||||||
|
|
||||||
|
fun process(irFile: IrFile): List<Pair<IrField, IrExpression>> {
|
||||||
|
irFile.transformChildrenVoid(this)
|
||||||
|
return fieldToInitializers
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitSimpleFunction(declaration: IrSimpleFunction): IrStatement {
|
||||||
|
declaration.correspondingPropertySymbol
|
||||||
|
?.owner
|
||||||
|
?.takeIf { !it.isConst }
|
||||||
|
?.takeIf { !it.isDelegated }
|
||||||
|
?.backingField
|
||||||
|
?.takeIf { it.initializer != null }
|
||||||
|
?.let { field ->
|
||||||
|
fieldToInitializers.add(field to field.initializer!!.expression)
|
||||||
|
}
|
||||||
|
|
||||||
|
fieldToInitializers.forEach { it.first.initializer = null }
|
||||||
|
|
||||||
|
return super.visitSimpleFunction(declaration)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitFieldAccess(expression: IrFieldAccessExpression): IrExpression {
|
||||||
|
return super.visitFieldAccess(expression)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitField(declaration: IrField): IrStatement {
|
||||||
|
return super.visitField(declaration)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitBody(body: IrBody): IrBody {
|
||||||
|
return super.visitBody(body)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user