JVM_IR fix string concatenation performance issues

KT-50080 KT-50084 KT-50140
This commit is contained in:
Dmitry Petrov
2021-12-08 18:09:52 +03:00
committed by TeamCityServer
parent fa41e0f5a9
commit 3017397960
18 changed files with 451 additions and 34 deletions
@@ -42664,6 +42664,30 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/strings/concatDynamicWithSpecialSymbols.kt");
}
@Test
@TestMetadata("concatGenericWithNullablePrimitiveUpperBound.kt")
public void testConcatGenericWithNullablePrimitiveUpperBound() throws Exception {
runTest("compiler/testData/codegen/box/strings/concatGenericWithNullablePrimitiveUpperBound.kt");
}
@Test
@TestMetadata("concatGenericWithPrimitiveUpperBound.kt")
public void testConcatGenericWithPrimitiveUpperBound() throws Exception {
runTest("compiler/testData/codegen/box/strings/concatGenericWithPrimitiveUpperBound.kt");
}
@Test
@TestMetadata("concatGenericWithStringUpperBound.kt")
public void testConcatGenericWithStringUpperBound() throws Exception {
runTest("compiler/testData/codegen/box/strings/concatGenericWithStringUpperBound.kt");
}
@Test
@TestMetadata("concatNullableGenericWithPrimitiveUpperBound.kt")
public void testConcatNullableGenericWithPrimitiveUpperBound() throws Exception {
runTest("compiler/testData/codegen/box/strings/concatNullableGenericWithPrimitiveUpperBound.kt");
}
@Test
@TestMetadata("constInStringTemplate.kt")
public void testConstInStringTemplate() throws Exception {
@@ -42736,6 +42760,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/strings/kt47917.kt");
}
@Test
@TestMetadata("kt50140.kt")
public void testKt50140() throws Exception {
runTest("compiler/testData/codegen/box/strings/kt50140.kt");
}
@Test
@TestMetadata("kt5389_stringBuilderGet.kt")
public void testKt5389_stringBuilderGet() throws Exception {
@@ -81,10 +81,10 @@ class FlattenStringConcatenationLowering(val context: CommonBackendContext) : Fi
private val IrCall.isStringPlusCall: Boolean
get() {
val function = symbol.owner
val receiver = dispatchReceiver ?: extensionReceiver
val receiverParameter = function.dispatchReceiverParameter ?: function.extensionReceiverParameter
return receiver != null
&& receiver.type.isStringClassType()
return receiverParameter != null
&& receiverParameter.type.isStringClassType()
&& function.returnType.isStringClassType()
&& function.valueParameters.size == 1
&& function.name == OperatorNameConventions.PLUS
@@ -13,12 +13,14 @@ import org.jetbrains.kotlin.backend.common.lower.loops.forLoopsPhase
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
import org.jetbrains.kotlin.backend.jvm.InlineClassAbi
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.codegen.representativeUpperBound
import org.jetbrains.kotlin.backend.jvm.ir.JvmIrBuilder
import org.jetbrains.kotlin.backend.jvm.ir.createJvmIrBuilder
import org.jetbrains.kotlin.ir.builders.*
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.IrStringConcatenationImpl
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.util.constructors
import org.jetbrains.kotlin.ir.util.functions
@@ -43,22 +45,6 @@ private val IrClass.toStringFunction: IrSimpleFunction
with(FlattenStringConcatenationLowering) { it.isToString }
}
private fun IrBuilderWithScope.normalizeArgument(expression: IrExpression): IrExpression =
if (expression.type.isByte() || expression.type.isShort()) {
// There is no special append or valueOf function for byte and short on the JVM.
irImplicitCast(expression, context.irBuiltIns.intType)
} else if (expression is IrConst<*> && expression.kind == IrConstKind.String && (expression.value as String).length == 1) {
// PSI2IR generates const Strings for 1-length literals in string templates (e.g., the space between x and y in "$x $y").
// We want to use the more efficient `append(Char)` function in such cases. This mirrors the behavior of the non-IR backend.
//
// In addition, this also means `append(Char)` will be used for the space in the following case: `x + " " + y`. The non-IR
// backend will still use `append(String)` in this case.
irChar((expression.value as String)[0])
} else {
expression
}
private fun JvmIrBuilder.callToString(expression: IrExpression): IrExpression {
val argument = normalizeArgument(expression)
val argumentType = if (argument.type.isPrimitiveType()) argument.type else context.irBuiltIns.anyNType
@@ -68,6 +54,51 @@ private fun JvmIrBuilder.callToString(expression: IrExpression): IrExpression {
}
}
private fun JvmIrBuilder.normalizeArgument(expression: IrExpression): IrExpression {
val type = expression.type
if (type.isByte() || type.isShort()) {
// There is no special append or valueOf function for byte and short on the JVM.
return irImplicitCast(expression, context.irBuiltIns.intType)
}
if (expression is IrConst<*> && expression.kind == IrConstKind.String && (expression.value as String).length == 1) {
// PSI2IR generates const Strings for 1-length literals in string templates (e.g., the space between x and y in "$x $y").
// We want to use the more efficient `append(Char)` function in such cases. This mirrors the behavior of the non-IR backend.
//
// In addition, this also means `append(Char)` will be used for the space in the following case: `x + " " + y`.
// The non-IR backend will still use `append(String)` in this case.
// NB KT-50091 shows an outlier where this might be actually less efficient, but in general we prefer `Char`.
return irChar((expression.value as String)[0])
}
val typeParameterSymbol = type.classifierOrNull as? IrTypeParameterSymbol
if (typeParameterSymbol != null) {
// Upcast type parameter to upper bound with specialized 'append' function
val upperBound = typeParameterSymbol.owner.representativeUpperBound
if (upperBound.classifierOrNull == context.irBuiltIns.stringClass) {
// T <: String || T <: String? =>
// upcast to 'String?'
return irImplicitCast(expression, context.irBuiltIns.stringType.makeNullable())
}
if (!(type as IrSimpleType).hasQuestionMark) {
if (upperBound.isByte() || upperBound.isShort()) {
// Expression type is not null,
// T <: Byte || T <: Short =>
// upcast to Int
return irImplicitCast(expression, context.irBuiltIns.intType)
} else if (upperBound.isPrimitiveType()) {
// Expression type is not null,
// T <: P, P is primitive type (other than 'Byte' or 'Short') =>
// upcast to P
return irImplicitCast(expression, upperBound)
}
}
}
return expression
}
private fun JvmIrBuilder.lowerInlineClassArgument(expression: IrExpression): IrExpression? {
if (InlineClassAbi.unboxType(expression.type) == null)
return null
@@ -114,21 +145,33 @@ private class JvmStringConcatenationLowering(val context: JvmBackendContext) : F
private val toStringFunction = stringBuilder.toStringFunction
private val defaultAppendFunction = stringBuilder.functions.single {
it.name.asString() == "append" &&
it.valueParameters.size == 1 &&
it.valueParameters.single().type.isNullableAny()
}
private val appendAnyNFunction =
findStringBuilderAppendFunctionWithParameter { it.type.isNullableAny() }!!
private val appendFunctions: Map<IrType, IrSimpleFunction?> =
(context.irBuiltIns.primitiveIrTypes + context.irBuiltIns.stringType).associateWith { type ->
stringBuilder.functions.singleOrNull {
it.name.asString() == "append" && it.valueParameters.singleOrNull()?.type == type
}
private val appendStringNFunction =
findStringBuilderAppendFunctionWithParameter { it.type.classOrNull == context.irBuiltIns.stringClass }!!
private val appendFunctionsByParameterType: Map<IrType, IrSimpleFunction> =
stringBuilder.functions
.filter { it.isAppendFunction() }
.associateBy { it.valueParameters[0].type }
private inline fun findStringBuilderAppendFunctionWithParameter(predicate: (IrValueParameter) -> Boolean) =
stringBuilder.functions.find {
it.isAppendFunction() && predicate(it.valueParameters[0])
}
private fun typeToAppendFunction(type: IrType): IrSimpleFunction =
appendFunctions[type] ?: defaultAppendFunction
private fun IrSimpleFunction.isAppendFunction() =
name.asString() == "append" && valueParameters.size == 1
private fun typeToAppendFunction(type: IrType): IrSimpleFunction {
appendFunctionsByParameterType[type]?.let { return it }
if (type.classOrNull == context.irBuiltIns.stringClass)
return appendStringNFunction
return appendAnyNFunction
}
override fun visitStringConcatenation(expression: IrStringConcatenation): IrExpression {
expression.transformChildrenVoid(this)
@@ -195,7 +195,13 @@ class JvmSymbols(
overriddenSymbols = overriddenSymbols + any.functionByName("toString")
}
val appendTypes = with(irBuiltIns) { listOf(anyNType, stringType, booleanType, charType, intType, longType, floatType, doubleType) }
val appendTypes = with(irBuiltIns) {
listOf(
anyNType,
stringType.makeNullable(),
booleanType, charType, intType, longType, floatType, doubleType
)
}
for (type in appendTypes) {
klass.addFunction("append", klass.defaultType).apply {
addValueParameter("value", type)
@@ -77,7 +77,7 @@ private fun IrSimpleType.buildPossiblyInnerType(classifier: IrClass?, index: Int
)
}
internal val IrTypeParameter.representativeUpperBound: IrType
val IrTypeParameter.representativeUpperBound: IrType
get() {
assert(superTypes.isNotEmpty()) { "Upper bounds should not be empty: ${render()}" }
@@ -0,0 +1,31 @@
// KOTLIN_CONFIGURATION_FLAGS: STRING_CONCAT=inline
// WITH_STDLIB
// IGNORE_BACKEND: WASM
// ^ wasm-function[2283]:0x218da: RuntimeError: wasm exception
import kotlin.test.assertEquals
fun <T : Boolean?> concatNBoolean(x: T) = "[[$x]]"
fun <T : Byte?> concatNByte(x: T) = "[[$x]]"
fun <T : Short?> concatNShort(x: T) = "[[$x]]"
fun <T : Int?> concatNInt(x: T) = "[[$x]]"
fun <T : Long?> concatNLong(x: T) = "[[$x]]"
fun <T : Float?> concatNFloat(x: T) = "[[$x]]"
fun <T : Double?> concatNDouble(x: T) = "[[$x]]"
fun box(): String {
assertEquals("[[true]]", concatNBoolean(true))
assertEquals("[[0]]", concatNByte(0.toByte()))
assertEquals("[[1]]", concatNShort(1.toShort()))
assertEquals("[[2]]", concatNInt(2))
assertEquals("[[3]]", concatNLong(3L))
assertEquals("[[4.4]]", concatNFloat(4.4f))
assertEquals("[[5.5]]", concatNFloat(5.5f))
return "OK"
}
// CHECK_BYTECODE_TEXT
// JVM_IR_TEMPLATES
// 7 INVOKEVIRTUAL java/lang/StringBuilder\.append \(Ljava/lang/Object;\)Ljava/lang/StringBuilder;
@@ -0,0 +1,35 @@
// KOTLIN_CONFIGURATION_FLAGS: STRING_CONCAT=inline
// WITH_STDLIB
// IGNORE_BACKEND: WASM
// ^ wasm-function[2283]:0x218cc: RuntimeError: wasm exception
import kotlin.test.assertEquals
fun <T : Boolean> concatBoolean(x: T) = "[[$x]]"
fun <T : Byte> concatByte(x: T) = "[[$x]]"
fun <T : Short> concatShort(x: T) = "[[$x]]"
fun <T : Int> concatInt(x: T) = "[[$x]]"
fun <T : Long> concatLong(x: T) = "[[$x]]"
fun <T : Float> concatFloat(x: T) = "[[$x]]"
fun <T : Double> concatDouble(x: T) = "[[$x]]"
fun box(): String {
assertEquals("[[true]]", concatBoolean(true))
assertEquals("[[0]]", concatByte(0.toByte()))
assertEquals("[[1]]", concatShort(1.toShort()))
assertEquals("[[2]]", concatInt(2))
assertEquals("[[3]]", concatLong(3L))
assertEquals("[[4.4]]", concatFloat(4.4f))
assertEquals("[[5.5]]", concatFloat(5.5f))
return "OK"
}
// CHECK_BYTECODE_TEXT
// JVM_IR_TEMPLATES
// 1 INVOKEVIRTUAL java/lang/StringBuilder\.append \(Z\)Ljava/lang/StringBuilder;
// 3 INVOKEVIRTUAL java/lang/StringBuilder\.append \(I\)Ljava/lang/StringBuilder;
// 1 INVOKEVIRTUAL java/lang/StringBuilder\.append \(J\)Ljava/lang/StringBuilder;
// 1 INVOKEVIRTUAL java/lang/StringBuilder\.append \(F\)Ljava/lang/StringBuilder;
// 1 INVOKEVIRTUAL java/lang/StringBuilder\.append \(D\)Ljava/lang/StringBuilder;
@@ -0,0 +1,37 @@
// KOTLIN_CONFIGURATION_FLAGS: STRING_CONCAT=inline
// WITH_STDLIB
import kotlin.test.assertEquals
fun concatAny(x: Any) = "$x!!"
fun <T : String> concat1(x: T) = "[[$x]]"
fun <T : String?> concat2(x: T) = "[[$x]]"
fun <T : String> concat3(x: T?) = "[[$x]]"
fun <T : String> concat4(x: T) = x + "!!"
fun <T : String?> concat5(x: T) = x + "!!"
fun <T : String> concat6(x: T?) = x + "!!"
fun box(): String {
assertEquals("[[1]]", concat1("1"))
assertEquals("[[2]]", concat2("2"))
assertEquals("[[null]]", concat2(null))
assertEquals("[[3]]", concat3("3"))
assertEquals("[[null]]", concat3(null))
assertEquals("4!!", concat4("4"))
assertEquals("5!!", concat5("5"))
assertEquals("null!!", concat5("null"))
assertEquals("6!!", concat5("6"))
assertEquals("null!!", concat5("null"))
return "OK"
}
// CHECK_BYTECODE_TEXT
// JVM_IR_TEMPLATES
// 1 INVOKEVIRTUAL java/lang/StringBuilder\.append \(Ljava/lang/Object;\)Ljava/lang/StringBuilder;
// ^ single instance of 'StringBuilder.append(Object)' from 'concatAny',
// keep it here to make sure there's no error in regexp.
// 16 INVOKEVIRTUAL java/lang/StringBuilder\.append \(Ljava/lang/String;\)Ljava/lang/StringBuilder;
// ^ everything else is done with 'StringBuilder.append(String)'
// 17 INVOKEVIRTUAL java/lang/StringBuilder\.append
// ^ no other instances of StringBuidler.append(...)
@@ -0,0 +1,31 @@
// KOTLIN_CONFIGURATION_FLAGS: STRING_CONCAT=inline
// WITH_STDLIB
// IGNORE_BACKEND: WASM
// ^ wasm-function[2283]:0x218da: RuntimeError: wasm exception
import kotlin.test.assertEquals
fun <T : Boolean> concatNBoolean(x: T?) = "[[$x]]"
fun <T : Byte> concatNByte(x: T?) = "[[$x]]"
fun <T : Short> concatNShort(x: T?) = "[[$x]]"
fun <T : Int> concatNInt(x: T?) = "[[$x]]"
fun <T : Long> concatNLong(x: T?) = "[[$x]]"
fun <T : Float> concatNFloat(x: T?) = "[[$x]]"
fun <T : Double> concatNDouble(x: T?) = "[[$x]]"
fun box(): String {
assertEquals("[[true]]", concatNBoolean(true))
assertEquals("[[0]]", concatNByte(0.toByte()))
assertEquals("[[1]]", concatNShort(1.toShort()))
assertEquals("[[2]]", concatNInt(2))
assertEquals("[[3]]", concatNLong(3L))
assertEquals("[[4.4]]", concatNFloat(4.4f))
assertEquals("[[5.5]]", concatNFloat(5.5f))
return "OK"
}
// CHECK_BYTECODE_TEXT
// JVM_IR_TEMPLATES
// 7 INVOKEVIRTUAL java/lang/StringBuilder\.append \(Ljava/lang/Object;\)Ljava/lang/StringBuilder;
+3
View File
@@ -0,0 +1,3 @@
fun <T : String> concat4(x: T) = x + "K"
fun box() = concat4("O")
@@ -5,5 +5,6 @@ fun foo(x: String?, y: Any?) = x + y
// JVM_IR_TEMPLATES
// 1 NEW java/lang/StringBuilder
// 2 INVOKEVIRTUAL java/lang/StringBuilder\.append \(Ljava/lang/Object;\)Ljava/lang/StringBuilder;
// 1 INVOKEVIRTUAL java/lang/StringBuilder\.append \(Ljava/lang/String;\)Ljava/lang/StringBuilder;
// 1 INVOKEVIRTUAL java/lang/StringBuilder\.append \(Ljava/lang/Object;\)Ljava/lang/StringBuilder;
// 1 INVOKEVIRTUAL java/lang/StringBuilder\.toString \(\)Ljava/lang/String;
@@ -42238,6 +42238,30 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
runTest("compiler/testData/codegen/box/strings/concatDynamicWithSpecialSymbols.kt");
}
@Test
@TestMetadata("concatGenericWithNullablePrimitiveUpperBound.kt")
public void testConcatGenericWithNullablePrimitiveUpperBound() throws Exception {
runTest("compiler/testData/codegen/box/strings/concatGenericWithNullablePrimitiveUpperBound.kt");
}
@Test
@TestMetadata("concatGenericWithPrimitiveUpperBound.kt")
public void testConcatGenericWithPrimitiveUpperBound() throws Exception {
runTest("compiler/testData/codegen/box/strings/concatGenericWithPrimitiveUpperBound.kt");
}
@Test
@TestMetadata("concatGenericWithStringUpperBound.kt")
public void testConcatGenericWithStringUpperBound() throws Exception {
runTest("compiler/testData/codegen/box/strings/concatGenericWithStringUpperBound.kt");
}
@Test
@TestMetadata("concatNullableGenericWithPrimitiveUpperBound.kt")
public void testConcatNullableGenericWithPrimitiveUpperBound() throws Exception {
runTest("compiler/testData/codegen/box/strings/concatNullableGenericWithPrimitiveUpperBound.kt");
}
@Test
@TestMetadata("constInStringTemplate.kt")
public void testConstInStringTemplate() throws Exception {
@@ -42310,6 +42334,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
runTest("compiler/testData/codegen/box/strings/kt47917.kt");
}
@Test
@TestMetadata("kt50140.kt")
public void testKt50140() throws Exception {
runTest("compiler/testData/codegen/box/strings/kt50140.kt");
}
@Test
@TestMetadata("kt5389_stringBuilderGet.kt")
public void testKt5389_stringBuilderGet() throws Exception {
@@ -42664,6 +42664,30 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/strings/concatDynamicWithSpecialSymbols.kt");
}
@Test
@TestMetadata("concatGenericWithNullablePrimitiveUpperBound.kt")
public void testConcatGenericWithNullablePrimitiveUpperBound() throws Exception {
runTest("compiler/testData/codegen/box/strings/concatGenericWithNullablePrimitiveUpperBound.kt");
}
@Test
@TestMetadata("concatGenericWithPrimitiveUpperBound.kt")
public void testConcatGenericWithPrimitiveUpperBound() throws Exception {
runTest("compiler/testData/codegen/box/strings/concatGenericWithPrimitiveUpperBound.kt");
}
@Test
@TestMetadata("concatGenericWithStringUpperBound.kt")
public void testConcatGenericWithStringUpperBound() throws Exception {
runTest("compiler/testData/codegen/box/strings/concatGenericWithStringUpperBound.kt");
}
@Test
@TestMetadata("concatNullableGenericWithPrimitiveUpperBound.kt")
public void testConcatNullableGenericWithPrimitiveUpperBound() throws Exception {
runTest("compiler/testData/codegen/box/strings/concatNullableGenericWithPrimitiveUpperBound.kt");
}
@Test
@TestMetadata("constInStringTemplate.kt")
public void testConstInStringTemplate() throws Exception {
@@ -42736,6 +42760,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/strings/kt47917.kt");
}
@Test
@TestMetadata("kt50140.kt")
public void testKt50140() throws Exception {
runTest("compiler/testData/codegen/box/strings/kt50140.kt");
}
@Test
@TestMetadata("kt5389_stringBuilderGet.kt")
public void testKt5389_stringBuilderGet() throws Exception {
@@ -34040,6 +34040,26 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
runTest("compiler/testData/codegen/box/strings/concatDynamicWithSpecialSymbols.kt");
}
@TestMetadata("concatGenericWithNullablePrimitiveUpperBound.kt")
public void testConcatGenericWithNullablePrimitiveUpperBound() throws Exception {
runTest("compiler/testData/codegen/box/strings/concatGenericWithNullablePrimitiveUpperBound.kt");
}
@TestMetadata("concatGenericWithPrimitiveUpperBound.kt")
public void testConcatGenericWithPrimitiveUpperBound() throws Exception {
runTest("compiler/testData/codegen/box/strings/concatGenericWithPrimitiveUpperBound.kt");
}
@TestMetadata("concatGenericWithStringUpperBound.kt")
public void testConcatGenericWithStringUpperBound() throws Exception {
runTest("compiler/testData/codegen/box/strings/concatGenericWithStringUpperBound.kt");
}
@TestMetadata("concatNullableGenericWithPrimitiveUpperBound.kt")
public void testConcatNullableGenericWithPrimitiveUpperBound() throws Exception {
runTest("compiler/testData/codegen/box/strings/concatNullableGenericWithPrimitiveUpperBound.kt");
}
@TestMetadata("constInStringTemplate.kt")
public void testConstInStringTemplate() throws Exception {
runTest("compiler/testData/codegen/box/strings/constInStringTemplate.kt");
@@ -34085,6 +34105,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
runTest("compiler/testData/codegen/box/strings/kt42457_old.kt");
}
@TestMetadata("kt50140.kt")
public void testKt50140() throws Exception {
runTest("compiler/testData/codegen/box/strings/kt50140.kt");
}
@TestMetadata("kt5389_stringBuilderGet.kt")
public void testKt5389_stringBuilderGet() throws Exception {
runTest("compiler/testData/codegen/box/strings/kt5389_stringBuilderGet.kt");
@@ -30552,6 +30552,30 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/strings/concatDynamicWithSpecialSymbols.kt");
}
@Test
@TestMetadata("concatGenericWithNullablePrimitiveUpperBound.kt")
public void testConcatGenericWithNullablePrimitiveUpperBound() throws Exception {
runTest("compiler/testData/codegen/box/strings/concatGenericWithNullablePrimitiveUpperBound.kt");
}
@Test
@TestMetadata("concatGenericWithPrimitiveUpperBound.kt")
public void testConcatGenericWithPrimitiveUpperBound() throws Exception {
runTest("compiler/testData/codegen/box/strings/concatGenericWithPrimitiveUpperBound.kt");
}
@Test
@TestMetadata("concatGenericWithStringUpperBound.kt")
public void testConcatGenericWithStringUpperBound() throws Exception {
runTest("compiler/testData/codegen/box/strings/concatGenericWithStringUpperBound.kt");
}
@Test
@TestMetadata("concatNullableGenericWithPrimitiveUpperBound.kt")
public void testConcatNullableGenericWithPrimitiveUpperBound() throws Exception {
runTest("compiler/testData/codegen/box/strings/concatNullableGenericWithPrimitiveUpperBound.kt");
}
@Test
@TestMetadata("constInStringTemplate.kt")
public void testConstInStringTemplate() throws Exception {
@@ -30612,6 +30636,12 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/strings/kt47917.kt");
}
@Test
@TestMetadata("kt50140.kt")
public void testKt50140() throws Exception {
runTest("compiler/testData/codegen/box/strings/kt50140.kt");
}
@Test
@TestMetadata("kt5389_stringBuilderGet.kt")
public void testKt5389_stringBuilderGet() throws Exception {
@@ -30654,6 +30654,30 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/strings/concatDynamicWithSpecialSymbols.kt");
}
@Test
@TestMetadata("concatGenericWithNullablePrimitiveUpperBound.kt")
public void testConcatGenericWithNullablePrimitiveUpperBound() throws Exception {
runTest("compiler/testData/codegen/box/strings/concatGenericWithNullablePrimitiveUpperBound.kt");
}
@Test
@TestMetadata("concatGenericWithPrimitiveUpperBound.kt")
public void testConcatGenericWithPrimitiveUpperBound() throws Exception {
runTest("compiler/testData/codegen/box/strings/concatGenericWithPrimitiveUpperBound.kt");
}
@Test
@TestMetadata("concatGenericWithStringUpperBound.kt")
public void testConcatGenericWithStringUpperBound() throws Exception {
runTest("compiler/testData/codegen/box/strings/concatGenericWithStringUpperBound.kt");
}
@Test
@TestMetadata("concatNullableGenericWithPrimitiveUpperBound.kt")
public void testConcatNullableGenericWithPrimitiveUpperBound() throws Exception {
runTest("compiler/testData/codegen/box/strings/concatNullableGenericWithPrimitiveUpperBound.kt");
}
@Test
@TestMetadata("constInStringTemplate.kt")
public void testConstInStringTemplate() throws Exception {
@@ -30714,6 +30738,12 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/strings/kt47917.kt");
}
@Test
@TestMetadata("kt50140.kt")
public void testKt50140() throws Exception {
runTest("compiler/testData/codegen/box/strings/kt50140.kt");
}
@Test
@TestMetadata("kt5389_stringBuilderGet.kt")
public void testKt5389_stringBuilderGet() throws Exception {
@@ -25484,6 +25484,26 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest
runTest("compiler/testData/codegen/box/strings/concatDynamicWithConstants.kt");
}
@TestMetadata("concatGenericWithNullablePrimitiveUpperBound.kt")
public void testConcatGenericWithNullablePrimitiveUpperBound() throws Exception {
runTest("compiler/testData/codegen/box/strings/concatGenericWithNullablePrimitiveUpperBound.kt");
}
@TestMetadata("concatGenericWithPrimitiveUpperBound.kt")
public void testConcatGenericWithPrimitiveUpperBound() throws Exception {
runTest("compiler/testData/codegen/box/strings/concatGenericWithPrimitiveUpperBound.kt");
}
@TestMetadata("concatGenericWithStringUpperBound.kt")
public void testConcatGenericWithStringUpperBound() throws Exception {
runTest("compiler/testData/codegen/box/strings/concatGenericWithStringUpperBound.kt");
}
@TestMetadata("concatNullableGenericWithPrimitiveUpperBound.kt")
public void testConcatNullableGenericWithPrimitiveUpperBound() throws Exception {
runTest("compiler/testData/codegen/box/strings/concatNullableGenericWithPrimitiveUpperBound.kt");
}
@TestMetadata("constInStringTemplate.kt")
public void testConstInStringTemplate() throws Exception {
runTest("compiler/testData/codegen/box/strings/constInStringTemplate.kt");
@@ -25534,6 +25554,11 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest
runTest("compiler/testData/codegen/box/strings/kt47917.kt");
}
@TestMetadata("kt50140.kt")
public void testKt50140() throws Exception {
runTest("compiler/testData/codegen/box/strings/kt50140.kt");
}
@TestMetadata("kt5389_stringBuilderGet.kt")
public void testKt5389_stringBuilderGet() throws Exception {
runTest("compiler/testData/codegen/box/strings/kt5389_stringBuilderGet.kt");
@@ -31681,6 +31681,30 @@ public class NativeExtBlackBoxTestGenerated extends AbstractNativeBlackBoxTest {
runTest("compiler/testData/codegen/box/strings/concatDynamicWithSpecialSymbols.kt");
}
@Test
@TestMetadata("concatGenericWithNullablePrimitiveUpperBound.kt")
public void testConcatGenericWithNullablePrimitiveUpperBound() throws Exception {
runTest("compiler/testData/codegen/box/strings/concatGenericWithNullablePrimitiveUpperBound.kt");
}
@Test
@TestMetadata("concatGenericWithPrimitiveUpperBound.kt")
public void testConcatGenericWithPrimitiveUpperBound() throws Exception {
runTest("compiler/testData/codegen/box/strings/concatGenericWithPrimitiveUpperBound.kt");
}
@Test
@TestMetadata("concatGenericWithStringUpperBound.kt")
public void testConcatGenericWithStringUpperBound() throws Exception {
runTest("compiler/testData/codegen/box/strings/concatGenericWithStringUpperBound.kt");
}
@Test
@TestMetadata("concatNullableGenericWithPrimitiveUpperBound.kt")
public void testConcatNullableGenericWithPrimitiveUpperBound() throws Exception {
runTest("compiler/testData/codegen/box/strings/concatNullableGenericWithPrimitiveUpperBound.kt");
}
@Test
@TestMetadata("constInStringTemplate.kt")
public void testConstInStringTemplate() throws Exception {
@@ -31741,6 +31765,12 @@ public class NativeExtBlackBoxTestGenerated extends AbstractNativeBlackBoxTest {
runTest("compiler/testData/codegen/box/strings/kt47917.kt");
}
@Test
@TestMetadata("kt50140.kt")
public void testKt50140() throws Exception {
runTest("compiler/testData/codegen/box/strings/kt50140.kt");
}
@Test
@TestMetadata("kt5389_stringBuilderGet.kt")
public void testKt5389_stringBuilderGet() throws Exception {