diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrInlineCodegen.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrInlineCodegen.kt index 33d8299f12a..0103954e536 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrInlineCodegen.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrInlineCodegen.kt @@ -8,6 +8,7 @@ package org.jetbrains.kotlin.backend.jvm.codegen import org.jetbrains.kotlin.backend.common.descriptors.WrappedSimpleFunctionDescriptor import org.jetbrains.kotlin.backend.jvm.JvmBackendContext import org.jetbrains.kotlin.backend.jvm.ir.isInlineParameter +import org.jetbrains.kotlin.backend.jvm.ir.isLambda import org.jetbrains.kotlin.codegen.IrExpressionLambda import org.jetbrains.kotlin.codegen.JvmKotlinType import org.jetbrains.kotlin.codegen.StackValue @@ -197,7 +198,7 @@ fun isInlineIrExpression(argumentExpression: IrExpression) = else -> false } -fun IrBlock.isInlineIrBlock(): Boolean = origin == IrStatementOrigin.LAMBDA || origin == IrStatementOrigin.ANONYMOUS_FUNCTION +fun IrBlock.isInlineIrBlock(): Boolean = origin.isLambda fun IrFunction.isInlineFunctionCall(context: JvmBackendContext) = (!context.state.isInlineDisabled || typeParameters.any { it.isReified }) && isInline \ No newline at end of file diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/ir/IrUtils.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/ir/IrUtils.kt index c2c009687fe..e9d17b03d38 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/ir/IrUtils.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/ir/IrUtils.kt @@ -99,7 +99,7 @@ fun IrType.getArrayElementType(irBuiltIns: IrBuiltIns): IrType = else irBuiltIns.primitiveArrayElementTypes.getValue(this.classOrNull!!) -val IrStatementOrigin?.isLambda +val IrStatementOrigin?.isLambda: Boolean get() = this == IrStatementOrigin.LAMBDA || this == IrStatementOrigin.ANONYMOUS_FUNCTION val IrConstructor.shouldBeHidden: Boolean diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/CallableReferenceLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/CallableReferenceLowering.kt index 555062ca5f1..581275a9c40 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/CallableReferenceLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/CallableReferenceLowering.kt @@ -48,9 +48,6 @@ internal val callableReferencePhase = makeIrFilePhase( description = "Handle callable references" ) -private val IrStatementOrigin?.isLambda - get() = this == IrStatementOrigin.LAMBDA || this == IrStatementOrigin.ANONYMOUS_FUNCTION - internal class InlineReferenceLocator(private val context: JvmBackendContext) : IrElementVisitorVoidWithContext() { val inlineReferences = mutableSetOf() @@ -379,11 +376,7 @@ internal class CallableReferenceLowering(private val context: JvmBackendContext) private fun createGetSignatureMethod(superFunction: IrSimpleFunction): IrSimpleFunction = buildOverride(superFunction).apply { body = context.createJvmIrBuilder(symbol, startOffset, endOffset).run { irExprBody(irCall(backendContext.ir.symbols.signatureStringIntrinsic).apply { - putValueArgument(0, with(irFunctionReference) { - IrFunctionReferenceImpl( - startOffset, endOffset, type, symbol, descriptor, typeArgumentsCount, valueArgumentsCount, origin - ) - }) + putValueArgument(0, irFunctionReference.deepCopyWithSymbols(symbol.owner)) }) } } diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/SyntheticAccessorLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/SyntheticAccessorLowering.kt index 115c81f245c..68e2ed6ec95 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/SyntheticAccessorLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/SyntheticAccessorLowering.kt @@ -35,7 +35,6 @@ import org.jetbrains.kotlin.ir.types.classifierOrNull import org.jetbrains.kotlin.ir.types.isSubtypeOfClass import org.jetbrains.kotlin.ir.types.makeNullable import org.jetbrains.kotlin.ir.util.* -import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid import org.jetbrains.kotlin.load.java.JavaVisibilities import org.jetbrains.kotlin.load.java.JvmAbi @@ -48,64 +47,6 @@ internal class SyntheticAccessorLowering(val context: JvmBackendContext) : IrEle override fun lower(irFile: IrFile) { inlineLambdaToCallSite.putAll(InlineReferenceLocator.scan(context, irFile).lambdaToCallSite) - - // Unconditionally add bridges for hidden constructors - irFile.transformChildrenVoid(object: IrElementTransformerVoid() { - private val hiddenDeclarations = mutableSetOf() - - private fun handleConstructor(declaration: IrConstructor): IrConstructorSymbol? { - if (declaration.shouldBeHidden) { - declaration.visibility = Visibilities.PRIVATE - hiddenDeclarations += declaration - } - - if (declaration !in hiddenDeclarations) - return null - - return functionMap.getOrPut(declaration.symbol) { - declaration.makeConstructorAccessor().also { accessor -> - // There's a special case in the JVM backend for serializing the metadata of hidden - // constructors - we serialize the descriptor of the original constructor, but the - // signature of the bridge. We implement this special case in the JVM IR backend by - // attaching the metadata directly to the bridge. We also have to move all annotations - // to the bridge method. Parameter annotations are already moved by the copyTo method. - accessor.metadata = declaration.metadata - declaration.safeAs()?.metadata = null - accessor.annotations += declaration.annotations - declaration.annotations.clear() - declaration.valueParameters.forEach { it.annotations.clear() } - }.symbol - } as IrConstructorSymbol - } - - override fun visitConstructor(declaration: IrConstructor): IrStatement { - handleConstructor(declaration) - return super.visitConstructor(declaration) - } - - override fun visitConstructorCall(expression: IrConstructorCall): IrExpression { - handleConstructor(expression.symbol.owner) - return super.visitConstructorCall(expression) - } - - override fun visitFunctionReference(expression: IrFunctionReference): IrExpression { - val function = expression.symbol.owner - - if (!expression.origin.isLambda && function is IrConstructor) { - handleConstructor(function)?.let { accessor -> - expression.transformChildrenVoid() - return IrFunctionReferenceImpl( - expression.startOffset, expression.endOffset, expression.type, - accessor, accessor.descriptor, accessor.owner.typeParameters.size, - accessor.owner.valueParameters.size, expression.origin - ) - } - } - - return super.visitFunctionReference(expression) - } - }) - irFile.transformChildrenVoid(this) pendingTransformations.forEach { it() } } @@ -147,6 +88,57 @@ internal class SyntheticAccessorLowering(val context: JvmBackendContext) : IrEle handleAccess(expression, expression.symbol, setterMap, ::makeSetterAccessorSymbol, ::modifySetterExpression) ) + override fun visitConstructor(declaration: IrConstructor): IrStatement { + handleHiddenConstructor(declaration) + return super.visitConstructor(declaration) + } + + override fun visitConstructorCall(expression: IrConstructorCall): IrExpression { + handleHiddenConstructor(expression.symbol.owner) + return super.visitConstructorCall(expression) + } + + override fun visitFunctionReference(expression: IrFunctionReference): IrExpression { + val function = expression.symbol.owner + + if (!expression.origin.isLambda && function is IrConstructor) { + handleHiddenConstructor(function)?.let { accessor -> + expression.transformChildrenVoid() + return IrFunctionReferenceImpl( + expression.startOffset, expression.endOffset, expression.type, + accessor, accessor.descriptor, accessor.owner.typeParameters.size, + accessor.owner.valueParameters.size, expression.origin + ) + } + } + + return super.visitFunctionReference(expression) + } + + private fun handleHiddenConstructor(declaration: IrConstructor): IrConstructorSymbol? { + functionMap[declaration.symbol]?.let { return it as IrConstructorSymbol } + + if (!declaration.shouldBeHidden) + return null + + declaration.visibility = Visibilities.PRIVATE + + return declaration.makeConstructorAccessor().also { accessor -> + functionMap[declaration.symbol] = accessor.symbol + + // There's a special case in the JVM backend for serializing the metadata of hidden + // constructors - we serialize the descriptor of the original constructor, but the + // signature of the bridge. We implement this special case in the JVM IR backend by + // attaching the metadata directly to the bridge. We also have to move all annotations + // to the bridge method. Parameter annotations are already moved by the copyTo method. + accessor.metadata = declaration.metadata + declaration.safeAs()?.metadata = null + accessor.annotations += declaration.annotations + declaration.annotations.clear() + declaration.valueParameters.forEach { it.annotations.clear() } + }.symbol + } + private inline fun handleAccess( expression: ExprT, symbol: FromSyT,