[FIR2IR] Avoid converting arguments of dynamic array set twice
^KT-63593 Fixed Merge-request: KT-MR-13152 Merged-by: Nikolay Lunyak <Nikolay.Lunyak@jetbrains.com>
This commit is contained in:
committed by
Space Team
parent
fb0461f422
commit
f12ecb3011
@@ -557,7 +557,7 @@ class Fir2IrVisitor(
|
||||
functionCall.calleeReference.name == OperatorNameConventions.SET &&
|
||||
functionCall.calleeReference.source?.kind == KtFakeSourceElementKind.ArrayAccessNameReference
|
||||
) {
|
||||
return convertToIrArrayAccessDynamicCall(functionCall)
|
||||
return convertToIrArraySetDynamicCall(functionCall)
|
||||
}
|
||||
return convertToIrCall(functionCall, dynamicOperator = null)
|
||||
}
|
||||
@@ -578,25 +578,24 @@ class Fir2IrVisitor(
|
||||
)
|
||||
}
|
||||
|
||||
private fun convertToIrArrayAccessDynamicCall(functionCall: FirFunctionCall): IrExpression {
|
||||
val explicitReceiverExpression = convertToIrCall(
|
||||
functionCall, dynamicOperator = IrDynamicOperator.ARRAY_ACCESS
|
||||
)
|
||||
if (explicitReceiverExpression is IrDynamicOperatorExpression) {
|
||||
explicitReceiverExpression.arguments.removeLast()
|
||||
private fun convertToIrArraySetDynamicCall(functionCall: FirFunctionCall): IrExpression {
|
||||
// `functionCall` has the form of `myDynamic.set(key1, key2, ..., newValue)`.
|
||||
// The resulting IR expects something like `myDynamic.ARRAY_ACCESS(key1, key2, ...).EQ(newValue)`.
|
||||
// Instead of constructing a `FirFunctionCall` for `get()` (the true `ARRAY_ACCESS`), and a new
|
||||
// call for `set()` (`EQ`), let's convert the whole thing as `ARRAY_ACCESS`, including
|
||||
// `newValue`, and then manually move it to a newly constructed EQ call.
|
||||
val arraySetAsGenericDynamicAccess = convertToIrCall(functionCall, IrDynamicOperator.ARRAY_ACCESS) as? IrDynamicOperatorExpression
|
||||
?: error("Converting dynamic array access should have resulted in IrDynamicOperatorExpression")
|
||||
val arraySetNewValue = arraySetAsGenericDynamicAccess.arguments.removeLast()
|
||||
return IrDynamicOperatorExpressionImpl(
|
||||
arraySetAsGenericDynamicAccess.startOffset,
|
||||
arraySetAsGenericDynamicAccess.endOffset,
|
||||
arraySetAsGenericDynamicAccess.type,
|
||||
IrDynamicOperator.EQ,
|
||||
).apply {
|
||||
receiver = arraySetAsGenericDynamicAccess
|
||||
arguments.add(arraySetNewValue)
|
||||
}
|
||||
val result = callGenerator.convertToIrCall(
|
||||
functionCall, functionCall.resolvedType, explicitReceiverExpression,
|
||||
dynamicOperator = IrDynamicOperator.EQ
|
||||
)
|
||||
if (result is IrDynamicOperatorExpression) {
|
||||
val arguments = result.arguments
|
||||
arguments[0] = arguments[arguments.lastIndex]
|
||||
while (arguments.size > 1) {
|
||||
arguments.removeLast()
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
override fun visitFunctionCall(functionCall: FirFunctionCall, data: Any?): IrExpression = whileAnalysing(session, functionCall) {
|
||||
|
||||
+6
@@ -1738,6 +1738,12 @@ public class FirJsBoxTestGenerated extends AbstractFirJsBoxTest {
|
||||
runTest("js/js.translator/testData/box/dynamic/compareTo.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("dynamicArraySetWithLambda.kt")
|
||||
public void testDynamicArraySetWithLambda() throws Exception {
|
||||
runTest("js/js.translator/testData/box/dynamic/dynamicArraySetWithLambda.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("equals.kt")
|
||||
public void testEquals() throws Exception {
|
||||
|
||||
+6
@@ -1738,6 +1738,12 @@ public class FirJsES6BoxTestGenerated extends AbstractFirJsES6BoxTest {
|
||||
runTest("js/js.translator/testData/box/dynamic/compareTo.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("dynamicArraySetWithLambda.kt")
|
||||
public void testDynamicArraySetWithLambda() throws Exception {
|
||||
runTest("js/js.translator/testData/box/dynamic/dynamicArraySetWithLambda.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("equals.kt")
|
||||
public void testEquals() throws Exception {
|
||||
|
||||
+6
@@ -1738,6 +1738,12 @@ public class IrBoxJsES6TestGenerated extends AbstractIrBoxJsES6Test {
|
||||
runTest("js/js.translator/testData/box/dynamic/compareTo.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("dynamicArraySetWithLambda.kt")
|
||||
public void testDynamicArraySetWithLambda() throws Exception {
|
||||
runTest("js/js.translator/testData/box/dynamic/dynamicArraySetWithLambda.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("equals.kt")
|
||||
public void testEquals() throws Exception {
|
||||
|
||||
+6
@@ -1738,6 +1738,12 @@ public class IrBoxJsTestGenerated extends AbstractIrBoxJsTest {
|
||||
runTest("js/js.translator/testData/box/dynamic/compareTo.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("dynamicArraySetWithLambda.kt")
|
||||
public void testDynamicArraySetWithLambda() throws Exception {
|
||||
runTest("js/js.translator/testData/box/dynamic/dynamicArraySetWithLambda.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("equals.kt")
|
||||
public void testEquals() throws Exception {
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
// ISSUE: KT-63593
|
||||
// WITH_STDLIB
|
||||
|
||||
fun <T> jso(): T = mutableMapOf<String, String>() as T
|
||||
|
||||
fun box(): String {
|
||||
val obj = jso<dynamic>()
|
||||
obj["a"] = run { "OK" }
|
||||
return obj["a"]
|
||||
}
|
||||
Reference in New Issue
Block a user