diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/IrUtils.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/IrUtils.kt index c50bc4a1e82..128f269266d 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/IrUtils.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/IrUtils.kt @@ -20,9 +20,11 @@ import org.jetbrains.kotlin.backend.common.CommonBackendContext import org.jetbrains.kotlin.backend.common.DumpIrTreeWithDescriptorsVisitor import org.jetbrains.kotlin.backend.common.deepCopyWithVariables import org.jetbrains.kotlin.backend.common.descriptors.* +import org.jetbrains.kotlin.backend.common.lower.VariableRemapper import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Visibilities +import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.builders.Scope @@ -499,3 +501,58 @@ fun IrClass.addFakeOverrides() { declarations += fakeOverriddenFunctions.values } + +fun createStaticFunctionWithReceivers( + irParent: IrDeclarationParent, + name: Name, + oldFunction: IrFunction, + dispatchReceiverType: IrType? = oldFunction.dispatchReceiverParameter?.type, + origin: IrDeclarationOrigin = oldFunction.origin, + copyBody: Boolean = true +): IrSimpleFunction { + val descriptor = WrappedSimpleFunctionDescriptor(Annotations.EMPTY, oldFunction.descriptor.source) + return IrFunctionImpl( + oldFunction.startOffset, oldFunction.endOffset, + origin, + IrSimpleFunctionSymbolImpl(descriptor), + name, + oldFunction.visibility, + Modality.FINAL, + oldFunction.returnType, + isInline = false, isExternal = false, isTailrec = false, isSuspend = false + ).apply { + descriptor.bind(this) + parent = irParent + + copyTypeParametersFrom(oldFunction) + + annotations.addAll(oldFunction.annotations) + + var offset = 0 + val dispatchReceiver = oldFunction.dispatchReceiverParameter?.copyTo( + this, + name = Name.identifier("this"), + index = offset++, + type = dispatchReceiverType!! + ) + val extensionReceiver = oldFunction.extensionReceiverParameter?.copyTo( + this, + name = Name.identifier("receiver"), + index = offset++ + ) + valueParameters.addAll(listOfNotNull(dispatchReceiver, extensionReceiver) + + oldFunction.valueParameters.map { it.copyTo(this, index = it.index + offset) } + ) + + val mapping: Map = + (listOfNotNull(oldFunction.dispatchReceiverParameter, oldFunction.extensionReceiverParameter) + oldFunction.valueParameters) + .zip(valueParameters).toMap() + if (copyBody) { + body = oldFunction.body + ?.transform(VariableRemapper(mapping), null) + ?.patchDeclarationParents(this) + } + + metadata = oldFunction.metadata + } +} diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/InlineClassDeclarationLowering.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/InlineClassDeclarationLowering.kt index a128687a79b..abb4a4fbe1c 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/InlineClassDeclarationLowering.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/InlineClassDeclarationLowering.kt @@ -8,18 +8,13 @@ package org.jetbrains.kotlin.backend.common.lower import org.jetbrains.kotlin.backend.common.BackendContext import org.jetbrains.kotlin.backend.common.ClassLoweringPass import org.jetbrains.kotlin.backend.common.FileLoweringPass -import org.jetbrains.kotlin.backend.common.descriptors.WrappedSimpleFunctionDescriptor -import org.jetbrains.kotlin.backend.common.ir.copyTo -import org.jetbrains.kotlin.backend.common.ir.copyTypeParametersFrom -import org.jetbrains.kotlin.descriptors.Modality +import org.jetbrains.kotlin.backend.common.ir.createStaticFunctionWithReceivers import org.jetbrains.kotlin.ir.IrStatement 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.expressions.* import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol -import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid @@ -142,10 +137,12 @@ class InlineClassLowering(val context: BackendContext) { staticMethod.valueParameters[0] function.extensionReceiverParameter -> - staticMethod.extensionReceiverParameter!! + staticMethod.valueParameters[1] - in function.valueParameters -> - staticMethod.valueParameters[valueDeclaration.index + 1] + in function.valueParameters -> { + val offset = if (function.extensionReceiverParameter != null) 2 else 1 + staticMethod.valueParameters[valueDeclaration.index + offset] + } else -> return expression } @@ -163,13 +160,14 @@ class InlineClassLowering(val context: BackendContext) { +irReturn( irCall(staticMethod).apply { val parameters = - listOf(function.dispatchReceiverParameter!!) + function.valueParameters + listOfNotNull( + function.dispatchReceiverParameter!!, + function.extensionReceiverParameter + ) + function.valueParameters for ((index, valueParameter) in parameters.withIndex()) { putValueArgument(index, irGet(valueParameter)) } - - extensionReceiver = function.extensionReceiverParameter?.let { irGet(it) } } ) } @@ -190,7 +188,7 @@ class InlineClassLowering(val context: BackendContext) { return expression } - return irCall(expression, getOrCreateStaticMethod(function), dispatchReceiverAsArgument = false) + return irCall(expression, getOrCreateStaticMethod(function)) } override fun visitCall(expression: IrCall): IrExpression { @@ -208,7 +206,7 @@ class InlineClassLowering(val context: BackendContext) { return irCall( expression, getOrCreateStaticMethod(function), - dispatchReceiverAsArgument = (function is IrSimpleFunction) + receiversAsArguments = (function is IrSimpleFunction) ) } @@ -219,11 +217,7 @@ class InlineClassLowering(val context: BackendContext) { return when { !klass.isInline -> expression function.isPrimary -> irConstructorCall(expression, function) - else -> irCall(expression, getOrCreateStaticMethod(function)).apply { - (0 until expression.valueArgumentsCount).forEach { - putValueArgument(it, expression.getValueArgument(it)!!) - } - } + else -> irCall(expression, getOrCreateStaticMethod(function)) } } @@ -242,36 +236,6 @@ class InlineClassLowering(val context: BackendContext) { else -> Name.identifier(asString() + INLINE_CLASS_IMPL_SUFFIX) } - private fun createStaticBodilessMethod(function: IrFunction): IrSimpleFunction { - val descriptor = WrappedSimpleFunctionDescriptor() - - return IrFunctionImpl( - function.startOffset, - function.endOffset, - function.origin, - IrSimpleFunctionSymbolImpl(descriptor), - function.name.toInlineClassImplementationName(), - function.visibility, - Modality.FINAL, - function.returnType, - function.isInline, - function.isExternal, - (function is IrSimpleFunction && function.isTailrec), - (function is IrSimpleFunction && function.isSuspend) - ).apply { - descriptor.bind(this) - copyTypeParametersFrom(function) - annotations += function.annotations - dispatchReceiverParameter = null - extensionReceiverParameter = function.extensionReceiverParameter?.copyTo(this) - if (function is IrSimpleFunction) { - valueParameters.add(function.dispatchReceiverParameter!!.let { p -> p.copyTo(this, index = p.index + 1) }) - valueParameters += function.valueParameters.map { p -> p.copyTo(this, index = p.index + 1) } - } else { - valueParameters += function.valueParameters.map { p -> p.copyTo(this) } - } - parent = function.parent - assert(isStaticMethodOfClass) - } - } + private fun createStaticBodilessMethod(function: IrFunction): IrSimpleFunction = + createStaticFunctionWithReceivers(function.parent, function.name.toInlineClassImplementationName(), function, copyBody = false) } diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/calls/CallsLoweringUtils.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/calls/CallsLoweringUtils.kt index e3db4ca8ac3..9391699ccf2 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/calls/CallsLoweringUtils.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/calls/CallsLoweringUtils.kt @@ -47,7 +47,7 @@ internal fun MutableMap IrExpression>.add internal typealias MemberToTransformer = HashMap IrExpression> internal fun MemberToTransformer.add(type: IrType, name: Name, v: IrFunctionSymbol) { - add(type, name) { irCall(it, v, dispatchReceiverAsArgument = true) } + add(type, name) { irCall(it, v, receiversAsArguments = true) } } internal fun MemberToTransformer.add(type: IrType, name: Name, v: IrFunction) { diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/calls/EnumIntrinsicsTransformer.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/calls/EnumIntrinsicsTransformer.kt index 7862408ed2e..daba1d13ded 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/calls/EnumIntrinsicsTransformer.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/calls/EnumIntrinsicsTransformer.kt @@ -9,7 +9,6 @@ import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext import org.jetbrains.kotlin.ir.util.irCall import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction import org.jetbrains.kotlin.ir.declarations.isStaticMethodOfClass -import org.jetbrains.kotlin.ir.expressions.IrCall import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression import org.jetbrains.kotlin.ir.types.getClass diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/calls/EqualityAndComparisonCallsTransformer.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/calls/EqualityAndComparisonCallsTransformer.kt index d68d478934d..4f5fcba2772 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/calls/EqualityAndComparisonCallsTransformer.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/calls/EqualityAndComparisonCallsTransformer.kt @@ -53,7 +53,7 @@ class EqualityAndComparisonCallsTransformer(context: JsIrBackendContext) : Calls comparator.owner.returnType, comparator ).apply { - putValueArgument(0, irCall(call, intrinsics.longCompareToLong, argumentAsDispatchReceiver = true)) + putValueArgument(0, irCall(call, intrinsics.longCompareToLong, argumentsAsReceivers = true)) putValueArgument(1, JsIrBuilder.buildInt(irBuiltIns.intType, 0)) } } @@ -95,7 +95,7 @@ class EqualityAndComparisonCallsTransformer(context: JsIrBackendContext) : Calls chooseEqualityOperatorForPrimitiveTypes(call) !isLhsPrimitive && !lhs.type.isNullable() && equalsMethod != null -> - irCall(call, equalsMethod.symbol, argumentAsDispatchReceiver = true) + irCall(call, equalsMethod.symbol, argumentsAsReceivers = true) else -> irCall(call, intrinsics.jsEquals) @@ -127,7 +127,7 @@ class EqualityAndComparisonCallsTransformer(context: JsIrBackendContext) : Calls // Use runtime function call in case when receiverType is a primitive JS type that doesn't have `compareTo` method, // or has a potential to be primitive type (being fake overridden from `Comparable`) function.isMethodOfPrimitiveJSType() || function.isFakeOverriddenFromComparable() -> - irCall(call, intrinsics.jsCompareTo, dispatchReceiverAsArgument = true) + irCall(call, intrinsics.jsCompareTo, receiversAsArguments = true) // Valid `compareTo` method must be present at this point else -> @@ -144,12 +144,12 @@ class EqualityAndComparisonCallsTransformer(context: JsIrBackendContext) : Calls // `Any.equals` works as identity operator call.isSuperToAny() -> - irCall(call, intrinsics.jsEqeqeq, dispatchReceiverAsArgument = true) + irCall(call, intrinsics.jsEqeqeq, receiversAsArguments = true) // Use runtime function call in case when receiverType is a primitive JS type that doesn't have `equals` method, // or has a potential to be primitive type (being fake overridden from `Any`) function.isMethodOfPotentiallyPrimitiveJSType() -> - irCall(call, intrinsics.jsEquals, dispatchReceiverAsArgument = true) + irCall(call, intrinsics.jsEquals, receiversAsArguments = true) // Valid `equals` method must be present at this point else -> call diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/calls/ExceptionHelperCallsTransformer.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/calls/ExceptionHelperCallsTransformer.kt index 266dd6d4bea..33f2f7e4fe2 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/calls/ExceptionHelperCallsTransformer.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/calls/ExceptionHelperCallsTransformer.kt @@ -7,7 +7,6 @@ package org.jetbrains.kotlin.ir.backend.js.lower.calls import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext import org.jetbrains.kotlin.ir.util.irCall -import org.jetbrains.kotlin.ir.expressions.IrCall import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression import org.jetbrains.kotlin.ir.util.kotlinPackageFqn import org.jetbrains.kotlin.name.FqName diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/calls/MethodsOfAnyCallsTransformer.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/calls/MethodsOfAnyCallsTransformer.kt index 445e5127b18..2f5a62a1852 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/calls/MethodsOfAnyCallsTransformer.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/calls/MethodsOfAnyCallsTransformer.kt @@ -29,9 +29,9 @@ class MethodsOfAnyCallsTransformer(context: JsIrBackendContext) : CallsTransform put(Name.identifier("toString")) { call -> if (shouldReplaceToStringWithRuntimeCall(call)) { if ((call as IrCall).isSuperToAny()) { - irCall(call, intrinsics.jsAnyToString, dispatchReceiverAsArgument = true) + irCall(call, intrinsics.jsAnyToString, receiversAsArguments = true) } else { - irCall(call, intrinsics.jsToString, dispatchReceiverAsArgument = true) + irCall(call, intrinsics.jsToString, receiversAsArguments = true) } } else { call @@ -41,9 +41,9 @@ class MethodsOfAnyCallsTransformer(context: JsIrBackendContext) : CallsTransform put(Name.identifier("hashCode")) { call -> if (call.symbol.owner.isFakeOverriddenFromAny()) { if ((call as IrCall).isSuperToAny()) { - irCall(call, intrinsics.jsGetObjectHashCode, dispatchReceiverAsArgument = true) + irCall(call, intrinsics.jsGetObjectHashCode, receiversAsArguments = true) } else { - irCall(call, intrinsics.jsHashCode, dispatchReceiverAsArgument = true) + irCall(call, intrinsics.jsHashCode, receiversAsArguments = true) } } else { call diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/calls/NumberOperatorCallsTransformer.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/calls/NumberOperatorCallsTransformer.kt index ce2f09db5e2..2690a9c7699 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/calls/NumberOperatorCallsTransformer.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/calls/NumberOperatorCallsTransformer.kt @@ -46,9 +46,9 @@ class NumberOperatorCallsTransformer(context: JsIrBackendContext) : CallsTransfo irBuiltIns.booleanType.let { // These operators are not short-circuit -- using bitwise operators '&', '|', '^' followed by coercion to boolean - add(it, OperatorNames.AND) { call -> toBoolean(irCall(call, intrinsics.jsBitAnd, dispatchReceiverAsArgument = true)) } - add(it, OperatorNames.OR) { call -> toBoolean(irCall(call, intrinsics.jsBitOr, dispatchReceiverAsArgument = true)) } - add(it, OperatorNames.XOR) { call -> toBoolean(irCall(call, intrinsics.jsBitXor, dispatchReceiverAsArgument = true)) } + add(it, OperatorNames.AND) { call -> toBoolean(irCall(call, intrinsics.jsBitAnd, receiversAsArguments = true)) } + add(it, OperatorNames.OR) { call -> toBoolean(irCall(call, intrinsics.jsBitOr, receiversAsArguments = true)) } + add(it, OperatorNames.XOR) { call -> toBoolean(irCall(call, intrinsics.jsBitXor, receiversAsArguments = true)) } add(it, OperatorNames.NOT, intrinsics.jsNot) } @@ -88,9 +88,9 @@ class NumberOperatorCallsTransformer(context: JsIrBackendContext) : CallsTransfo return with(call.symbol.owner.valueParameters[0].type) { when { isByte() || isShort() || isInt() -> - irCall(call, intrinsics.jsNumberRangeToNumber, dispatchReceiverAsArgument = true) + irCall(call, intrinsics.jsNumberRangeToNumber, receiversAsArguments = true) isLong() -> - irCall(call, intrinsics.jsNumberRangeToLong, dispatchReceiverAsArgument = true) + irCall(call, intrinsics.jsNumberRangeToLong, receiversAsArguments = true) else -> call } } @@ -101,7 +101,7 @@ class NumberOperatorCallsTransformer(context: JsIrBackendContext) : CallsTransfo intrinsic: IrFunctionSymbol, toInt32: Boolean = false ): IrExpression { - val newCall = irCall(call, intrinsic, dispatchReceiverAsArgument = true) + val newCall = irCall(call, intrinsic, receiversAsArguments = true) if (toInt32) return toInt32(newCall) return newCall @@ -152,7 +152,7 @@ class NumberOperatorCallsTransformer(context: JsIrBackendContext) : CallsTransfo transformCrement(call, intrinsics.jsMinus) private fun transformCrement(call: IrFunctionAccessExpression, correspondingBinaryOp: IrFunctionSymbol): IrExpression { - val operation = irCall(call, correspondingBinaryOp, dispatchReceiverAsArgument = true).apply { + val operation = irCall(call, correspondingBinaryOp, receiversAsArguments = true).apply { putValueArgument(1, buildInt(1)) } @@ -161,7 +161,7 @@ class NumberOperatorCallsTransformer(context: JsIrBackendContext) : CallsTransfo private fun transformUnaryMinus(call: IrFunctionAccessExpression) = convertResultToPrimitiveType( - irCall(call, intrinsics.jsUnaryMinus, dispatchReceiverAsArgument = true), + irCall(call, intrinsics.jsUnaryMinus, receiversAsArguments = true), call.type ) diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/JvmDeclarationFactory.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/JvmDeclarationFactory.kt index 9075bfa31e6..174325b5b91 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/JvmDeclarationFactory.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/JvmDeclarationFactory.kt @@ -9,37 +9,29 @@ import org.jetbrains.kotlin.backend.common.deepCopyWithWrappedDescriptors import org.jetbrains.kotlin.backend.common.descriptors.WrappedClassConstructorDescriptor import org.jetbrains.kotlin.backend.common.descriptors.WrappedClassDescriptor import org.jetbrains.kotlin.backend.common.descriptors.WrappedValueParameterDescriptor -import org.jetbrains.kotlin.backend.common.ir.DeclarationFactory -import org.jetbrains.kotlin.backend.common.ir.copyTo -import org.jetbrains.kotlin.backend.common.ir.copyTypeParametersFrom -import org.jetbrains.kotlin.backend.common.ir.createImplicitParameterDeclarationWithWrappedDescriptor +import org.jetbrains.kotlin.backend.common.ir.* import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin -import org.jetbrains.kotlin.backend.jvm.lower.createStaticFunctionWithReceivers import org.jetbrains.kotlin.builtins.CompanionObjectMapping.isMappedIntrinsicCompanionObject import org.jetbrains.kotlin.codegen.OwnerKind import org.jetbrains.kotlin.codegen.state.GenerationState -import org.jetbrains.kotlin.descriptors.* -import org.jetbrains.kotlin.descriptors.annotations.Annotations -import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl +import org.jetbrains.kotlin.descriptors.ClassKind +import org.jetbrains.kotlin.descriptors.Modality +import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.builders.declarations.buildField import org.jetbrains.kotlin.ir.builders.setSourceRange import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.impl.IrClassImpl import org.jetbrains.kotlin.ir.declarations.impl.IrConstructorImpl -import org.jetbrains.kotlin.ir.declarations.impl.IrFieldImpl import org.jetbrains.kotlin.ir.declarations.impl.IrValueParameterImpl import org.jetbrains.kotlin.ir.symbols.impl.IrClassSymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.IrConstructorSymbolImpl -import org.jetbrains.kotlin.ir.symbols.impl.IrFieldSymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl import org.jetbrains.kotlin.ir.types.IrType -import org.jetbrains.kotlin.ir.types.toKotlinType import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.load.java.JavaVisibilities import org.jetbrains.kotlin.load.java.JvmAbi import org.jetbrains.kotlin.name.Name -import org.jetbrains.org.objectweb.asm.Opcodes import java.util.* class JvmDeclarationFactory( diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InterfaceDelegationLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InterfaceDelegationLowering.kt index c212d74a7da..bae840b4e1c 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InterfaceDelegationLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InterfaceDelegationLowering.kt @@ -205,7 +205,7 @@ private class InterfaceSuperCallsLowering(val context: JvmBackendContext) : IrEl if (superCallee.isDefinitelyNotDefaultImplsMethod()) return super.visitCall(expression) val redirectTarget = context.declarationFactory.getDefaultImplsFunction(superCallee) - val newCall = irCall(expression, redirectTarget, dispatchReceiverAsArgument = true, extensionReceiverAsArgument = true) + val newCall = irCall(expression, redirectTarget, receiversAsArguments = true) return super.visitCall(newCall) } diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InterfaceLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InterfaceLowering.kt index 8d9913e12e4..5850c0144a7 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InterfaceLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InterfaceLowering.kt @@ -6,36 +6,27 @@ package org.jetbrains.kotlin.backend.jvm.lower import org.jetbrains.kotlin.backend.common.ClassLoweringPass -import org.jetbrains.kotlin.backend.common.descriptors.WrappedSimpleFunctionDescriptor -import org.jetbrains.kotlin.backend.common.ir.copyTo -import org.jetbrains.kotlin.backend.common.ir.copyTypeParametersFrom import org.jetbrains.kotlin.backend.common.ir.passTypeArgumentsFrom import org.jetbrains.kotlin.backend.common.lower.InitializersLowering.Companion.clinitName -import org.jetbrains.kotlin.backend.common.lower.VariableRemapper import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase import org.jetbrains.kotlin.backend.jvm.JvmBackendContext import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin import org.jetbrains.kotlin.backend.jvm.ir.hasJvmDefault import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Visibilities -import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.ir.declarations.* -import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl import org.jetbrains.kotlin.ir.expressions.IrCall import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrFunctionReference import org.jetbrains.kotlin.ir.expressions.IrReturn import org.jetbrains.kotlin.ir.expressions.impl.* import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol -import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl -import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.util.copyTypeAndValueArgumentsFrom import org.jetbrains.kotlin.ir.util.irCall import org.jetbrains.kotlin.ir.util.isInterface import org.jetbrains.kotlin.ir.util.patchDeclarationParents import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid -import org.jetbrains.kotlin.name.Name internal val interfacePhase = makeIrFilePhase( ::InterfaceLowering, @@ -127,7 +118,7 @@ private class InterfaceLowering(val context: JvmBackendContext) : IrElementTrans val newFunction = removedFunctions[expression.symbol]?.owner return super.visitCall( if (newFunction != null) { - irCall(expression, newFunction, dispatchReceiverAsArgument = true, extensionReceiverAsArgument = true) + irCall(expression, newFunction, receiversAsArguments = true) } else { expression } @@ -148,7 +139,7 @@ private class InterfaceLowering(val context: JvmBackendContext) : IrElementTrans typeArgumentsCount, origin ).apply { - copyTypeAndValueArgumentsFrom(expression, dispatchReceiverAsArgument = true, extensionReceiverAsArgument = true) + copyTypeAndValueArgumentsFrom(expression, receiversAsArguments = true) } } } else { @@ -157,56 +148,3 @@ private class InterfaceLowering(val context: JvmBackendContext) : IrElementTrans ) } } - - -internal fun createStaticFunctionWithReceivers( - irParent: IrDeclarationParent, - name: Name, - oldFunction: IrFunction, - dispatchReceiverType: IrType? = oldFunction.dispatchReceiverParameter?.type, - origin: IrDeclarationOrigin = oldFunction.origin -): IrSimpleFunction { - val descriptor = WrappedSimpleFunctionDescriptor(Annotations.EMPTY, oldFunction.descriptor.source) - return IrFunctionImpl( - oldFunction.startOffset, oldFunction.endOffset, - origin, - IrSimpleFunctionSymbolImpl(descriptor), - name, - oldFunction.visibility, - Modality.FINAL, - oldFunction.returnType, - isInline = false, isExternal = false, isTailrec = false, isSuspend = false - ).apply { - descriptor.bind(this) - parent = irParent - - copyTypeParametersFrom(oldFunction) - - annotations.addAll(oldFunction.annotations) - - var offset = 0 - val dispatchReceiver = oldFunction.dispatchReceiverParameter?.copyTo( - this, - name = Name.identifier("this"), - index = offset++, - type = dispatchReceiverType!! - ) - val extensionReceiver = oldFunction.extensionReceiverParameter?.copyTo( - this, - name = Name.identifier("receiver"), - index = offset++ - ) - valueParameters.addAll(listOfNotNull(dispatchReceiver, extensionReceiver) + - oldFunction.valueParameters.map { it.copyTo(this, index = it.index + offset) } - ) - - val mapping: Map = - (listOfNotNull(oldFunction.dispatchReceiverParameter, oldFunction.extensionReceiverParameter) + oldFunction.valueParameters) - .zip(valueParameters).toMap() - body = oldFunction.body - ?.transform(VariableRemapper(mapping), null) - ?.patchDeclarationParents(this) - - metadata = oldFunction.metadata - } -} diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/StaticDefaultFunctionLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/StaticDefaultFunctionLowering.kt index c9709d9e0cd..8cf0c8a7ea6 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/StaticDefaultFunctionLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/StaticDefaultFunctionLowering.kt @@ -18,6 +18,7 @@ package org.jetbrains.kotlin.backend.jvm.lower import org.jetbrains.kotlin.backend.common.BackendContext import org.jetbrains.kotlin.backend.common.ClassLoweringPass +import org.jetbrains.kotlin.backend.common.ir.createStaticFunctionWithReceivers import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.declarations.IrClass diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/IrUtils.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/IrUtils.kt index 83116a30349..def90224b9b 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/IrUtils.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/IrUtils.kt @@ -414,23 +414,23 @@ fun ReferenceSymbolTable.referenceFunction(callable: CallableDescriptor): IrFunc /** * Create new call based on given [call] and [newFunction] - * [dispatchReceiverAsFirstArgument]: optionally convert call with dispatch receiver to static call - * [firstArgumentAsDispatchReceiver]: optionally convert static call to call with dispatch receiver + * [receiversAsArguments]: optionally convert call with dispatch receiver to static call + * [argumentsAsReceivers]: optionally convert static call to call with dispatch receiver */ fun irConstructorCall( call: IrFunctionAccessExpression, newFunction: IrConstructor, - dispatchReceiverAsFirstArgument: Boolean = false, - firstArgumentAsDispatchReceiver: Boolean = false + receiversAsArguments: Boolean = false, + argumentsAsReceivers: Boolean = false ): IrConstructorCall = - irConstructorCall(call, newFunction.symbol, dispatchReceiverAsFirstArgument, firstArgumentAsDispatchReceiver) + irConstructorCall(call, newFunction.symbol, receiversAsArguments, argumentsAsReceivers) fun irConstructorCall( call: IrFunctionAccessExpression, newSymbol: IrConstructorSymbol, - dispatchReceiverAsFirstArgument: Boolean = false, - firstArgumentAsDispatchReceiver: Boolean = false + receiversAsArguments: Boolean = false, + argumentsAsDispatchers: Boolean = false ): IrConstructorCall = call.run { IrConstructorCallImpl( @@ -446,8 +446,8 @@ fun irConstructorCall( ).apply { copyTypeAndValueArgumentsFrom( call, - dispatchReceiverAsFirstArgument, - firstArgumentAsDispatchReceiver + receiversAsArguments, + argumentsAsDispatchers ) } } @@ -455,27 +455,21 @@ fun irConstructorCall( fun irCall( call: IrFunctionAccessExpression, newFunction: IrFunction, - dispatchReceiverAsArgument: Boolean = false, - argumentAsDispatchReceiver: Boolean = false, - extensionReceiverAsArgument: Boolean = false, - argumentAsExtensionReceiver: Boolean = false + receiversAsArguments: Boolean = false, + argumentsAsReceivers: Boolean = false ): IrCall = irCall( call, newFunction.symbol, - dispatchReceiverAsArgument, - argumentAsDispatchReceiver, - extensionReceiverAsArgument, - argumentAsExtensionReceiver + receiversAsArguments, + argumentsAsReceivers ) fun irCall( call: IrFunctionAccessExpression, newSymbol: IrFunctionSymbol, - dispatchReceiverAsArgument: Boolean = false, - argumentAsDispatchReceiver: Boolean = false, - extensionReceiverAsArgument: Boolean = false, - argumentAsExtensionReceiver: Boolean = false + receiversAsArguments: Boolean = false, + argumentsAsReceivers: Boolean = false ): IrCall = call.run { IrCallImpl( @@ -489,54 +483,42 @@ fun irCall( ).apply { copyTypeAndValueArgumentsFrom( call, - dispatchReceiverAsArgument, - argumentAsDispatchReceiver, - extensionReceiverAsArgument, - argumentAsExtensionReceiver + receiversAsArguments, + argumentsAsReceivers ) } } fun IrFunctionAccessExpression.copyTypeAndValueArgumentsFrom( src: IrFunctionAccessExpression, - dispatchReceiverAsArgument: Boolean = false, - argumentAsDispatchReceiver: Boolean = false, - extensionReceiverAsArgument: Boolean = false, - argumentAsExtensionReceiver: Boolean = false + receiversAsArguments: Boolean = false, + argumentsAsReceivers: Boolean = false ) = copyTypeAndValueArgumentsFrom( src, src.symbol.owner, symbol.owner, - dispatchReceiverAsArgument, - argumentAsDispatchReceiver, - extensionReceiverAsArgument, - argumentAsExtensionReceiver + receiversAsArguments, + argumentsAsReceivers ) fun IrFunctionReference.copyTypeAndValueArgumentsFrom( src: IrFunctionReference, - dispatchReceiverAsArgument: Boolean = false, - argumentAsDispatchReceiver: Boolean = false, - extensionReceiverAsArgument: Boolean = false, - argumentAsExtensionReceiver: Boolean = false + receiversAsArguments: Boolean = false, + argumentsAsReceivers: Boolean = false ) = copyTypeAndValueArgumentsFrom( src, src.symbol.owner, symbol.owner, - dispatchReceiverAsArgument, - argumentAsDispatchReceiver, - extensionReceiverAsArgument, - argumentAsExtensionReceiver + receiversAsArguments, + argumentsAsReceivers ) private fun IrMemberAccessExpression.copyTypeAndValueArgumentsFrom( src: IrMemberAccessExpression, srcFunction: IrFunction, destFunction: IrFunction, - dispatchReceiverAsArgument: Boolean = false, - argumentAsDispatchReceiver: Boolean = false, - extensionReceiverAsArgument: Boolean = false, - argumentAsExtensionReceiver: Boolean = false + receiversAsArguments: Boolean = false, + argumentsAsReceivers: Boolean = false ) { copyTypeArgumentsFrom(src) @@ -544,10 +526,10 @@ private fun IrMemberAccessExpression.copyTypeAndValueArgumentsFrom( var srcValueArgumentIndex = 0 when { - dispatchReceiverAsArgument && srcFunction.dispatchReceiverParameter != null -> { + receiversAsArguments && srcFunction.dispatchReceiverParameter != null -> { putValueArgument(destValueArgumentIndex++, src.dispatchReceiver) } - argumentAsDispatchReceiver && destFunction.dispatchReceiverParameter != null -> { + argumentsAsReceivers && destFunction.dispatchReceiverParameter != null -> { dispatchReceiver = src.getValueArgument(srcValueArgumentIndex++) } else -> { @@ -556,10 +538,10 @@ private fun IrMemberAccessExpression.copyTypeAndValueArgumentsFrom( } when { - extensionReceiverAsArgument && srcFunction.extensionReceiverParameter != null -> { + receiversAsArguments && srcFunction.extensionReceiverParameter != null -> { putValueArgument(destValueArgumentIndex++, src.extensionReceiver) } - argumentAsExtensionReceiver && destFunction.extensionReceiverParameter != null -> { + argumentsAsReceivers && destFunction.extensionReceiverParameter != null -> { extensionReceiver = src.getValueArgument(srcValueArgumentIndex++) } else -> {