From 969478481ef737f1e947cfb153bdf415ca2f25ae Mon Sep 17 00:00:00 2001 From: Mark Punzalan Date: Thu, 27 Jun 2019 21:42:44 -0700 Subject: [PATCH] Move extension receiver to value parameters for static functions created during InlineClassLowering phase. This was the only place where both dispatch and extension receivers were NOT moved to value parameters, which meant that the receivers were not following the conventional ordering. Merged createStaticBodilessMethod with createStaticFunctionWithReceivers and the latter was moved to backend/common/ir/IrUtils.kt. --- .../kotlin/backend/common/ir/IrUtils.kt | 57 +++++++++++++ .../lower/InlineClassDeclarationLowering.kt | 66 ++++----------- .../js/lower/calls/CallsLoweringUtils.kt | 2 +- .../lower/calls/EnumIntrinsicsTransformer.kt | 1 - .../EqualityAndComparisonCallsTransformer.kt | 10 +-- .../calls/ExceptionHelperCallsTransformer.kt | 1 - .../calls/MethodsOfAnyCallsTransformer.kt | 8 +- .../calls/NumberOperatorCallsTransformer.kt | 16 ++-- .../jvm/descriptors/JvmDeclarationFactory.kt | 16 +--- .../jvm/lower/InterfaceDelegationLowering.kt | 2 +- .../backend/jvm/lower/InterfaceLowering.kt | 66 +-------------- .../lower/StaticDefaultFunctionLowering.kt | 1 + .../org/jetbrains/kotlin/ir/util/IrUtils.kt | 80 +++++++------------ 13 files changed, 129 insertions(+), 197 deletions(-) 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 -> {