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.
This commit is contained in:
Mark Punzalan
2019-06-27 21:42:44 -07:00
committed by max-kammerer
parent 1abdf0561a
commit 969478481e
13 changed files with 129 additions and 197 deletions
@@ -47,7 +47,7 @@ internal fun <K> MutableMap<K, (IrFunctionAccessExpression) -> IrExpression>.add
internal typealias MemberToTransformer = HashMap<SimpleMemberKey, (IrFunctionAccessExpression) -> 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) {
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
)