[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.name == OperatorNameConventions.SET &&
|
||||||
functionCall.calleeReference.source?.kind == KtFakeSourceElementKind.ArrayAccessNameReference
|
functionCall.calleeReference.source?.kind == KtFakeSourceElementKind.ArrayAccessNameReference
|
||||||
) {
|
) {
|
||||||
return convertToIrArrayAccessDynamicCall(functionCall)
|
return convertToIrArraySetDynamicCall(functionCall)
|
||||||
}
|
}
|
||||||
return convertToIrCall(functionCall, dynamicOperator = null)
|
return convertToIrCall(functionCall, dynamicOperator = null)
|
||||||
}
|
}
|
||||||
@@ -578,25 +578,24 @@ class Fir2IrVisitor(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun convertToIrArrayAccessDynamicCall(functionCall: FirFunctionCall): IrExpression {
|
private fun convertToIrArraySetDynamicCall(functionCall: FirFunctionCall): IrExpression {
|
||||||
val explicitReceiverExpression = convertToIrCall(
|
// `functionCall` has the form of `myDynamic.set(key1, key2, ..., newValue)`.
|
||||||
functionCall, dynamicOperator = IrDynamicOperator.ARRAY_ACCESS
|
// 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
|
||||||
if (explicitReceiverExpression is IrDynamicOperatorExpression) {
|
// call for `set()` (`EQ`), let's convert the whole thing as `ARRAY_ACCESS`, including
|
||||||
explicitReceiverExpression.arguments.removeLast()
|
// `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) {
|
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");
|
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
|
@Test
|
||||||
@TestMetadata("equals.kt")
|
@TestMetadata("equals.kt")
|
||||||
public void testEquals() throws Exception {
|
public void testEquals() throws Exception {
|
||||||
|
|||||||
+6
@@ -1738,6 +1738,12 @@ public class FirJsES6BoxTestGenerated extends AbstractFirJsES6BoxTest {
|
|||||||
runTest("js/js.translator/testData/box/dynamic/compareTo.kt");
|
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
|
@Test
|
||||||
@TestMetadata("equals.kt")
|
@TestMetadata("equals.kt")
|
||||||
public void testEquals() throws Exception {
|
public void testEquals() throws Exception {
|
||||||
|
|||||||
+6
@@ -1738,6 +1738,12 @@ public class IrBoxJsES6TestGenerated extends AbstractIrBoxJsES6Test {
|
|||||||
runTest("js/js.translator/testData/box/dynamic/compareTo.kt");
|
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
|
@Test
|
||||||
@TestMetadata("equals.kt")
|
@TestMetadata("equals.kt")
|
||||||
public void testEquals() throws Exception {
|
public void testEquals() throws Exception {
|
||||||
|
|||||||
+6
@@ -1738,6 +1738,12 @@ public class IrBoxJsTestGenerated extends AbstractIrBoxJsTest {
|
|||||||
runTest("js/js.translator/testData/box/dynamic/compareTo.kt");
|
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
|
@Test
|
||||||
@TestMetadata("equals.kt")
|
@TestMetadata("equals.kt")
|
||||||
public void testEquals() throws Exception {
|
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