[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>>
|
||||
) : 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,
|
||||
@@ -123,6 +133,13 @@ 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(
|
||||
@@ -352,6 +369,12 @@ private val forLoopsLoweringPhase = makeBodyLoweringPhase(
|
||||
description = "[Optimization] For loops lowering"
|
||||
)
|
||||
|
||||
private val propertyLazyInitLoweringPhase = makeFileLoweringPhase(
|
||||
::PropertyLazyInitLowering,
|
||||
name = "PropertyLazyInitLowering",
|
||||
description = "Make property init as lazy"
|
||||
)
|
||||
|
||||
private val propertyAccessorInlinerLoweringPhase = makeBodyLoweringPhase(
|
||||
::PropertyAccessorInlineLowering,
|
||||
name = "PropertyAccessorInlineLowering",
|
||||
@@ -727,6 +750,7 @@ val loweringList = listOf<Lowering>(
|
||||
rangeContainsLoweringPhase,
|
||||
forLoopsLoweringPhase,
|
||||
primitiveCompanionLoweringPhase,
|
||||
propertyLazyInitLoweringPhase,
|
||||
propertyAccessorInlinerLoweringPhase,
|
||||
foldConstantLoweringPhase,
|
||||
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