diff --git a/js/js.inliner/src/org/jetbrains/kotlin/js/inline/ExpressionDecomposer.kt b/js/js.inliner/src/org/jetbrains/kotlin/js/inline/ExpressionDecomposer.kt index c9d028c10ac..f72752bd668 100644 --- a/js/js.inliner/src/org/jetbrains/kotlin/js/inline/ExpressionDecomposer.kt +++ b/js/js.inliner/src/org/jetbrains/kotlin/js/inline/ExpressionDecomposer.kt @@ -19,6 +19,7 @@ package org.jetbrains.kotlin.js.inline.util import com.google.dart.compiler.backend.js.ast.* import com.google.dart.compiler.backend.js.ast.metadata.* import org.jetbrains.kotlin.js.translate.utils.JsAstUtils.* +import org.jetbrains.kotlin.js.translate.utils.ast.* import kotlin.platform.platformStatic import kotlin.properties.Delegates @@ -81,6 +82,21 @@ class ExpressionDecomposer private ( return false } + override fun visit(x: JsArrayAccess, ctx: JsContext<*>): Boolean { + x.process() + return false + } + + private fun JsArrayAccess.process() { + array = accept(array) + + if (array in containsNodeWithSideEffect && index in containsExtractable) { + array = array.extractToTemporary() + } + + index = accept(index) + } + override fun visit(x: JsInvocation, ctx: JsContext<*>): Boolean { CallableInvocationAdapter(x).process() return false diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/astUtils.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/astUtils.kt index 5f865864c8c..c102d3de04e 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/astUtils.kt +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/astUtils.kt @@ -55,3 +55,11 @@ public fun JsNode.any(predicate: (JsNode) -> Boolean): Boolean { visitor.accept(this) return visitor.matched } + +public var JsArrayAccess.index: JsExpression + get() = getIndexExpression() + set(value) = setIndexExpression(value) + +public var JsArrayAccess.array: JsExpression + get() = getArrayExpression() + set(value) = setArrayExpression(value) diff --git a/js/js.translator/testData/inlineEvaluationOrder/cases/arrayAccess1.kt b/js/js.translator/testData/inlineEvaluationOrder/cases/arrayAccess1.kt new file mode 100644 index 00000000000..97c082c5b76 --- /dev/null +++ b/js/js.translator/testData/inlineEvaluationOrder/cases/arrayAccess1.kt @@ -0,0 +1,8 @@ +package foo + +fun box(): String { + assertEquals(2, fizz(array(1, 2))[buzz(1)]) + assertEquals("fizz(1,2);buzz(1);", pullLog()) + + return "OK" +} \ No newline at end of file diff --git a/js/js.translator/testData/inlineEvaluationOrder/cases/arrayAccess2.kt b/js/js.translator/testData/inlineEvaluationOrder/cases/arrayAccess2.kt new file mode 100644 index 00000000000..c9971ce69a1 --- /dev/null +++ b/js/js.translator/testData/inlineEvaluationOrder/cases/arrayAccess2.kt @@ -0,0 +1,8 @@ +package foo + +fun box(): String { + assertEquals(2, array(1, 2)[fizz(0) + buzz(1)]) + assertEquals("fizz(0);buzz(1);", pullLog()) + + return "OK" +} \ No newline at end of file diff --git a/js/js.translator/testData/inlineEvaluationOrder/cases/arrayAccess3.kt b/js/js.translator/testData/inlineEvaluationOrder/cases/arrayAccess3.kt new file mode 100644 index 00000000000..2dfd2ea4020 --- /dev/null +++ b/js/js.translator/testData/inlineEvaluationOrder/cases/arrayAccess3.kt @@ -0,0 +1,8 @@ +package foo + +fun box(): String { + assertEquals(2, array(1, fizz(2))[fizz(0) + buzz(1)]) + assertEquals("fizz(2);fizz(0);buzz(1);", pullLog()) + + return "OK" +} \ No newline at end of file