From d0e4515ec19c726bfc0798577fa05c1596a70f94 Mon Sep 17 00:00:00 2001 From: Alexander Korepanov Date: Mon, 31 Jul 2023 17:26:51 +0200 Subject: [PATCH] [JS IR] Materialize all JsCompositeBlock ^KT-60667 Fixed --- .../backend/JsToStringGenerationVisitor.java | 2 +- .../js/test/fir/FirJsBoxTestGenerated.java | 6 ++ .../js/test/fir/FirJsES6BoxTestGenerated.java | 6 ++ .../js/test/ir/IrBoxJsES6TestGenerated.java | 6 ++ .../js/test/ir/IrBoxJsTestGenerated.java | 6 ++ .../jsAstOptimizations/inlineEmptyFunction.kt | 62 +++++++++++++++ .../inlineEmptyFunctionTest.js | 77 +++++++++++++++++++ 7 files changed, 164 insertions(+), 1 deletion(-) create mode 100644 js/js.translator/testData/box/jsAstOptimizations/inlineEmptyFunction.kt create mode 100644 js/js.translator/testData/box/jsAstOptimizations/inlineEmptyFunctionTest.js diff --git a/js/js.ast/src/org/jetbrains/kotlin/js/backend/JsToStringGenerationVisitor.java b/js/js.ast/src/org/jetbrains/kotlin/js/backend/JsToStringGenerationVisitor.java index 58fe18d95d5..e828c9a96c6 100644 --- a/js/js.ast/src/org/jetbrains/kotlin/js/backend/JsToStringGenerationVisitor.java +++ b/js/js.ast/src/org/jetbrains/kotlin/js/backend/JsToStringGenerationVisitor.java @@ -828,7 +828,7 @@ public class JsToStringGenerationVisitor extends JsVisitor { } private static JsStatement materialize(JsStatement statement) { - return statement instanceof JsCompositeBlock && ((JsCompositeBlock) statement).getStatements().size() > 1 + return statement instanceof JsCompositeBlock ? new JsBlock(statement) : statement; } diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/fir/FirJsBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/fir/FirJsBoxTestGenerated.java index b832e195e9f..be263d80dc1 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/fir/FirJsBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/fir/FirJsBoxTestGenerated.java @@ -6946,6 +6946,12 @@ public class FirJsBoxTestGenerated extends AbstractFirJsBoxTest { runTest("js/js.translator/testData/box/jsAstOptimizations/deadCodeElimination.kt"); } + @Test + @TestMetadata("inlineEmptyFunction.kt") + public void testInlineEmptyFunction() throws Exception { + runTest("js/js.translator/testData/box/jsAstOptimizations/inlineEmptyFunction.kt"); + } + @Test @TestMetadata("tempVarDeclOnAssignment.kt") public void testTempVarDeclOnAssignment() throws Exception { diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/fir/FirJsES6BoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/fir/FirJsES6BoxTestGenerated.java index a75f520d1cd..89fe3cdc9c3 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/fir/FirJsES6BoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/fir/FirJsES6BoxTestGenerated.java @@ -7052,6 +7052,12 @@ public class FirJsES6BoxTestGenerated extends AbstractFirJsES6BoxTest { runTest("js/js.translator/testData/box/jsAstOptimizations/deadCodeElimination.kt"); } + @Test + @TestMetadata("inlineEmptyFunction.kt") + public void testInlineEmptyFunction() throws Exception { + runTest("js/js.translator/testData/box/jsAstOptimizations/inlineEmptyFunction.kt"); + } + @Test @TestMetadata("tempVarDeclOnAssignment.kt") public void testTempVarDeclOnAssignment() throws Exception { diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrBoxJsES6TestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrBoxJsES6TestGenerated.java index cfd90874cb9..6586210e1e2 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrBoxJsES6TestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrBoxJsES6TestGenerated.java @@ -7052,6 +7052,12 @@ public class IrBoxJsES6TestGenerated extends AbstractIrBoxJsES6Test { runTest("js/js.translator/testData/box/jsAstOptimizations/deadCodeElimination.kt"); } + @Test + @TestMetadata("inlineEmptyFunction.kt") + public void testInlineEmptyFunction() throws Exception { + runTest("js/js.translator/testData/box/jsAstOptimizations/inlineEmptyFunction.kt"); + } + @Test @TestMetadata("tempVarDeclOnAssignment.kt") public void testTempVarDeclOnAssignment() throws Exception { diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrBoxJsTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrBoxJsTestGenerated.java index ed79409fce1..afb314cf351 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrBoxJsTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrBoxJsTestGenerated.java @@ -6946,6 +6946,12 @@ public class IrBoxJsTestGenerated extends AbstractIrBoxJsTest { runTest("js/js.translator/testData/box/jsAstOptimizations/deadCodeElimination.kt"); } + @Test + @TestMetadata("inlineEmptyFunction.kt") + public void testInlineEmptyFunction() throws Exception { + runTest("js/js.translator/testData/box/jsAstOptimizations/inlineEmptyFunction.kt"); + } + @Test @TestMetadata("tempVarDeclOnAssignment.kt") public void testTempVarDeclOnAssignment() throws Exception { diff --git a/js/js.translator/testData/box/jsAstOptimizations/inlineEmptyFunction.kt b/js/js.translator/testData/box/jsAstOptimizations/inlineEmptyFunction.kt new file mode 100644 index 00000000000..9875bd1b592 --- /dev/null +++ b/js/js.translator/testData/box/jsAstOptimizations/inlineEmptyFunction.kt @@ -0,0 +1,62 @@ +inline fun inlineFunction(x: Int) {} + +var OK : Any? = null +val flag1 = 1 +val flag2 = 2 + +fun check() = true + +fun sep(comment: String) {} + +fun setOK(): Int { + OK = "OK" + return 1 +} + +// EXPECT_GENERATED_JS: function=box expect=inlineEmptyFunctionTest.js +fun box(): String { + sep("Simple call") + inlineFunction(1) + inlineFunction(setOK()) + + sep("Call in if") + if (flag1 != 0) { + if (OK == "OK" && flag1 == 1 && flag2 is Int && check()) { + inlineFunction(2) + } + } + + sep("Call in else") + if (flag1 != 0) { + if (OK == "OK" && flag1 == 1 && flag2 is Int && check()) { + check() // non inline call + check() // non inline call + } else { + inlineFunction(3) + } + } + + sep("Call in while") + while (OK != "OK") { + inlineFunction(4) + } + + sep("Call in when") + when (OK) { + is String -> inlineFunction(5) + is Number -> inlineFunction(6) + else -> inlineFunction(7) + } + + sep("Call in try/catch/finally") + try { + inlineFunction(8) + } catch (e: Exception) { + inlineFunction(9) + } finally { + inlineFunction(10) + } + + sep("End") + return OK as String +} diff --git a/js/js.translator/testData/box/jsAstOptimizations/inlineEmptyFunctionTest.js b/js/js.translator/testData/box/jsAstOptimizations/inlineEmptyFunctionTest.js new file mode 100644 index 00000000000..d0e8517978b --- /dev/null +++ b/js/js.translator/testData/box/jsAstOptimizations/inlineEmptyFunctionTest.js @@ -0,0 +1,77 @@ +function box() { + sep('Simple call'); + // Inline function 'inlineFunction' call + // Inline function 'inlineFunction' call + setOK(); + sep('Call in if'); + if (!(flag1 === 0)) { + var tmp; + var tmp_0; + if (equals(OK, 'OK') ? flag1 === 1 : false) { + var tmp_1 = flag2; + tmp_0 = typeof tmp_1 === 'number'; + } else { + tmp_0 = false; + } + if (tmp_0) { + tmp = check_1(); + } else { + tmp = false; + } + if (tmp) { + // Inline function 'inlineFunction' call + } + } + sep('Call in else'); + if (!(flag1 === 0)) { + var tmp_2; + var tmp_3; + if (equals(OK, 'OK') ? flag1 === 1 : false) { + var tmp_4 = flag2; + tmp_3 = typeof tmp_4 === 'number'; + } else { + tmp_3 = false; + } + if (tmp_3) { + tmp_2 = check_1(); + } else { + tmp_2 = false; + } + if (tmp_2) { + check_1(); + check_1(); + } else { + // Inline function 'inlineFunction' call + } + } + sep('Call in while'); + while (!equals(OK, 'OK')) { + // Inline function 'inlineFunction' call + } + sep('Call in when'); + var tmp0_subject = OK; + if (!(tmp0_subject == null) ? typeof tmp0_subject === 'string' : false) { + // Inline function 'inlineFunction' call + } else { + if (isNumber(tmp0_subject)) { + // Inline function 'inlineFunction' call + } + } + sep('Call in try/catch/finally'); + try { + // Inline function 'inlineFunction' call + } catch ($p) { + if ($p instanceof Exception) { + var e = $p; + // Inline function 'inlineFunction' call + } else { + throw $p; + } + } + finally { + // Inline function 'inlineFunction' call + } + sep('End'); + var tmp_5 = OK; + return (!(tmp_5 == null) ? typeof tmp_5 === 'string' : false) ? tmp_5 : THROW_CCE(); +}