From ec53f9b25475078c35e1038a9181c096a90ac76f Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Mon, 30 Oct 2017 14:52:43 +0300 Subject: [PATCH] JS: don't emit short circuit operators for boolean and/or See KT-21004 --- .../js/test/semantics/BoxJsTestGenerated.java | 6 +++++ .../PrimitiveBinaryOperationFIF.java | 18 +++++++++------ .../evaluationOrder/booleanAndOr.kt | 22 +++++++++++++++++++ 3 files changed, 39 insertions(+), 7 deletions(-) create mode 100644 js/js.translator/testData/box/expression/evaluationOrder/booleanAndOr.kt 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 83da036853d..2703531c2e3 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 @@ -2251,6 +2251,12 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest { doTest(fileName); } + @TestMetadata("booleanAndOr.kt") + public void testBooleanAndOr() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/expression/evaluationOrder/booleanAndOr.kt"); + doTest(fileName); + } + @TestMetadata("callArgs.kt") public void testCallArgs() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/expression/evaluationOrder/callArgs.kt"); diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/PrimitiveBinaryOperationFIF.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/PrimitiveBinaryOperationFIF.java index 7d2f7d4e925..98f398bb077 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/PrimitiveBinaryOperationFIF.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/PrimitiveBinaryOperationFIF.java @@ -191,14 +191,18 @@ public enum PrimitiveBinaryOperationFIF implements FunctionIntrinsicFactory { // Temporary hack to get '%' for deprecated 'mod' operator Name descriptorName = descriptor.getName().equals(OperatorNameConventions.MOD) ? OperatorNameConventions.REM : descriptor.getName(); + switch (descriptorName.asString()) { + case "or": + return JsBinaryOperator.BIT_OR; + case "and": + return JsBinaryOperator.BIT_AND; + case "xor": + return JsBinaryOperator.BIT_XOR; + default: + break; + } + KtToken token = OperatorConventions.BINARY_OPERATION_NAMES.inverse().get(descriptorName); - if (token == null) { - token = OperatorConventions.BOOLEAN_OPERATIONS.inverse().get(descriptorName); - } - if (token == null) { - assert descriptorName.asString().equals("xor"); - return JsBinaryOperator.BIT_XOR; - } return OperatorTable.getBinaryOperator(token); } diff --git a/js/js.translator/testData/box/expression/evaluationOrder/booleanAndOr.kt b/js/js.translator/testData/box/expression/evaluationOrder/booleanAndOr.kt new file mode 100644 index 00000000000..4b57b72404b --- /dev/null +++ b/js/js.translator/testData/box/expression/evaluationOrder/booleanAndOr.kt @@ -0,0 +1,22 @@ +// EXPECTED_REACHABLE_NODES: 1135 +var log = "" + +fun foo(a: Boolean, b: () -> Boolean): Boolean = a or b() + +fun bar(a: Boolean, b: () -> Boolean): Boolean = a and b() + +fun box(): String { + if (!foo(true) { log += "1"; false }) return "fail1" + if (!foo(true) { log += "2"; true }) return "fail2" + if (foo(false) { log += "3"; false }) return "fail3" + if (!foo(false) { log += "4"; true }) return "fail4" + + if (bar(true) { log += "5"; false }) return "fail5" + if (!bar(true) { log += "6"; true }) return "fail6" + if (bar(false) { log += "7"; false }) return "fail7" + if (bar(false) { log += "8"; true }) return "fail8" + + if (log != "12345678") return "fail log: $log" + + return "OK" +} \ No newline at end of file