[JS IR] Add deep copying for callable reference

Perform a deep copy of callable reference adapter on inline lowering

^KT-49844 Fixed
This commit is contained in:
Alexander Korepanov
2021-12-09 14:12:00 +03:00
committed by Space
parent 7b41d382b8
commit b82c306530
13 changed files with 133 additions and 20 deletions
@@ -1116,6 +1116,12 @@ public class FirBlackBoxInlineCodegenTestGenerated extends AbstractFirBlackBoxIn
public void testInlineVarargInts() throws Exception { public void testInlineVarargInts() throws Exception {
runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineVarargInts.kt"); runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineVarargInts.kt");
} }
@Test
@TestMetadata("multipleCallableReferenceUsage.kt")
public void testMultipleCallableReferenceUsage() throws Exception {
runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/multipleCallableReferenceUsage.kt");
}
} }
@Nested @Nested
@@ -245,10 +245,17 @@ class FunctionInlining(
return super.visitCall(expression) return super.visitCall(expression)
return when { return when {
functionArgument is IrFunctionReference -> inlineFunctionReference(expression, functionArgument) functionArgument is IrFunctionReference ->
functionArgument.isAdaptedFunctionReference() -> inlineAdaptedFunctionReference(expression, functionArgument as IrBlock) inlineFunctionReference(expression, functionArgument, functionArgument.symbol.owner)
functionArgument is IrFunctionExpression -> inlineFunctionExpression(expression, functionArgument)
else -> super.visitCall(expression) functionArgument.isAdaptedFunctionReference() ->
inlineAdaptedFunctionReference(expression, functionArgument as IrBlock)
functionArgument is IrFunctionExpression ->
inlineFunctionExpression(expression, functionArgument)
else ->
super.visitCall(expression)
} }
} }
@@ -264,10 +271,12 @@ class FunctionInlining(
} }
fun inlineAdaptedFunctionReference(irCall: IrCall, irBlock: IrBlock): IrExpression { fun inlineAdaptedFunctionReference(irCall: IrCall, irBlock: IrBlock): IrExpression {
val irFunction = irBlock.statements[0] as IrFunction val irFunction = irBlock.statements[0].let {
irFunction.transformChildrenVoid(this) it.transformChildrenVoid(this)
copyIrElement.copy(it) as IrFunction
}
val irFunctionReference = irBlock.statements[1] as IrFunctionReference val irFunctionReference = irBlock.statements[1] as IrFunctionReference
val inlinedFunctionReference = inlineFunctionReference(irCall, irFunctionReference) val inlinedFunctionReference = inlineFunctionReference(irCall, irFunctionReference, irFunction)
return IrBlockImpl( return IrBlockImpl(
irCall.startOffset, irCall.endOffset, irCall.startOffset, irCall.endOffset,
inlinedFunctionReference.type, origin = null, inlinedFunctionReference.type, origin = null,
@@ -275,7 +284,11 @@ class FunctionInlining(
) )
} }
fun inlineFunctionReference(irCall: IrCall, irFunctionReference: IrFunctionReference): IrExpression { fun inlineFunctionReference(
irCall: IrCall,
irFunctionReference: IrFunctionReference,
inlinedFunction: IrFunction
): IrExpression {
irFunctionReference.transformChildrenVoid(this) irFunctionReference.transformChildrenVoid(this)
val function = irFunctionReference.symbol.owner val function = irFunctionReference.symbol.owner
@@ -294,14 +307,14 @@ class FunctionInlining(
} }
val immediateCall = with(irCall) { val immediateCall = with(irCall) {
when (function) { when (inlinedFunction) {
is IrConstructor -> { is IrConstructor -> {
val classTypeParametersCount = function.parentAsClass.typeParameters.size val classTypeParametersCount = inlinedFunction.parentAsClass.typeParameters.size
IrConstructorCallImpl.fromSymbolOwner( IrConstructorCallImpl.fromSymbolOwner(
startOffset, startOffset,
endOffset, endOffset,
function.returnType, inlinedFunction.returnType,
function.symbol, inlinedFunction.symbol,
classTypeParametersCount classTypeParametersCount
) )
} }
@@ -309,13 +322,13 @@ class FunctionInlining(
IrCallImpl( IrCallImpl(
startOffset, startOffset,
endOffset, endOffset,
function.returnType, inlinedFunction.returnType,
function.symbol, inlinedFunction.symbol,
function.typeParameters.size, inlinedFunction.typeParameters.size,
function.valueParameters.size inlinedFunction.valueParameters.size
) )
else -> else ->
error("Unknown function kind : ${function.render()}") error("Unknown function kind : ${inlinedFunction.render()}")
} }
}.apply { }.apply {
for (parameter in functionParameters) { for (parameter in functionParameters) {
@@ -353,15 +366,15 @@ class FunctionInlining(
} }
when (parameter) { when (parameter) {
function.dispatchReceiverParameter -> function.dispatchReceiverParameter ->
this.dispatchReceiver = argument.implicitCastIfNeededTo(function.dispatchReceiverParameter!!.type) this.dispatchReceiver = argument.implicitCastIfNeededTo(inlinedFunction.dispatchReceiverParameter!!.type)
function.extensionReceiverParameter -> function.extensionReceiverParameter ->
this.extensionReceiver = argument.implicitCastIfNeededTo(function.extensionReceiverParameter!!.type) this.extensionReceiver = argument.implicitCastIfNeededTo(inlinedFunction.extensionReceiverParameter!!.type)
else -> else ->
putValueArgument( putValueArgument(
parameter.index, parameter.index,
argument.implicitCastIfNeededTo(function.valueParameters[parameter.index].type) argument.implicitCastIfNeededTo(inlinedFunction.valueParameters[parameter.index].type)
) )
} }
} }
@@ -0,0 +1,34 @@
// WITH_STDLIB
// KJS_WITH_FULL_RUNTIME
// FILE: 1.kt
package test
inline fun doIt(f: () -> Int): Int = f()
inline fun calcOnePlusTwo(f: (Int) -> Int): Int = f(1) + f(2)
inline fun getFirstArg(a: Int, vararg other: Int): Int = a
fun testCustomFunction(): Boolean {
val x = doIt { calcOnePlusTwo(::getFirstArg) }
return x == 3
}
fun testRuntimeFunctionCase1(): Boolean {
val x = "123".let { it.minOf(::maxOf) }
return x == '1'
}
fun testRuntimeFunctionCase2(): Boolean {
val x = "3123".minOfOrNull { a: Char -> a.titlecase().maxOf(::maxOf) }
return x == '1'
}
// FILE: 2.kt
import test.*
fun box(): String {
if (!testCustomFunction()) return "testCustomFunction failed"
if (!testRuntimeFunctionCase1()) return "testRuntimeFunctionCase1 failed"
if (!testRuntimeFunctionCase2()) return "testRuntimeFunctionCase2 failed"
return "OK"
}
@@ -1116,6 +1116,12 @@ public class BlackBoxInlineCodegenTestGenerated extends AbstractBlackBoxInlineCo
public void testInlineVarargInts() throws Exception { public void testInlineVarargInts() throws Exception {
runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineVarargInts.kt"); runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineVarargInts.kt");
} }
@Test
@TestMetadata("multipleCallableReferenceUsage.kt")
public void testMultipleCallableReferenceUsage() throws Exception {
runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/multipleCallableReferenceUsage.kt");
}
} }
@Nested @Nested
@@ -1116,6 +1116,12 @@ public class CompileKotlinAgainstInlineKotlinTestGenerated extends AbstractCompi
public void testInlineVarargInts() throws Exception { public void testInlineVarargInts() throws Exception {
runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineVarargInts.kt"); runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineVarargInts.kt");
} }
@Test
@TestMetadata("multipleCallableReferenceUsage.kt")
public void testMultipleCallableReferenceUsage() throws Exception {
runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/multipleCallableReferenceUsage.kt");
}
} }
@Nested @Nested
@@ -1116,6 +1116,12 @@ public class IrBlackBoxInlineCodegenTestGenerated extends AbstractIrBlackBoxInli
public void testInlineVarargInts() throws Exception { public void testInlineVarargInts() throws Exception {
runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineVarargInts.kt"); runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineVarargInts.kt");
} }
@Test
@TestMetadata("multipleCallableReferenceUsage.kt")
public void testMultipleCallableReferenceUsage() throws Exception {
runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/multipleCallableReferenceUsage.kt");
}
} }
@Nested @Nested
@@ -1116,6 +1116,12 @@ public class IrCompileKotlinAgainstInlineKotlinTestGenerated extends AbstractIrC
public void testInlineVarargInts() throws Exception { public void testInlineVarargInts() throws Exception {
runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineVarargInts.kt"); runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineVarargInts.kt");
} }
@Test
@TestMetadata("multipleCallableReferenceUsage.kt")
public void testMultipleCallableReferenceUsage() throws Exception {
runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/multipleCallableReferenceUsage.kt");
}
} }
@Nested @Nested
@@ -1116,6 +1116,12 @@ public class IrSerializeCompileKotlinAgainstInlineKotlinTestGenerated extends Ab
public void testInlineVarargInts() throws Exception { public void testInlineVarargInts() throws Exception {
runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineVarargInts.kt"); runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineVarargInts.kt");
} }
@Test
@TestMetadata("multipleCallableReferenceUsage.kt")
public void testMultipleCallableReferenceUsage() throws Exception {
runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/multipleCallableReferenceUsage.kt");
}
} }
@Nested @Nested
@@ -1116,6 +1116,12 @@ public class JvmIrAgainstOldBoxInlineTestGenerated extends AbstractJvmIrAgainstO
public void testInlineVarargInts() throws Exception { public void testInlineVarargInts() throws Exception {
runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineVarargInts.kt"); runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineVarargInts.kt");
} }
@Test
@TestMetadata("multipleCallableReferenceUsage.kt")
public void testMultipleCallableReferenceUsage() throws Exception {
runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/multipleCallableReferenceUsage.kt");
}
} }
@Nested @Nested
@@ -1116,6 +1116,12 @@ public class JvmOldAgainstIrBoxInlineTestGenerated extends AbstractJvmOldAgainst
public void testInlineVarargInts() throws Exception { public void testInlineVarargInts() throws Exception {
runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineVarargInts.kt"); runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineVarargInts.kt");
} }
@Test
@TestMetadata("multipleCallableReferenceUsage.kt")
public void testMultipleCallableReferenceUsage() throws Exception {
runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/multipleCallableReferenceUsage.kt");
}
} }
@Nested @Nested
@@ -918,6 +918,12 @@ public class JsCodegenInlineTestGenerated extends AbstractJsCodegenInlineTest {
public void testInlineVarargInts() throws Exception { public void testInlineVarargInts() throws Exception {
runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineVarargInts.kt"); runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineVarargInts.kt");
} }
@Test
@TestMetadata("multipleCallableReferenceUsage.kt")
public void testMultipleCallableReferenceUsage() throws Exception {
runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/multipleCallableReferenceUsage.kt");
}
} }
@Nested @Nested
@@ -918,6 +918,12 @@ public class IrJsCodegenInlineTestGenerated extends AbstractIrJsCodegenInlineTes
public void testInlineVarargInts() throws Exception { public void testInlineVarargInts() throws Exception {
runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineVarargInts.kt"); runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineVarargInts.kt");
} }
@Test
@TestMetadata("multipleCallableReferenceUsage.kt")
public void testMultipleCallableReferenceUsage() throws Exception {
runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/multipleCallableReferenceUsage.kt");
}
} }
@Nested @Nested
@@ -36326,6 +36326,12 @@ public class ExternalTestGenerated extends AbstractExternalNativeBlackBoxTest {
public void testInlineVarargInts() throws Exception { public void testInlineVarargInts() throws Exception {
runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineVarargInts.kt"); runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineVarargInts.kt");
} }
@Test
@TestMetadata("multipleCallableReferenceUsage.kt")
public void testMultipleCallableReferenceUsage() throws Exception {
runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/multipleCallableReferenceUsage.kt");
}
} }
@Nested @Nested