From 6e60a31b736cb021a9b76ad993db1cdaa8e13871 Mon Sep 17 00:00:00 2001 From: Zalim Bashorov Date: Mon, 20 Apr 2015 18:28:26 +0300 Subject: [PATCH] JS backend: don't translate labels on expression #KT-7487 Fixed --- .../js/test/semantics/LabelTestGenerated.java | 6 ++ .../expression/ExpressionVisitor.java | 10 +++- .../labels/cases/labelOnExpression.kt | 56 +++++++++++++++++++ 3 files changed, 70 insertions(+), 2 deletions(-) create mode 100644 js/js.translator/testData/labels/cases/labelOnExpression.kt diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/LabelTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/LabelTestGenerated.java index 4b17cdb7112..a5073ba2990 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/LabelTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/LabelTestGenerated.java @@ -35,6 +35,12 @@ public class LabelTestGenerated extends AbstractLabelTest { JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("js/js.translator/testData/labels/cases"), Pattern.compile("^(.+)\\.kt$"), true); } + @TestMetadata("labelOnExpression.kt") + public void testLabelOnExpression() throws Exception { + String fileName = JetTestUtils.navigationMetadata("js/js.translator/testData/labels/cases/labelOnExpression.kt"); + doTest(fileName); + } + @TestMetadata("labelWithVariableClashing.kt") public void testLabelWithVariableClashing() throws Exception { String fileName = JetTestUtils.navigationMetadata("js/js.translator/testData/labels/cases/labelWithVariableClashing.kt"); diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/ExpressionVisitor.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/ExpressionVisitor.java index 591e1a87aca..39de547dc47 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/ExpressionVisitor.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/ExpressionVisitor.java @@ -23,7 +23,6 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.descriptors.DeclarationDescriptor; import org.jetbrains.kotlin.descriptors.FunctionDescriptor; import org.jetbrains.kotlin.descriptors.VariableDescriptor; -import org.jetbrains.kotlin.js.translate.context.TemporaryVariable; import org.jetbrains.kotlin.js.translate.context.TranslationContext; import org.jetbrains.kotlin.js.translate.declaration.ClassTranslator; import org.jetbrains.kotlin.js.translate.expression.loopTranslator.LoopTranslatorPackage; @@ -49,7 +48,6 @@ import java.util.List; import static org.jetbrains.kotlin.js.translate.context.Namer.getCapturedVarAccessor; import static org.jetbrains.kotlin.js.translate.general.Translation.translateAsExpression; -import static org.jetbrains.kotlin.js.translate.reference.CallExpressionTranslator.shouldBeInlined; import static org.jetbrains.kotlin.js.translate.reference.ReferenceTranslator.translateAsFQReference; import static org.jetbrains.kotlin.js.translate.utils.BindingUtils.*; import static org.jetbrains.kotlin.js.translate.utils.ErrorReportingUtils.message; @@ -290,13 +288,21 @@ public final class ExpressionVisitor extends TranslatorVisitor { ) { JetExpression baseExpression = expression.getBaseExpression(); assert baseExpression != null; + + if (BindingContextUtilPackage.isUsedAsExpression(expression, context.bindingContext())) { + return Translation.translateAsExpression(baseExpression, context).source(expression); + } + JsScope scope = context.scope(); assert scope instanceof JsFunctionScope: "Labeled statement is unexpected outside of function scope"; JsFunctionScope functionScope = (JsFunctionScope) scope; + String labelIdent = getReferencedName(expression.getTargetLabel()); + JsName labelName = functionScope.enterLabel(labelIdent); JsStatement baseStatement = Translation.translateAsStatement(baseExpression, context); functionScope.exitLabel(); + return new JsLabel(labelName, baseStatement).source(expression); } diff --git a/js/js.translator/testData/labels/cases/labelOnExpression.kt b/js/js.translator/testData/labels/cases/labelOnExpression.kt new file mode 100644 index 00000000000..ed8e4482c08 --- /dev/null +++ b/js/js.translator/testData/labels/cases/labelOnExpression.kt @@ -0,0 +1,56 @@ +// CHECK_LABELS_COUNT: function=test0 count=0 +// CHECK_LABELS_COUNT: function=test1 count=0 +// CHECK_LABELS_COUNT: function=test2 count=0 +// CHECK_LABELS_COUNT: function=test3 count=0 + +package foo + +fun myRun(f: () -> R) = f() + +fun test0() { + val a = @aa 1 + + assertEquals(1, a) + assertEquals(3, @l1 a + @l2 2) + + val b = @bb if (true) @t "then block" else @e "else block" + + assertEquals("then block", b) +} + +fun test1() { + run @label { + return@label false + } +} + +fun test2() { + myRun @label { + return@label false + } +} + +// KT-7487 +public fun test3() { + val f = Foo() + f.iter @label { + return@label false + } +} + +class Foo { + inline fun iter(body: ()->Boolean) { + for (i in 0 .. 10) { + if (!body()) break + } + } +} + +fun box(): String { + test0() + test1() + test2() + test3() + + return "OK" +}