From bb4d25dfc9456a332e0025b77212489202ab4060 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Fri, 16 Jun 2023 23:28:44 +0200 Subject: [PATCH] IR: do not copy calls/references in ExpectSymbolTransformer This is just a refactoring/optimization that makes use of the fact that IrCall.symbol and other similar fields are now mutable. --- .../jetbrains/kotlin/cli/js/klib/irForKlib.kt | 3 +- .../common/ir/ExpectSymbolTransformer.kt | 127 +++++------------- .../common/lower/ExpectDeclarationRemover.kt | 17 +-- 3 files changed, 46 insertions(+), 101 deletions(-) diff --git a/compiler/cli/cli-js/src/org/jetbrains/kotlin/cli/js/klib/irForKlib.kt b/compiler/cli/cli-js/src/org/jetbrains/kotlin/cli/js/klib/irForKlib.kt index d4057543036..8498aee468c 100644 --- a/compiler/cli/cli-js/src/org/jetbrains/kotlin/cli/js/klib/irForKlib.kt +++ b/compiler/cli/cli-js/src/org/jetbrains/kotlin/cli/js/klib/irForKlib.kt @@ -115,9 +115,8 @@ fun generateIrForKlibSerialization( } if (configuration.get(CommonConfigurationKeys.EXPECT_ACTUAL_LINKER) != true) { - moduleFragment.transform(ExpectDeclarationRemover(psi2IrContext.symbolTable, false), null) + moduleFragment.accept(ExpectDeclarationRemover(psi2IrContext.symbolTable, false), null) } return moduleFragment to pluginContext } - diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/ExpectSymbolTransformer.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/ExpectSymbolTransformer.kt index edc1c74724a..dc17d977f37 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/ExpectSymbolTransformer.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/ExpectSymbolTransformer.kt @@ -13,21 +13,18 @@ import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI import org.jetbrains.kotlin.ir.declarations.IrDeclaration import org.jetbrains.kotlin.ir.expressions.* -import org.jetbrains.kotlin.ir.expressions.impl.* import org.jetbrains.kotlin.ir.symbols.IrClassSymbol import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol -import org.jetbrains.kotlin.ir.util.copyTypeAndValueArgumentsFrom -import org.jetbrains.kotlin.ir.util.irCall -import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid +import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid /** * [ExpectSymbolTransformer] replaces `expect` symbols in expressions with `actual` symbols. An `actual` symbol must be provided by * overriding [getActualClass], [getActualProperty], [getActualConstructor], and [getActualFunction]. */ @OptIn(ObsoleteDescriptorBasedAPI::class) -abstract class ExpectSymbolTransformer : IrElementTransformerVoid() { +abstract class ExpectSymbolTransformer : IrElementVisitorVoid { protected abstract fun getActualClass(descriptor: ClassDescriptor): IrClassSymbol? @@ -49,112 +46,60 @@ abstract class ExpectSymbolTransformer : IrElementTransformerVoid() { */ protected open fun isTargetDeclaration(declaration: IrDeclaration): Boolean = declaration.isExpect - override fun visitElement(element: IrElement): IrElement { - element.transformChildrenVoid() - return element + override fun visitElement(element: IrElement) { + element.acceptChildren(this, null) } - override fun visitConstructorCall(expression: IrConstructorCall): IrExpression { - val nExpression = super.visitConstructorCall(expression) as IrConstructorCall - if (!isTargetDeclaration(nExpression.symbol.owner)) return nExpression + override fun visitConstructorCall(expression: IrConstructorCall) { + super.visitConstructorCall(expression) + if (!isTargetDeclaration(expression.symbol.owner)) return - val newCallee = getActualConstructor(nExpression.symbol.descriptor) ?: return nExpression - with(nExpression) { - return IrConstructorCallImpl( - startOffset, endOffset, type, newCallee, typeArgumentsCount, constructorTypeArgumentsCount, valueArgumentsCount, origin - ).also { - it.attributeOwnerId = attributeOwnerId - it.copyTypeAndValueArgumentsFrom(nExpression) - } - } + expression.symbol = getActualConstructor(expression.symbol.descriptor) ?: return } - override fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall): IrExpression { - val nExpression = super.visitDelegatingConstructorCall(expression) as IrDelegatingConstructorCall - if (!isTargetDeclaration(nExpression.symbol.owner)) return nExpression + override fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall) { + super.visitDelegatingConstructorCall(expression) + if (!isTargetDeclaration(expression.symbol.owner)) return - val newCallee = getActualConstructor(nExpression.symbol.descriptor) ?: return nExpression - with(nExpression) { - return IrDelegatingConstructorCallImpl( - startOffset, endOffset, type, newCallee, typeArgumentsCount, valueArgumentsCount - ).also { - it.attributeOwnerId = attributeOwnerId - it.copyTypeAndValueArgumentsFrom(nExpression) - } - } + expression.symbol = getActualConstructor(expression.symbol.descriptor) ?: return } - override fun visitEnumConstructorCall(expression: IrEnumConstructorCall): IrExpression { - val nExpression = super.visitEnumConstructorCall(expression) as IrEnumConstructorCall - if (!isTargetDeclaration(nExpression.symbol.owner)) return nExpression + override fun visitEnumConstructorCall(expression: IrEnumConstructorCall) { + super.visitEnumConstructorCall(expression) + if (!isTargetDeclaration(expression.symbol.owner)) return - val newCallee = getActualConstructor(nExpression.symbol.descriptor) ?: return nExpression - with(nExpression) { - return IrEnumConstructorCallImpl( - startOffset, endOffset, type, newCallee, typeArgumentsCount, valueArgumentsCount - ).also { - it.attributeOwnerId = attributeOwnerId - it.copyTypeAndValueArgumentsFrom(nExpression) - } - } + expression.symbol = getActualConstructor(expression.symbol.descriptor) ?: return } - override fun visitCall(expression: IrCall): IrExpression { - val nExpression = super.visitCall(expression) as IrCall - if (!isTargetDeclaration(nExpression.symbol.owner)) return nExpression + override fun visitCall(expression: IrCall) { + super.visitCall(expression) + if (!isTargetDeclaration(expression.symbol.owner)) return - val newCallee = getActualFunction(nExpression.symbol.descriptor) ?: return nExpression - return irCall(nExpression, newCallee).also { - it.attributeOwnerId = nExpression.attributeOwnerId - } + expression.symbol = getActualFunction(expression.symbol.descriptor) ?: return } - override fun visitPropertyReference(expression: IrPropertyReference): IrExpression { - val nExpression = super.visitPropertyReference(expression) as IrPropertyReference - if (!isTargetDeclaration(nExpression.symbol.owner)) return nExpression + override fun visitPropertyReference(expression: IrPropertyReference) { + super.visitPropertyReference(expression) + if (!isTargetDeclaration(expression.symbol.owner)) return - val (newSymbol, newGetter, newSetter) = getActualProperty(nExpression.symbol.descriptor) ?: return nExpression - with(nExpression) { - return IrPropertyReferenceImpl( - startOffset, endOffset, type, - newSymbol, typeArgumentsCount, - field, newGetter, newSetter, - origin - ).also { - it.attributeOwnerId = attributeOwnerId - copyTypeArgumentsFrom(nExpression) - it.dispatchReceiver = dispatchReceiver - it.extensionReceiver = extensionReceiver - } - } + val (newSymbol, newGetter, newSetter) = getActualProperty(expression.symbol.descriptor) ?: return + expression.symbol = newSymbol + expression.getter = newGetter + expression.setter = newSetter } - override fun visitFunctionReference(expression: IrFunctionReference): IrExpression { - val nExpression = super.visitFunctionReference(expression) as IrFunctionReference - if (!isTargetDeclaration(nExpression.symbol.owner)) return nExpression + override fun visitFunctionReference(expression: IrFunctionReference) { + super.visitFunctionReference(expression) + if (!isTargetDeclaration(expression.symbol.owner)) return - val newCallee = getActualFunction(nExpression.symbol.descriptor) ?: return nExpression - with(nExpression) { - return IrFunctionReferenceImpl( - startOffset, endOffset, type, newCallee, typeArgumentsCount, valueArgumentsCount, reflectionTarget, origin - ).also { - it.attributeOwnerId = attributeOwnerId - it.copyTypeArgumentsFrom(nExpression) - it.dispatchReceiver = dispatchReceiver - it.extensionReceiver = extensionReceiver - } - } + expression.symbol = getActualFunction(expression.symbol.descriptor) ?: return } - override fun visitClassReference(expression: IrClassReference): IrExpression { - val nExpression = super.visitClassReference(expression) as IrClassReference - val oldSymbol = nExpression.symbol as? IrClassSymbol ?: return nExpression - if (!isTargetDeclaration(oldSymbol.owner)) return nExpression + override fun visitClassReference(expression: IrClassReference) { + super.visitClassReference(expression) + val oldSymbol = expression.symbol as? IrClassSymbol ?: return + if (!isTargetDeclaration(oldSymbol.owner)) return - val newSymbol = getActualClass(oldSymbol.descriptor) ?: return nExpression - with(nExpression) { - return IrClassReferenceImpl(startOffset, endOffset, type, newSymbol, classType) - } + expression.symbol = getActualClass(oldSymbol.descriptor) ?: return } - } diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/ExpectDeclarationRemover.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/ExpectDeclarationRemover.kt index c09510b8223..352adff2eed 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/ExpectDeclarationRemover.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/ExpectDeclarationRemover.kt @@ -9,13 +9,14 @@ import org.jetbrains.kotlin.backend.common.BackendContext import org.jetbrains.kotlin.backend.common.FileLoweringPass import org.jetbrains.kotlin.backend.common.ir.ExpectSymbolTransformer import org.jetbrains.kotlin.descriptors.* -import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrExpressionBody import org.jetbrains.kotlin.ir.expressions.IrGetValue -import org.jetbrains.kotlin.ir.symbols.* +import org.jetbrains.kotlin.ir.symbols.IrClassSymbol +import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol +import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol import org.jetbrains.kotlin.ir.types.extractTypeParameters import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid @@ -27,8 +28,8 @@ import kotlin.collections.set // `doRemove` means should expect-declaration be removed from IR @OptIn(ObsoleteDescriptorBasedAPI::class) -open class ExpectDeclarationRemover(val symbolTable: ReferenceSymbolTable, private val doRemove: Boolean) - : ExpectSymbolTransformer(), FileLoweringPass { +open class ExpectDeclarationRemover(val symbolTable: ReferenceSymbolTable, private val doRemove: Boolean) : ExpectSymbolTransformer(), + FileLoweringPass { constructor(context: BackendContext) : this(context.ir.symbols.externalSymbolTable, true) @@ -38,16 +39,16 @@ open class ExpectDeclarationRemover(val symbolTable: ReferenceSymbolTable, priva visitFile(irFile) } - override fun visitFile(declaration: IrFile): IrFile { + override fun visitFile(declaration: IrFile) { if (doRemove) { declaration.declarations.removeAll { shouldRemoveTopLevelDeclaration(it) } } - return super.visitFile(declaration) + super.visitFile(declaration) } - override fun visitValueParameter(declaration: IrValueParameter): IrStatement { + override fun visitValueParameter(declaration: IrValueParameter) { tryCopyDefaultArguments(declaration) - return super.visitValueParameter(declaration) + super.visitValueParameter(declaration) } fun transformFlat(declaration: IrDeclaration): List? {