From a84c2a6f3180c6576bae0e1f09410f7cfb9ffba1 Mon Sep 17 00:00:00 2001 From: Dmitry Petrov Date: Tue, 20 Jun 2017 17:08:39 +0300 Subject: [PATCH] Improve string concatentation & string templates code generation Reuse StringBuilder instances for nested subexpressions. (NB StringBuilder instance for string template with a string concatenation inside an expression entry, such as `"${"a" + "b"}"`, will not be reused, although that doesn't seem to be a real-life issue). #KT-18558 Fixed Target versions 1.1.4 #KT-13682 Fixed Target versions 1.1.4 Join adjacent strings literals, escaped strings, and constant values (in a language version that supports const val inlining). Use StringBuilder#append(char) for single-character constants (e.g., " " in "$a $b"). #KT-17280 Fixed Target versions 1.1.4 #KT-15235 Fixed Target versions 1.1.4 --- .../kotlin/codegen/ExpressionCodegen.java | 159 +++++++++++++----- .../kotlin/codegen/intrinsics/Concat.kt | 6 +- .../kotlin/backend/jvm/intrinsics/Concat.kt | 6 +- .../testData/codegen/box/constants/kt9532.kt | 9 +- .../codegen/box/constants/kt9532_lv10.kt | 34 ++++ .../box/strings/constInStringTemplate.kt | 25 +++ .../codegen/box/strings/nestedConcat.kt | 21 +++ .../testData/codegen/bytecodeText/kt5016.kt | 2 +- .../codegen/bytecodeText/kt5016int.kt | 2 +- .../codegen/bytecodeText/kt5016intOrNull.kt | 2 +- .../bytecodeText/stringOperations/kt15235.kt | 4 + .../stringOperations/nestedConcat.kt | 15 ++ .../ir/IrBlackBoxCodegenTestGenerated.java | 18 ++ .../codegen/BlackBoxCodegenTestGenerated.java | 18 ++ .../codegen/BytecodeTextTestGenerated.java | 12 ++ .../LightAnalysisModeTestGenerated.java | 18 ++ .../semantics/JsCodegenBoxTestGenerated.java | 18 ++ 17 files changed, 313 insertions(+), 56 deletions(-) create mode 100644 compiler/testData/codegen/box/constants/kt9532_lv10.kt create mode 100644 compiler/testData/codegen/box/strings/constInStringTemplate.kt create mode 100644 compiler/testData/codegen/box/strings/nestedConcat.kt create mode 100644 compiler/testData/codegen/bytecodeText/stringOperations/kt15235.kt create mode 100644 compiler/testData/codegen/bytecodeText/stringOperations/nestedConcat.kt diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java index d31f303077e..d4e8956f7ff 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java @@ -74,8 +74,7 @@ import org.jetbrains.kotlin.resolve.calls.model.*; import org.jetbrains.kotlin.resolve.calls.util.CallMaker; import org.jetbrains.kotlin.resolve.calls.util.FakeCallableDescriptorForObject; import org.jetbrains.kotlin.resolve.calls.util.UnderscoreUtilKt; -import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant; -import org.jetbrains.kotlin.resolve.constants.ConstantValue; +import org.jetbrains.kotlin.resolve.constants.*; import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator; import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluatorKt; import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt; @@ -826,14 +825,71 @@ public class ExpressionCodegen extends KtVisitor impleme @Override public StackValue visitStringTemplateExpression(@NotNull KtStringTemplateExpression expression, StackValue receiver) { - StringBuilder constantValue = new StringBuilder(""); - KtStringTemplateEntry[] entries = expression.getEntries(); + List entries = preprocessStringTemplate(expression); - if (entries.length == 1 && entries[0] instanceof KtStringTemplateEntryWithExpression) { - KtExpression expr = entries[0].getExpression(); - return genToString(gen(expr), expressionType(expr)); + if (entries.size() == 1) { + StringTemplateEntry entry = entries.get(0); + if (entry instanceof StringTemplateEntry.Expression) { + KtExpression expr = ((StringTemplateEntry.Expression) entry).expression; + return genToString(gen(expr), expressionType(expr)); + } + else { + Type type = expressionType(expression); + return StackValue.constant(((StringTemplateEntry.Constant) entry).value, type); + } } + return StackValue.operation(JAVA_STRING_TYPE, v -> { + genStringBuilderConstructor(v); + invokeAppendForEntries(v, entries); + v.invokevirtual("java/lang/StringBuilder", "toString", "()Ljava/lang/String;", false); + return Unit.INSTANCE; + }); + } + + private void invokeAppendForEntries(InstructionAdapter v, List entries) { + for (StringTemplateEntry entry : entries) { + if (entry instanceof StringTemplateEntry.Expression) { + invokeAppend(v, ((StringTemplateEntry.Expression) entry).expression); + } + else { + String value = ((StringTemplateEntry.Constant) entry).value; + if (value.length() == 1) { + v.iconst(value.charAt(0)); + genInvokeAppendMethod(v, Type.CHAR_TYPE); + } + else { + v.aconst(value); + genInvokeAppendMethod(v, JAVA_STRING_TYPE); + } + } + } + } + + private static abstract class StringTemplateEntry { + static class Constant extends StringTemplateEntry { + final String value; + + Constant(String value) { + this.value = value; + } + } + + static class Expression extends StringTemplateEntry { + final KtExpression expression; + + Expression(KtExpression expression) { + this.expression = expression; + } + } + } + + private @NotNull List preprocessStringTemplate(@NotNull KtStringTemplateExpression expression) { + KtStringTemplateEntry[] entries = expression.getEntries(); + + List result = new ArrayList<>(entries.length); + + StringBuilder constantValue = new StringBuilder(""); for (KtStringTemplateEntry entry : entries) { if (entry instanceof KtLiteralStringTemplateEntry) { constantValue.append(entry.getText()); @@ -841,36 +897,46 @@ public class ExpressionCodegen extends KtVisitor impleme else if (entry instanceof KtEscapeStringTemplateEntry) { constantValue.append(((KtEscapeStringTemplateEntry) entry).getUnescapedValue()); } + else if (entry instanceof KtStringTemplateEntryWithExpression) { + KtExpression entryExpression = entry.getExpression(); + if (entryExpression == null) throw new AssertionError("No expression in " + entry); + + ConstantValue compileTimeConstant = + getPrimitiveOrStringCompileTimeConstant(entryExpression, bindingContext, state.getShouldInlineConstVals()); + + if (compileTimeConstant != null && isConstantValueInlinableInStringTemplate(compileTimeConstant)) { + constantValue.append(String.valueOf(compileTimeConstant.getValue())); + } + else { + result.add(new StringTemplateEntry.Constant(constantValue.toString())); + constantValue.setLength(0); + + result.add(new StringTemplateEntry.Expression(entryExpression)); + } + } else { - constantValue = null; - break; + throw new AssertionError("Unexpected string template entry: " + entry); } } - if (constantValue != null) { - Type type = expressionType(expression); - return StackValue.constant(constantValue.toString(), type); - } - else { - return StackValue.operation(JAVA_STRING_TYPE, v -> { - genStringBuilderConstructor(v); - for (KtStringTemplateEntry entry : entries) { - if (entry instanceof KtStringTemplateEntryWithExpression) { - invokeAppend(entry.getExpression()); - } - else { - String text = entry instanceof KtEscapeStringTemplateEntry - ? ((KtEscapeStringTemplateEntry) entry).getUnescapedValue() - : entry.getText(); - v.aconst(text); - genInvokeAppendMethod(v, JAVA_STRING_TYPE); - } - } - v.invokevirtual("java/lang/StringBuilder", "toString", "()Ljava/lang/String;", false); - return Unit.INSTANCE; - }); + + String leftoverConstantValue = constantValue.toString(); + if (leftoverConstantValue.length() > 0) { + result.add(new StringTemplateEntry.Constant(leftoverConstantValue)); } + + return result; } + private static boolean isConstantValueInlinableInStringTemplate(@NotNull ConstantValue constant) { + return constant instanceof StringValue || + constant instanceof BooleanValue || + constant instanceof DoubleValue || + constant instanceof FloatValue || + constant instanceof IntegerValueConstant || + constant instanceof NullValue; + } + + @Override public StackValue visitBlockExpression(@NotNull KtBlockExpression expression, StackValue receiver) { return generateBlock(expression, false); @@ -3250,22 +3316,31 @@ public class ExpressionCodegen extends KtVisitor impleme } } - public void invokeAppend(KtExpression expr) { + public void invokeAppend(InstructionAdapter v, KtExpression expr) { + expr = KtPsiUtil.safeDeparenthesize(expr); + ConstantValue compileTimeConstant = getPrimitiveOrStringCompileTimeConstant(expr, bindingContext, state.getShouldInlineConstVals()); - if (compileTimeConstant == null && expr instanceof KtBinaryExpression) { - KtBinaryExpression binaryExpression = (KtBinaryExpression) expr; - if (binaryExpression.getOperationToken() == KtTokens.PLUS) { - KtExpression left = binaryExpression.getLeft(); - KtExpression right = binaryExpression.getRight(); - Type leftType = expressionType(left); + if (compileTimeConstant == null) { + if (expr instanceof KtBinaryExpression) { + KtBinaryExpression binaryExpression = (KtBinaryExpression) expr; + if (binaryExpression.getOperationToken() == KtTokens.PLUS) { + KtExpression left = binaryExpression.getLeft(); + KtExpression right = binaryExpression.getRight(); + Type leftType = expressionType(left); - if (leftType.equals(JAVA_STRING_TYPE)) { - invokeAppend(left); - invokeAppend(right); - return; + if (leftType.equals(JAVA_STRING_TYPE)) { + invokeAppend(v, left); + invokeAppend(v, right); + return; + } } } + else if (expr instanceof KtStringTemplateExpression) { + List entries = preprocessStringTemplate((KtStringTemplateExpression) expr); + invokeAppendForEntries(v, entries); + return; + } } Type exprType = expressionType(expr); diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/Concat.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/Concat.kt index 3d4d532e8f6..b590386f20b 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/Concat.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/Concat.kt @@ -42,8 +42,8 @@ class Concat : IntrinsicMethod() { if (element is KtBinaryExpression && element.operationReference.getReferencedNameElementType() == KtTokens.PLUS) { // LHS + RHS genStringBuilderConstructor(v) - codegen.invokeAppend(element.left) - codegen.invokeAppend(element.right) + codegen.invokeAppend(v, element.left) + codegen.invokeAppend(v, element.right) } else { // Explicit plus call LHS?.plus(RHS) or LHS.plus(RHS) @@ -51,7 +51,7 @@ class Concat : IntrinsicMethod() { genStringBuilderConstructor(v) v.swap() genInvokeAppendMethod(v, returnType) - codegen.invokeAppend(arguments[0]) + codegen.invokeAppend(v, arguments[0]) } v.invokevirtual("java/lang/StringBuilder", "toString", "()Ljava/lang/String;", false) diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/Concat.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/Concat.kt index ffe869d4719..88160866b95 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/Concat.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/Concat.kt @@ -48,8 +48,8 @@ class Concat : IntrinsicMethod() { if (element is KtBinaryExpression && element.operationReference.getReferencedNameElementType() == KtTokens.PLUS) { // LHS + RHS genStringBuilderConstructor(v) - codegen.invokeAppend(element.left) - codegen.invokeAppend(element.right) + codegen.invokeAppend(v, element.left) + codegen.invokeAppend(v, element.right) } else { // LHS?.plus(RHS) @@ -57,7 +57,7 @@ class Concat : IntrinsicMethod() { genStringBuilderConstructor(v) v.swap() genInvokeAppendMethod(v, returnType) - codegen.invokeAppend(arguments.get(0)) + codegen.invokeAppend(v, arguments.get(0)) } v.invokevirtual("java/lang/StringBuilder", "toString", "()Ljava/lang/String;", false) diff --git a/compiler/testData/codegen/box/constants/kt9532.kt b/compiler/testData/codegen/box/constants/kt9532.kt index 0073c9670b5..83487d3d28e 100644 --- a/compiler/testData/codegen/box/constants/kt9532.kt +++ b/compiler/testData/codegen/box/constants/kt9532.kt @@ -1,5 +1,4 @@ // TODO: muted automatically, investigate should it be ran for JS or not -// IGNORE_BACKEND: JS object A { const val a: String = "$" @@ -7,7 +6,7 @@ object A { const val c = 10000 val bNonConst = "1234$a" - val bNullable: String = "1234$a" + val bNullable: String? = "1234$a" } object B { @@ -16,7 +15,7 @@ object B { const val c = 10000 val bNonConst = "1234$a" - val bNullable: String = "1234$a" + val bNullable: String? = "1234$a" } fun box(): String { @@ -26,8 +25,8 @@ fun box(): String { if (A.c !== B.c) return "Fail 3: A.c !== B.c" - if (A.bNonConst === B.bNonConst) return "Fail 5: A.bNonConst == B.bNonConst" - if (A.bNullable === B.bNullable) return "Fail 6: A.bNullable == B.bNullable" + if (A.bNonConst !== B.bNonConst) return "Fail 4: A.bNonConst !== B.bNonConst" + if (A.bNullable !== B.bNullable) return "Fail 5: A.bNullable !== B.bNullable" return "OK" } \ No newline at end of file diff --git a/compiler/testData/codegen/box/constants/kt9532_lv10.kt b/compiler/testData/codegen/box/constants/kt9532_lv10.kt new file mode 100644 index 00000000000..828d90fa11a --- /dev/null +++ b/compiler/testData/codegen/box/constants/kt9532_lv10.kt @@ -0,0 +1,34 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS +// LANGUAGE_VERSION: 1.0 + +object A { + const val a: String = "$" + const val b = "1234$a" + const val c = 10000 + + val bNonConst = "1234$a" + val bNullable: String? = "1234$a" +} + +object B { + const val a: String = "$" + const val b = "1234$a" + const val c = 10000 + + val bNonConst = "1234$a" + val bNullable: String? = "1234$a" +} + +fun box(): String { + if (A.a !== B.a) return "Fail 1: A.a !== B.a" + + if (A.b !== B.b) return "Fail 2: A.b !== B.b" + + if (A.c !== B.c) return "Fail 3: A.c !== B.c" + + if (A.bNonConst === B.bNonConst) return "Fail 4: A.bNonConst === B.bNonConst" + if (A.bNullable === B.bNullable) return "Fail 5: A.bNullable === B.bNullable" + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/strings/constInStringTemplate.kt b/compiler/testData/codegen/box/strings/constInStringTemplate.kt new file mode 100644 index 00000000000..5595599889d --- /dev/null +++ b/compiler/testData/codegen/box/strings/constInStringTemplate.kt @@ -0,0 +1,25 @@ +// WITH_RUNTIME + +import kotlin.test.assertEquals + +const val constTrue = true +const val const42 = 42 +const val constPiF = 3.14F +const val constPi = 3.1415926358 +const val constString = "string" + +fun box(): String { + assertEquals("true", "$constTrue") + assertEquals("42", "$const42") + assertEquals("3.14", "$constPiF") + assertEquals("3.1415926358", "$constPi") + assertEquals("string", "$constString") + + assertEquals(constPi.toString(), "$constPi") + assertEquals((constPi * constPi).toString(), "${constPi * constPi}") + + assertEquals("null", "${null}") + assertEquals("42", "${42}") + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/strings/nestedConcat.kt b/compiler/testData/codegen/box/strings/nestedConcat.kt new file mode 100644 index 00000000000..6c27ecec29e --- /dev/null +++ b/compiler/testData/codegen/box/strings/nestedConcat.kt @@ -0,0 +1,21 @@ +// WITH_RUNTIME + +import kotlin.test.assertEquals + +fun test1(s1: String, s2: String, s3: String) = + (s1 + s2) + s3 + +fun test2(s1: String, s2: String, s3: String) = + s1 + (s2 + s3) + +fun test3(s1: String, s2: String, s3: String) = + "s1: $s1; " + + "s2: $s2; " + + "s3: $s3" + +fun box(): String { + assertEquals("123", test1("1", "2", "3")) + assertEquals("123", test2("1", "2", "3")) + assertEquals("s1: 1; s2: 2; s3: 3", test3("1", "2", "3")) + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/kt5016.kt b/compiler/testData/codegen/bytecodeText/kt5016.kt index d8d795e8be1..c183af84c90 100644 --- a/compiler/testData/codegen/bytecodeText/kt5016.kt +++ b/compiler/testData/codegen/bytecodeText/kt5016.kt @@ -6,5 +6,5 @@ class kt5016 { } // 0 INVOKEVIRTUAL java/lang/StringBuilder.append \(Ljava/lang/Object;\)Ljava/lang/StringBuilder -// 3 INVOKEVIRTUAL java/lang/StringBuilder.append \(Ljava/lang/String;\)Ljava/lang/StringBuilder +// 2 INVOKEVIRTUAL java/lang/StringBuilder.append \(Ljava/lang/String;\)Ljava/lang/StringBuilder // 1 INVOKEVIRTUAL java/lang/StringBuilder.toString diff --git a/compiler/testData/codegen/bytecodeText/kt5016int.kt b/compiler/testData/codegen/bytecodeText/kt5016int.kt index 62727ef5e67..acfaeb2f4cf 100644 --- a/compiler/testData/codegen/bytecodeText/kt5016int.kt +++ b/compiler/testData/codegen/bytecodeText/kt5016int.kt @@ -6,6 +6,6 @@ class kt5016int { } // 0 INVOKEVIRTUAL java/lang/StringBuilder.append \(Ljava/lang/Object;\)Ljava/lang/StringBuilder -// 2 INVOKEVIRTUAL java/lang/StringBuilder.append \(Ljava/lang/String;\)Ljava/lang/StringBuilder +// 1 INVOKEVIRTUAL java/lang/StringBuilder.append \(Ljava/lang/String;\)Ljava/lang/StringBuilder // 1 INVOKEVIRTUAL java/lang/StringBuilder.append \(I\)Ljava/lang/StringBuilder // 1 INVOKEVIRTUAL java/lang/StringBuilder.toString diff --git a/compiler/testData/codegen/bytecodeText/kt5016intOrNull.kt b/compiler/testData/codegen/bytecodeText/kt5016intOrNull.kt index fcd1efb4178..5ce97809d5e 100644 --- a/compiler/testData/codegen/bytecodeText/kt5016intOrNull.kt +++ b/compiler/testData/codegen/bytecodeText/kt5016intOrNull.kt @@ -6,5 +6,5 @@ class kt5016intOrNull { } // 1 INVOKEVIRTUAL java/lang/StringBuilder.append \(Ljava/lang/Object;\)Ljava/lang/StringBuilder -// 2 INVOKEVIRTUAL java/lang/StringBuilder.append \(Ljava/lang/String;\)Ljava/lang/StringBuilder +// 1 INVOKEVIRTUAL java/lang/StringBuilder.append \(Ljava/lang/String;\)Ljava/lang/StringBuilder // 1 INVOKEVIRTUAL java/lang/StringBuilder.toString diff --git a/compiler/testData/codegen/bytecodeText/stringOperations/kt15235.kt b/compiler/testData/codegen/bytecodeText/stringOperations/kt15235.kt new file mode 100644 index 00000000000..d228458da1a --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/stringOperations/kt15235.kt @@ -0,0 +1,4 @@ +val c = 1 +fun foo() = "a\"($c)\"d" + +// 3 INVOKEVIRTUAL java/lang/StringBuilder.append \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/stringOperations/nestedConcat.kt b/compiler/testData/codegen/bytecodeText/stringOperations/nestedConcat.kt new file mode 100644 index 00000000000..ec7f120355e --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/stringOperations/nestedConcat.kt @@ -0,0 +1,15 @@ +fun test1(s1: String, s2: String, s3: String) = + (s1 + s2) + s3 + +fun test2(s1: String, s2: String, s3: String) = + s1 + (s2 + s3) + +fun test3(s1: String, s2: String, s3: String, s4: String) = + ((s1 + s2) + ((s3 + s4))) + +fun test4(s1: String, s2: String, s3: String) = + "s1: $s1; " + + "s2: $s2; " + + "s3: $s3" + +// 4 NEW java/lang/StringBuilder \ No newline at end of file diff --git a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index ef259388d07..827d670641c 100644 --- a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -4157,6 +4157,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes doTest(fileName); } + @TestMetadata("kt9532_lv10.kt") + public void testKt9532_lv10() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/constants/kt9532_lv10.kt"); + doTest(fileName); + } + @TestMetadata("long.kt") public void testLong() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/constants/long.kt"); @@ -17510,6 +17516,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/strings"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true); } + @TestMetadata("constInStringTemplate.kt") + public void testConstInStringTemplate() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/strings/constInStringTemplate.kt"); + doTest(fileName); + } + @TestMetadata("ea35743.kt") public void testEa35743() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/strings/ea35743.kt"); @@ -17582,6 +17594,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes doTest(fileName); } + @TestMetadata("nestedConcat.kt") + public void testNestedConcat() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/strings/nestedConcat.kt"); + doTest(fileName); + } + @TestMetadata("rawStrings.kt") public void testRawStrings() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/strings/rawStrings.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index e81287feb73..f589f03c130 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -4157,6 +4157,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest(fileName); } + @TestMetadata("kt9532_lv10.kt") + public void testKt9532_lv10() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/constants/kt9532_lv10.kt"); + doTest(fileName); + } + @TestMetadata("long.kt") public void testLong() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/constants/long.kt"); @@ -17510,6 +17516,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/strings"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true); } + @TestMetadata("constInStringTemplate.kt") + public void testConstInStringTemplate() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/strings/constInStringTemplate.kt"); + doTest(fileName); + } + @TestMetadata("ea35743.kt") public void testEa35743() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/strings/ea35743.kt"); @@ -17582,6 +17594,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest(fileName); } + @TestMetadata("nestedConcat.kt") + public void testNestedConcat() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/strings/nestedConcat.kt"); + doTest(fileName); + } + @TestMetadata("rawStrings.kt") public void testRawStrings() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/strings/rawStrings.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java index 00397e98cc5..62077c742b0 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java @@ -1988,6 +1988,18 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest { doTest(fileName); } + @TestMetadata("kt15235.kt") + public void testKt15235() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/stringOperations/kt15235.kt"); + doTest(fileName); + } + + @TestMetadata("nestedConcat.kt") + public void testNestedConcat() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/stringOperations/nestedConcat.kt"); + doTest(fileName); + } + @TestMetadata("nonNullableStringPlus.kt") public void testNonNullableStringPlus() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/stringOperations/nonNullableStringPlus.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 05bfdddba9d..aee39ba859f 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -4157,6 +4157,12 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes doTest(fileName); } + @TestMetadata("kt9532_lv10.kt") + public void testKt9532_lv10() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/constants/kt9532_lv10.kt"); + doTest(fileName); + } + @TestMetadata("long.kt") public void testLong() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/constants/long.kt"); @@ -17510,6 +17516,12 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/strings"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true); } + @TestMetadata("constInStringTemplate.kt") + public void testConstInStringTemplate() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/strings/constInStringTemplate.kt"); + doTest(fileName); + } + @TestMetadata("ea35743.kt") public void testEa35743() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/strings/ea35743.kt"); @@ -17582,6 +17594,12 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes doTest(fileName); } + @TestMetadata("nestedConcat.kt") + public void testNestedConcat() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/strings/nestedConcat.kt"); + doTest(fileName); + } + @TestMetadata("rawStrings.kt") public void testRawStrings() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/strings/rawStrings.kt"); diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index bffaf39ec30..4322497dded 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -4796,6 +4796,12 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { @TestMetadata("kt9532.kt") public void testKt9532() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/constants/kt9532.kt"); + doTest(fileName); + } + + @TestMetadata("kt9532_lv10.kt") + public void testKt9532_lv10() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/constants/kt9532_lv10.kt"); try { doTest(fileName); } @@ -21512,6 +21518,12 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/strings"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JS, true); } + @TestMetadata("constInStringTemplate.kt") + public void testConstInStringTemplate() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/strings/constInStringTemplate.kt"); + doTest(fileName); + } + @TestMetadata("ea35743.kt") public void testEa35743() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/strings/ea35743.kt"); @@ -21590,6 +21602,12 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { doTest(fileName); } + @TestMetadata("nestedConcat.kt") + public void testNestedConcat() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/strings/nestedConcat.kt"); + doTest(fileName); + } + @TestMetadata("rawStrings.kt") public void testRawStrings() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/strings/rawStrings.kt");