From 17ee38a0b77956e033b5fefc6a753fa61b405b17 Mon Sep 17 00:00:00 2001 From: Roman Artemev Date: Wed, 18 Apr 2018 22:31:42 +0300 Subject: [PATCH] Refactor secondary constructor lowering using new builders --- .../backend/js/lower/SecondaryCtorLowering.kt | 226 ++++++------------ 1 file changed, 78 insertions(+), 148 deletions(-) diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/SecondaryCtorLowering.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/SecondaryCtorLowering.kt index 2132a217136..02c927d3c22 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/SecondaryCtorLowering.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/SecondaryCtorLowering.kt @@ -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 { @@ -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 } + } }