Refactor secondary constructor lowering using new builders
This commit is contained in:
+78
-148
@@ -6,25 +6,19 @@
|
||||
package org.jetbrains.kotlin.ir.backend.js.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
||||
import org.jetbrains.kotlin.descriptors.SourceElement
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.impl.LazyClassReceiverParameterDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
|
||||
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
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.descriptors.JsSymbolBuilder
|
||||
import org.jetbrains.kotlin.ir.backend.js.descriptors.initialize
|
||||
import org.jetbrains.kotlin.ir.backend.js.ir.JsIrBuilder
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.Namer
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.isPrimary
|
||||
import org.jetbrains.kotlin.ir.builders.*
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrValueParameterImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrBlockBodyImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrReturnImpl
|
||||
@@ -32,14 +26,11 @@ import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrValueParameterSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.util.deepCopyWithSymbols
|
||||
import org.jetbrains.kotlin.ir.util.transformFlat
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
class SecondaryCtorLowering(val context: JsIrBackendContext) : IrElementTransformerVoid(), FileLoweringPass {
|
||||
|
||||
@@ -125,142 +116,83 @@ class SecondaryCtorLowering(val context: JsIrBackendContext) : IrElementTransfor
|
||||
}
|
||||
}
|
||||
|
||||
private fun createInitConstructor(declaration: IrConstructor, name: String): IrSimpleFunction {
|
||||
// TODO delegate name generation
|
||||
val actualName = "${name}_\$Init\$"
|
||||
private fun createInitConstructor(declaration: IrConstructor, name: String): IrSimpleFunction =
|
||||
JsSymbolBuilder.copyFunctionSymbol(declaration.symbol, "${name}_\$Init\$").let {
|
||||
|
||||
//region TODO: get rid of descriptors and replace them with direct symbol creation
|
||||
val thisParamDesc = ValueParameterDescriptorImpl(
|
||||
declaration.descriptor,
|
||||
null,
|
||||
declaration.descriptor.valueParameters.size,
|
||||
Annotations.EMPTY,
|
||||
Name.identifier("\$this"),
|
||||
declaration.descriptor.returnType,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
null,
|
||||
SourceElement.NO_SOURCE
|
||||
)
|
||||
val thisSymbol =
|
||||
JsSymbolBuilder.buildValueParameter(it, declaration.valueParameters.size, declaration.returnType, "\$this")
|
||||
|
||||
val functionDescriptor = SimpleFunctionDescriptorImpl.create(
|
||||
declaration.descriptor.containingDeclaration,
|
||||
declaration.descriptor.annotations,
|
||||
Name.identifier(actualName),
|
||||
declaration.descriptor.kind,
|
||||
declaration.descriptor.source
|
||||
).initialize(
|
||||
null,
|
||||
declaration.descriptor.dispatchReceiverParameter,
|
||||
declaration.descriptor.typeParameters,
|
||||
declaration.descriptor.valueParameters + thisParamDesc,
|
||||
declaration.returnType,
|
||||
declaration.descriptor.modality,
|
||||
declaration.visibility
|
||||
)
|
||||
//endregion
|
||||
|
||||
|
||||
val thisSymbol = IrValueParameterSymbolImpl(thisParamDesc)
|
||||
val functionSymbol = IrSimpleFunctionSymbolImpl(functionDescriptor)
|
||||
|
||||
val thisParam = IrValueParameterImpl(
|
||||
UNDEFINED_OFFSET,
|
||||
UNDEFINED_OFFSET,
|
||||
JsLoweredDeclarationOrigin.SECONDARY_CTOR_RECEIVER,
|
||||
thisSymbol
|
||||
)
|
||||
|
||||
val constructor = IrFunctionImpl(
|
||||
declaration.startOffset, declaration.endOffset,
|
||||
declaration.origin, functionSymbol
|
||||
)
|
||||
|
||||
var statements = (declaration.body as IrStatementContainer).statements.map { it.deepCopyWithSymbols() }
|
||||
val fixer = ThisUsageReplaceTransformer(functionSymbol, thisSymbol)
|
||||
for (stmt in statements) {
|
||||
stmt.transformChildrenVoid(fixer)
|
||||
}
|
||||
|
||||
val retStmt = IrReturnImpl(
|
||||
UNDEFINED_OFFSET,
|
||||
UNDEFINED_OFFSET,
|
||||
functionSymbol,
|
||||
IrGetValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, thisSymbol)
|
||||
)
|
||||
|
||||
statements += retStmt
|
||||
val newBody = IrBlockBodyImpl(declaration.body!!.startOffset, declaration.body!!.endOffset, statements)
|
||||
|
||||
constructor.valueParameters += declaration.valueParameters
|
||||
constructor.typeParameters += declaration.typeParameters
|
||||
constructor.parent = declaration.parent
|
||||
constructor.valueParameters += thisParam
|
||||
constructor.body = newBody
|
||||
|
||||
return constructor
|
||||
}
|
||||
|
||||
|
||||
private fun createCreateConstructor(ctorOrig: IrConstructor, ctorImpl: IrSimpleFunction, name: String): IrSimpleFunction {
|
||||
// TODO delegate name generation
|
||||
val actualName = "${name}_\$Create\$"
|
||||
|
||||
//region TODO: descriptor -> symbol
|
||||
val functionDescriptor = SimpleFunctionDescriptorImpl.create(
|
||||
ctorOrig.descriptor,
|
||||
ctorOrig.descriptor.annotations,
|
||||
Name.identifier(actualName),
|
||||
ctorOrig.descriptor.kind,
|
||||
ctorOrig.descriptor.source
|
||||
).initialize(
|
||||
null,
|
||||
ctorOrig.descriptor.dispatchReceiverParameter,
|
||||
ctorOrig.descriptor.typeParameters,
|
||||
ctorOrig.descriptor.valueParameters,
|
||||
ctorOrig.returnType,
|
||||
ctorOrig.descriptor.modality,
|
||||
ctorOrig.visibility
|
||||
)
|
||||
//endregion
|
||||
|
||||
val functionSymbol = IrSimpleFunctionSymbolImpl(functionDescriptor)
|
||||
|
||||
val constructor = IrFunctionImpl(
|
||||
ctorOrig.startOffset, ctorOrig.endOffset,
|
||||
ctorOrig.origin, functionSymbol
|
||||
)
|
||||
|
||||
val createFunctionIntrinsic = context.intrinsics.jsObjectCreate
|
||||
val irBuilder = context.createIrBuilder(functionSymbol, ctorOrig.startOffset, ctorOrig.endOffset).irBlockBody {
|
||||
val thisVar = irTemporaryVar(
|
||||
IrCallImpl(
|
||||
startOffset,
|
||||
endOffset,
|
||||
ctorOrig.returnType,
|
||||
createFunctionIntrinsic.symbol,
|
||||
createFunctionIntrinsic.descriptor,
|
||||
mapOf(createFunctionIntrinsic.typeParameters[0].descriptor to ctorOrig.returnType)
|
||||
)
|
||||
it.initialize(
|
||||
dispatchParameterDescriptor = declaration.descriptor.dispatchReceiverParameter,
|
||||
typeParameters = declaration.descriptor.typeParameters,
|
||||
valueParameters = declaration.descriptor.valueParameters + thisSymbol.descriptor as ValueParameterDescriptor,
|
||||
type = declaration.descriptor.returnType,
|
||||
modality = declaration.descriptor.modality,
|
||||
visibility = declaration.descriptor.visibility
|
||||
)
|
||||
+irReturn(
|
||||
irCall(ctorImpl.symbol).apply {
|
||||
ctorOrig.valueParameters.forEachIndexed { index, irValueParameter ->
|
||||
putValueArgument(index, irGet(irValueParameter.symbol))
|
||||
}
|
||||
putValueArgument(ctorOrig.valueParameters.size, irGet(thisVar.symbol))
|
||||
|
||||
val thisParam = JsIrBuilder.buildValueParameter(thisSymbol)
|
||||
|
||||
return IrFunctionImpl(
|
||||
declaration.startOffset, declaration.endOffset,
|
||||
declaration.origin, it
|
||||
).apply {
|
||||
val retStmt = JsIrBuilder.buildReturn(it, JsIrBuilder.buildGetValue(thisSymbol))
|
||||
val statements = (declaration.body as IrStatementContainer).statements
|
||||
|
||||
valueParameters += (declaration.valueParameters + thisParam)
|
||||
typeParameters += declaration.typeParameters
|
||||
parent = declaration.parent
|
||||
body = JsIrBuilder.buildBlockBody(statements + retStmt).apply {
|
||||
transformChildrenVoid(ThisUsageReplaceTransformer(it, thisSymbol))
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
constructor.valueParameters += ctorOrig.valueParameters
|
||||
constructor.typeParameters += ctorOrig.typeParameters
|
||||
constructor.parent = ctorOrig.parent
|
||||
constructor.body = IrBlockBodyImpl(ctorOrig.body?.startOffset!!, ctorOrig.body?.endOffset!!, irBuilder.statements)
|
||||
|
||||
return constructor
|
||||
}
|
||||
private fun createCreateConstructor(ctorOrig: IrConstructor, ctorImpl: IrSimpleFunction, name: String): IrSimpleFunction =
|
||||
JsSymbolBuilder.copyFunctionSymbol(ctorOrig.symbol, "${name}_\$Create\$").let {
|
||||
it.initialize(
|
||||
dispatchParameterDescriptor = ctorOrig.descriptor.dispatchReceiverParameter,
|
||||
typeParameters = ctorOrig.descriptor.typeParameters,
|
||||
valueParameters = ctorOrig.descriptor.valueParameters,
|
||||
type = ctorOrig.returnType,
|
||||
modality = ctorOrig.descriptor.modality,
|
||||
visibility = ctorOrig.visibility
|
||||
)
|
||||
|
||||
return IrFunctionImpl(
|
||||
ctorOrig.startOffset, ctorOrig.endOffset,
|
||||
ctorOrig.origin, it
|
||||
).apply {
|
||||
|
||||
valueParameters += ctorOrig.valueParameters
|
||||
typeParameters += ctorOrig.typeParameters
|
||||
parent = ctorOrig.parent
|
||||
|
||||
val returnType = ctorOrig.returnType
|
||||
val createFunctionIntrinsic = context.intrinsics.jsObjectCreate
|
||||
val irCreateCall = JsIrBuilder.buildCall(
|
||||
createFunctionIntrinsic.symbol,
|
||||
returnType,
|
||||
mapOf(createFunctionIntrinsic.typeParameters[0].descriptor to returnType)
|
||||
)
|
||||
val irDelegateCall = JsIrBuilder.buildCall(ctorImpl.symbol).also {
|
||||
for (i in 0 until valueParameters.size) {
|
||||
it.putValueArgument(i, JsIrBuilder.buildGetValue(valueParameters[i].symbol))
|
||||
}
|
||||
// valueParameters.forEachIndexed { i, p -> it.putValueArgument(i, JsIrBuilder.buildGetValue(p.symbol)) }
|
||||
it.putValueArgument(ctorOrig.valueParameters.size, irCreateCall)
|
||||
|
||||
// typeParameters.mapIndexed { i, t -> ctorImpl.typeParameters[i].descriptor -> }
|
||||
}
|
||||
val irReturn = JsIrBuilder.buildReturn(it, irDelegateCall)
|
||||
|
||||
|
||||
body = JsIrBuilder.buildBlockBody(listOf(irReturn))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class CallsiteRedirectionTransformer(val context: JsIrBackendContext) : IrElementTransformer<IrFunction?> {
|
||||
@@ -314,16 +246,14 @@ class SecondaryCtorLowering(val context: JsIrBackendContext) : IrElementTransfor
|
||||
private fun redirectCall(
|
||||
call: IrFunctionAccessExpression,
|
||||
newTarget: IrSimpleFunctionSymbol
|
||||
): IrCallImpl {
|
||||
val newCall = IrCallImpl(call.startOffset, call.endOffset, newTarget)
|
||||
) = IrCallImpl(call.startOffset, call.endOffset, newTarget).apply {
|
||||
|
||||
newCall.copyTypeArgumentsFrom(call)
|
||||
copyTypeArgumentsFrom(call)
|
||||
|
||||
for (i in 0 until call.valueArgumentsCount) {
|
||||
newCall.putValueArgument(i, call.getValueArgument(i))
|
||||
putValueArgument(i, call.getValueArgument(i))
|
||||
}
|
||||
|
||||
return newCall
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user