From 563637548aeb859a0b92c8b46bd4c2f4e98f3068 Mon Sep 17 00:00:00 2001 From: Svyatoslav Kuzmich Date: Wed, 6 Jun 2018 18:32:44 +0300 Subject: [PATCH] KJS: Fix loop levels in ContinueReplacingVisitor (KT-24777) --- .../LabeledBlockToDoWhileTransformation.kt | 6 ++--- .../rewriters/ContinueReplacingVisitor.kt | 5 ++++ .../js/test/semantics/BoxJsTestGenerated.java | 5 ++++ .../test/semantics/IrBoxJsTestGenerated.java | 5 ++++ .../continueInLoopWithInlinableCondition.kt | 24 +++++++++++++++++++ 5 files changed, 42 insertions(+), 3 deletions(-) create mode 100644 js/js.translator/testData/box/inline/continueInLoopWithInlinableCondition.kt diff --git a/js/js.inliner/src/org/jetbrains/kotlin/js/inline/clean/LabeledBlockToDoWhileTransformation.kt b/js/js.inliner/src/org/jetbrains/kotlin/js/inline/clean/LabeledBlockToDoWhileTransformation.kt index edadbfd394c..53898bbc7ae 100644 --- a/js/js.inliner/src/org/jetbrains/kotlin/js/inline/clean/LabeledBlockToDoWhileTransformation.kt +++ b/js/js.inliner/src/org/jetbrains/kotlin/js/inline/clean/LabeledBlockToDoWhileTransformation.kt @@ -29,9 +29,9 @@ object LabeledBlockToDoWhileTransformation { } fun JsStatement.isLoop(): Boolean = when (this) { - is JsWhile -> true - is JsDoWhile -> true - is JsFor -> true + is JsWhile, + is JsDoWhile, + is JsFor, is JsForIn -> true else -> false } diff --git a/js/js.inliner/src/org/jetbrains/kotlin/js/inline/util/rewriters/ContinueReplacingVisitor.kt b/js/js.inliner/src/org/jetbrains/kotlin/js/inline/util/rewriters/ContinueReplacingVisitor.kt index 312687c69f1..5b136165bdc 100644 --- a/js/js.inliner/src/org/jetbrains/kotlin/js/inline/util/rewriters/ContinueReplacingVisitor.kt +++ b/js/js.inliner/src/org/jetbrains/kotlin/js/inline/util/rewriters/ContinueReplacingVisitor.kt @@ -26,6 +26,7 @@ class ContinueReplacingVisitor(val loopLabelName: JsName?, val guardLabelName: J override fun visit(x: JsContinue, ctx: JsContext): Boolean { val target = x.label?.name val shouldReplace = if (target == null) loopNestingLevel == 0 else target == loopLabelName + assert(loopNestingLevel >= 0) if (shouldReplace) { ctx.replaceMe(JsBreak(guardLabelName.makeRef())) } @@ -42,6 +43,7 @@ class ContinueReplacingVisitor(val loopLabelName: JsName?, val guardLabelName: J override fun endVisit(x: JsWhile, ctx: JsContext) { super.endVisit(x, ctx) + if (loopLabelName == null) return loopNestingLevel-- } @@ -54,6 +56,7 @@ class ContinueReplacingVisitor(val loopLabelName: JsName?, val guardLabelName: J override fun endVisit(x: JsDoWhile, ctx: JsContext) { super.endVisit(x, ctx) + if (loopLabelName == null) return loopNestingLevel-- } @@ -66,6 +69,7 @@ class ContinueReplacingVisitor(val loopLabelName: JsName?, val guardLabelName: J override fun endVisit(x: JsFor, ctx: JsContext) { super.endVisit(x, ctx) + if (loopLabelName == null) return loopNestingLevel-- } @@ -78,6 +82,7 @@ class ContinueReplacingVisitor(val loopLabelName: JsName?, val guardLabelName: J override fun endVisit(x: JsForIn, ctx: JsContext) { super.endVisit(x, ctx) + if (loopLabelName == null) return loopNestingLevel-- } } diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/BoxJsTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/BoxJsTestGenerated.java index c0b32c296ab..38232c7e1bc 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/BoxJsTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/BoxJsTestGenerated.java @@ -3724,6 +3724,11 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest { runTest("js/js.translator/testData/box/inline/classObject.kt"); } + @TestMetadata("continueInLoopWithInlinableCondition.kt") + public void testContinueInLoopWithInlinableCondition() throws Exception { + runTest("js/js.translator/testData/box/inline/continueInLoopWithInlinableCondition.kt"); + } + @TestMetadata("dontInlineFunctionCall.kt") public void testDontInlineFunctionCall() throws Exception { runTest("js/js.translator/testData/box/inline/dontInlineFunctionCall.kt"); diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/IrBoxJsTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/IrBoxJsTestGenerated.java index 3106c489a3f..f3a7ac74069 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/IrBoxJsTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/IrBoxJsTestGenerated.java @@ -3724,6 +3724,11 @@ public class IrBoxJsTestGenerated extends AbstractIrBoxJsTest { runTest("js/js.translator/testData/box/inline/classObject.kt"); } + @TestMetadata("continueInLoopWithInlinableCondition.kt") + public void testContinueInLoopWithInlinableCondition() throws Exception { + runTest("js/js.translator/testData/box/inline/continueInLoopWithInlinableCondition.kt"); + } + @TestMetadata("dontInlineFunctionCall.kt") public void testDontInlineFunctionCall() throws Exception { runTest("js/js.translator/testData/box/inline/dontInlineFunctionCall.kt"); diff --git a/js/js.translator/testData/box/inline/continueInLoopWithInlinableCondition.kt b/js/js.translator/testData/box/inline/continueInLoopWithInlinableCondition.kt new file mode 100644 index 00000000000..79c646bacfc --- /dev/null +++ b/js/js.translator/testData/box/inline/continueInLoopWithInlinableCondition.kt @@ -0,0 +1,24 @@ +// EXPECTED_REACHABLE_NODES: 1122 +/* +Modified test case from KT-24777 + */ +package foo + +inline fun condition() = false + +fun run(x: Boolean): String { + var y = 0 + do { + if (y > 0) + return "NOT OK" + y += 1 + do { + } while (false) + if (x) continue + } while (condition()) + return "OK" +} + +fun box(): String { + return run(true) +}