PrimaryConstructorLowering
This commit is contained in:
committed by
Anton Bannykh
parent
76ff30b86e
commit
f6d4ea469c
@@ -311,6 +311,13 @@ private val primaryConstructorLoweringPhase = makeJsModulePhase(
|
||||
prerequisite = setOf(enumClassConstructorLoweringPhase)
|
||||
)
|
||||
|
||||
private val delegateToPrimaryConstructorLoweringPhase = makeJsModulePhase(
|
||||
::DelegateToSyntheticPrimaryConstructor,
|
||||
name = "DelegateToSyntheticPrimaryConstructor",
|
||||
description = "Delegates to synthetic primary constructor",
|
||||
prerequisite = setOf(primaryConstructorLoweringPhase)
|
||||
)
|
||||
|
||||
private val annotationConstructorLowering = makeJsModulePhase(
|
||||
::AnnotationConstructorLowering,
|
||||
name = "AnnotationConstructorLowering",
|
||||
@@ -465,6 +472,7 @@ val jsPhases = namedIrModulePhase(
|
||||
innerClassConstructorCallsLoweringPhase then
|
||||
propertiesLoweringPhase then
|
||||
primaryConstructorLoweringPhase then
|
||||
delegateToPrimaryConstructorLoweringPhase then
|
||||
annotationConstructorLowering then
|
||||
initializersLoweringPhase then
|
||||
initializersCleanupLoweringPhase then
|
||||
|
||||
@@ -17,4 +17,5 @@ class JsMapping : DefaultMapping() {
|
||||
val secondaryConstructorToFactory = newMapping<IrConstructor, IrSimpleFunction>()
|
||||
val objectToGetInstanceFunction = newMapping<IrClass, IrSimpleFunction>()
|
||||
val objectToInstanceField = newMapping<IrClass, IrField>()
|
||||
val classToSyntheticPrimaryConstructor = newMapping<IrClass, IrConstructor>()
|
||||
}
|
||||
+37
-21
@@ -5,47 +5,42 @@
|
||||
|
||||
package org.jetbrains.kotlin.ir.backend.js.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.ClassLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.CommonBackendContext
|
||||
import org.jetbrains.kotlin.backend.common.BodyLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.DeclarationTransformer
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.ir.backend.js.JsCommonBackendContext
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.addConstructor
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrConstructor
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOriginImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.IrBody
|
||||
import org.jetbrains.kotlin.ir.expressions.IrInstanceInitializerCall
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrBlockBodyImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrDelegatingConstructorCallImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrInstanceInitializerCallImpl
|
||||
import org.jetbrains.kotlin.ir.util.parentAsClass
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
|
||||
|
||||
// Create primary constructor if it doesn't exist
|
||||
class PrimaryConstructorLowering(context: CommonBackendContext) : ClassLoweringPass {
|
||||
private val unitType = context.irBuiltIns.unitType
|
||||
class PrimaryConstructorLowering(context: JsCommonBackendContext) : DeclarationTransformer {
|
||||
|
||||
override fun lower(irClass: IrClass) {
|
||||
val constructors = irClass.declarations.filterIsInstance<IrConstructor>()
|
||||
private var IrClass.syntheticPrimaryConstructor by context.mapping.classToSyntheticPrimaryConstructor
|
||||
|
||||
if (constructors.any { it.isPrimary }) return
|
||||
override fun transformFlat(declaration: IrDeclaration): List<IrDeclaration>? {
|
||||
if (declaration is IrClass) {
|
||||
val constructors = declaration.declarations.filterIsInstance<IrConstructor>()
|
||||
|
||||
val primary = createPrimaryConstructor(irClass)
|
||||
if (constructors.any { it.isPrimary }) return null
|
||||
|
||||
val initializeTransformer = object : IrElementTransformerVoid() {
|
||||
override fun visitDeclaration(declaration: IrDeclaration) = declaration // optimize visiting
|
||||
|
||||
override fun visitInstanceInitializerCall(expression: IrInstanceInitializerCall) = expression.run {
|
||||
IrDelegatingConstructorCallImpl(startOffset, endOffset, type, primary.symbol)
|
||||
}
|
||||
declaration.syntheticPrimaryConstructor = createPrimaryConstructor(declaration)
|
||||
}
|
||||
|
||||
constructors.forEach { it.transformChildrenVoid(initializeTransformer) }
|
||||
return null
|
||||
}
|
||||
|
||||
private object SYNTHETIC_PRIMARY_CONSTRUCTOR : IrDeclarationOriginImpl("SYNTHETIC_PRIMARY_CONSTRUCTOR")
|
||||
|
||||
private val unitType = context.irBuiltIns.unitType
|
||||
|
||||
private fun createPrimaryConstructor(irClass: IrClass): IrConstructor {
|
||||
val declaration = irClass.addConstructor {
|
||||
origin = SYNTHETIC_PRIMARY_CONSTRUCTOR
|
||||
@@ -59,4 +54,25 @@ class PrimaryConstructorLowering(context: CommonBackendContext) : ClassLoweringP
|
||||
|
||||
return declaration
|
||||
}
|
||||
}
|
||||
|
||||
class DelegateToSyntheticPrimaryConstructor(context: JsCommonBackendContext) : BodyLoweringPass {
|
||||
|
||||
private var IrClass.syntheticPrimaryConstructor by context.mapping.classToSyntheticPrimaryConstructor
|
||||
|
||||
override fun lower(irBody: IrBody, container: IrDeclaration) {
|
||||
if (container is IrConstructor && !container.isPrimary) {
|
||||
container.parentAsClass.syntheticPrimaryConstructor?.let { primary ->
|
||||
val initializeTransformer = object : IrElementTransformerVoid() {
|
||||
override fun visitDeclaration(declaration: IrDeclaration) = declaration // optimize visiting
|
||||
|
||||
override fun visitInstanceInitializerCall(expression: IrInstanceInitializerCall) = expression.run {
|
||||
IrDelegatingConstructorCallImpl(startOffset, endOffset, type, primary.symbol)
|
||||
}
|
||||
}
|
||||
|
||||
irBody.transformChildrenVoid(initializeTransformer)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -228,6 +228,13 @@ private val primaryConstructorLoweringPhase = makeWasmModulePhase(
|
||||
description = "Creates primary constructor if it doesn't exist"
|
||||
)
|
||||
|
||||
private val delegateToPrimaryConstructorLoweringPhase = makeWasmModulePhase(
|
||||
::DelegateToSyntheticPrimaryConstructor,
|
||||
name = "DelegateToSyntheticPrimaryConstructor",
|
||||
description = "Delegates to synthetic primary constructor",
|
||||
prerequisite = setOf(primaryConstructorLoweringPhase)
|
||||
)
|
||||
|
||||
private val initializersLoweringPhase = makeWasmModulePhase(
|
||||
::InitializersLowering,
|
||||
name = "InitializersLowering",
|
||||
@@ -372,6 +379,7 @@ val wasmPhases = namedIrModulePhase<WasmBackendContext>(
|
||||
innerClassConstructorCallsLoweringPhase then
|
||||
propertiesLoweringPhase then
|
||||
primaryConstructorLoweringPhase then
|
||||
delegateToPrimaryConstructorLoweringPhase then
|
||||
initializersLoweringPhase then
|
||||
initializersCleanupLoweringPhase then
|
||||
// Common prefix ends
|
||||
|
||||
Reference in New Issue
Block a user