diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/IrElementToJsExpressionTransformer.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/IrElementToJsExpressionTransformer.kt index 6645e64a797..3d85bf5404c 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/IrElementToJsExpressionTransformer.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/IrElementToJsExpressionTransformer.kt @@ -13,6 +13,7 @@ import org.jetbrains.kotlin.ir.backend.js.utils.emptyScope import org.jetbrains.kotlin.ir.backend.js.utils.getJsNameOrKotlinName import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.expressions.* +import org.jetbrains.kotlin.ir.types.isString import org.jetbrains.kotlin.ir.types.isUnit import org.jetbrains.kotlin.ir.util.isEffectivelyExternal import org.jetbrains.kotlin.ir.util.isEnumClass @@ -68,7 +69,15 @@ class IrElementToJsExpressionTransformer : BaseIrElementToJsNodeTransformer(JsStringLiteral("")) { jsExpr, irExpr -> + + val firstArgument = expression.arguments.firstOrNull() + val (head, tail) = if (firstArgument?.type?.isString() == true) { + Pair(firstArgument.accept(this, context), expression.arguments.asSequence().drop(1)) + } else { + Pair(JsStringLiteral(""), expression.arguments.asSequence()) + } + + return tail.fold(head) { jsExpr, irExpr -> JsBinaryOperation( JsBinaryOperator.ADD, jsExpr, diff --git a/compiler/testData/codegen/box/strings/interpolation.kt b/compiler/testData/codegen/box/strings/interpolation.kt index 772cb33771a..c1e11e0cbb8 100644 --- a/compiler/testData/codegen/box/strings/interpolation.kt +++ b/compiler/testData/codegen/box/strings/interpolation.kt @@ -1,9 +1,33 @@ +// CHECK_STRING_LITERAL_COUNT: function=foo count=1 +fun foo(x: Int) = "foo $x" + +// CHECK_STRING_LITERAL_COUNT: function=bar count=2 IGNORED_BACKENDS=JS +fun bar(x: Int) = "$x bar" + +// CHECK_STRING_LITERAL_COUNT: function=baz count=1 +fun baz(x: Int) = "${x.toString()} baz" + +// CHECK_STRING_LITERAL_COUNT: function=beer count=2 IGNORED_BACKENDS=JS +fun beer(x: Int?) = "$x beer" + +// CHECK_STRING_LITERAL_COUNT: function=quux count=2 IGNORED_BACKENDS=JS +fun quux(x: Int?) = "${x?.toString()} quux" + +// CHECK_STRING_LITERAL_COUNT: function=test count=2 fun test(p: String?): String { return "${p ?: "Default"} test" } + fun box(): String { if (test(null) != "Default test") return "fail 1: ${test(null)}" - if (test("Good") != "Good test") return "fail 1: ${test("OK")}" + if (test("Good") != "Good test") return "fail 2: ${test("Good")}" + if (foo(3) != "foo 3") return "fail 3: ${foo(3)}" + if (bar(4) != "4 bar") return "fail 4: ${bar(4)}" + if (baz(5) != "5 baz") return "fail 5: ${baz(5)}" + if (beer(6) != "6 beer") return "fail 6: ${beer(6)}" + if (beer(null) != "null beer") return "fail 7: ${beer(null)}" + if (quux(8) != "8 quux") return "fail 8: ${quux(8)}" + if (quux(null) != "null quux") return "fail 9: ${quux(null)}" return "OK" } \ No newline at end of file diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/testOld/utils/DirectiveTestUtils.java b/js/js.tests/test/org/jetbrains/kotlin/js/testOld/utils/DirectiveTestUtils.java index f2e26957a2d..7110e557630 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/testOld/utils/DirectiveTestUtils.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/testOld/utils/DirectiveTestUtils.java @@ -224,6 +224,8 @@ public class DirectiveTestUtils { private static final DirectiveHandler COUNT_DEBUGGER = new CountNodesDirective<>("CHECK_DEBUGGER_COUNT", JsDebugger.class); + private static final DirectiveHandler COUNT_STRING_LITERALS = new CountNodesDirective<>("CHECK_STRING_LITERAL_COUNT", JsStringLiteral.class); + private static final DirectiveHandler NOT_REFERENCED = new DirectiveHandler("CHECK_NOT_REFERENCED") { @Override void processEntry(@NotNull JsNode ast, @NotNull ArgumentsHelper arguments) throws Exception { @@ -365,6 +367,7 @@ public class DirectiveTestUtils { COUNT_CASES, COUNT_IF, COUNT_DEBUGGER, + COUNT_STRING_LITERALS, NOT_REFERENCED, HAS_INLINE_METADATA, HAS_NO_INLINE_METADATA,