Support indy concatenation
This commit is contained in:
@@ -23,6 +23,7 @@ class StringConcatGenerator(val mode: JvmRuntimeStringConcat, val mv: Instructio
|
|||||||
|
|
||||||
private val template = StringBuilder("")
|
private val template = StringBuilder("")
|
||||||
private val paramTypes = arrayListOf<Type>()
|
private val paramTypes = arrayListOf<Type>()
|
||||||
|
private var justFlushed = false
|
||||||
|
|
||||||
@JvmOverloads
|
@JvmOverloads
|
||||||
fun genStringBuilderConstructorIfNeded(swap: Boolean = false) {
|
fun genStringBuilderConstructorIfNeded(swap: Boolean = false) {
|
||||||
@@ -37,6 +38,7 @@ class StringConcatGenerator(val mode: JvmRuntimeStringConcat, val mv: Instructio
|
|||||||
|
|
||||||
@JvmOverloads
|
@JvmOverloads
|
||||||
fun putValueOrProcessConstant(stackValue: StackValue, type: Type = stackValue.type, kotlinType: KotlinType? = stackValue.kotlinType) {
|
fun putValueOrProcessConstant(stackValue: StackValue, type: Type = stackValue.type, kotlinType: KotlinType? = stackValue.kotlinType) {
|
||||||
|
justFlushed = false
|
||||||
if (mode == JvmRuntimeStringConcat.ENABLE) {
|
if (mode == JvmRuntimeStringConcat.ENABLE) {
|
||||||
when (stackValue) {
|
when (stackValue) {
|
||||||
is StackValue.Constant -> {
|
is StackValue.Constant -> {
|
||||||
@@ -70,6 +72,7 @@ class StringConcatGenerator(val mode: JvmRuntimeStringConcat, val mv: Instructio
|
|||||||
false
|
false
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
|
justFlushed = false
|
||||||
paramTypes.add(type)
|
paramTypes.add(type)
|
||||||
template.append("\u0001")
|
template.append("\u0001")
|
||||||
if (paramTypes.size == 200) {
|
if (paramTypes.size == 200) {
|
||||||
@@ -77,6 +80,7 @@ class StringConcatGenerator(val mode: JvmRuntimeStringConcat, val mv: Instructio
|
|||||||
// because of `StringConcatFactory` limitation add use it as new argument for further processing:
|
// because of `StringConcatFactory` limitation add use it as new argument for further processing:
|
||||||
// "The number of parameter slots in {@code concatType} is less than or equal to 200"
|
// "The number of parameter slots in {@code concatType} is less than or equal to 200"
|
||||||
genToString()
|
genToString()
|
||||||
|
justFlushed = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -86,21 +90,38 @@ class StringConcatGenerator(val mode: JvmRuntimeStringConcat, val mv: Instructio
|
|||||||
mv.invokevirtual("java/lang/StringBuilder", "toString", "()Ljava/lang/String;", false)
|
mv.invokevirtual("java/lang/StringBuilder", "toString", "()Ljava/lang/String;", false)
|
||||||
} else {
|
} else {
|
||||||
//if state was flushed in `invokeAppend` do nothing
|
//if state was flushed in `invokeAppend` do nothing
|
||||||
if (template.isEmpty() && paramTypes.size == 1 && paramTypes[0] == JAVA_STRING_TYPE) return
|
if (justFlushed) return
|
||||||
val bootstrap = Handle(
|
if (mode == JvmRuntimeStringConcat.ENABLE) {
|
||||||
Opcodes.H_INVOKESTATIC,
|
val bootstrap = Handle(
|
||||||
"java/lang/invoke/StringConcatFactory",
|
Opcodes.H_INVOKESTATIC,
|
||||||
"makeConcatWithConstants",
|
"java/lang/invoke/StringConcatFactory",
|
||||||
"(Ljava/lang/invoke/MethodHandles\$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;",
|
"makeConcatWithConstants",
|
||||||
false
|
"(Ljava/lang/invoke/MethodHandles\$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;",
|
||||||
)
|
false
|
||||||
|
)
|
||||||
|
|
||||||
mv.invokedynamic(
|
mv.invokedynamic(
|
||||||
"makeConcatWithConstants",
|
"makeConcatWithConstants",
|
||||||
Type.getMethodDescriptor(JAVA_STRING_TYPE, *paramTypes.toTypedArray()),
|
Type.getMethodDescriptor(JAVA_STRING_TYPE, *paramTypes.toTypedArray()),
|
||||||
bootstrap,
|
bootstrap,
|
||||||
arrayOf(template.toString())
|
arrayOf(template.toString())
|
||||||
)
|
)
|
||||||
|
} else {
|
||||||
|
val bootstrap = Handle(
|
||||||
|
Opcodes.H_INVOKESTATIC,
|
||||||
|
"java/lang/invoke/StringConcatFactory",
|
||||||
|
"makeConcat",
|
||||||
|
"(Ljava/lang/invoke/MethodHandles\$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;",
|
||||||
|
false
|
||||||
|
)
|
||||||
|
|
||||||
|
mv.invokedynamic(
|
||||||
|
"makeConcat",
|
||||||
|
Type.getMethodDescriptor(JAVA_STRING_TYPE, *paramTypes.toTypedArray()),
|
||||||
|
bootstrap,
|
||||||
|
arrayOf()
|
||||||
|
)
|
||||||
|
}
|
||||||
template.clear()
|
template.clear()
|
||||||
paramTypes.clear()
|
paramTypes.clear()
|
||||||
paramTypes.add(JAVA_STRING_TYPE)
|
paramTypes.add(JAVA_STRING_TYPE)
|
||||||
|
|||||||
Generated
+35
@@ -4486,6 +4486,41 @@ public class FirBytecodeTextTestGenerated extends AbstractFirBytecodeTextTest {
|
|||||||
runTest("compiler/testData/codegen/bytecodeText/stringOperations/concat.kt");
|
runTest("compiler/testData/codegen/bytecodeText/stringOperations/concat.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("concatDynamic.kt")
|
||||||
|
public void testConcatDynamic() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/bytecodeText/stringOperations/concatDynamic.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("concatDynamic200.kt")
|
||||||
|
public void testConcatDynamic200() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/bytecodeText/stringOperations/concatDynamic200.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("concatDynamic201.kt")
|
||||||
|
public void testConcatDynamic201() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/bytecodeText/stringOperations/concatDynamic201.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("concatDynamicConstants.kt")
|
||||||
|
public void testConcatDynamicConstants() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/bytecodeText/stringOperations/concatDynamicConstants.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("concatDynamicIndy.kt")
|
||||||
|
public void testConcatDynamicIndy() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/bytecodeText/stringOperations/concatDynamicIndy.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("concatDynamicIndy201.kt")
|
||||||
|
public void testConcatDynamicIndy201() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/bytecodeText/stringOperations/concatDynamicIndy201.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("concatNotDynamic.kt")
|
||||||
|
public void testConcatNotDynamic() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/bytecodeText/stringOperations/concatNotDynamic.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("constConcat.kt")
|
@TestMetadata("constConcat.kt")
|
||||||
public void testConstConcat() throws Exception {
|
public void testConstConcat() throws Exception {
|
||||||
runTest("compiler/testData/codegen/bytecodeText/stringOperations/constConcat.kt");
|
runTest("compiler/testData/codegen/bytecodeText/stringOperations/constConcat.kt");
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ fun box() {
|
|||||||
z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z +
|
z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z +
|
||||||
z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z +
|
z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z +
|
||||||
z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z +
|
z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z +
|
||||||
|
"some constant" + "some constant" + "some constant" + "some constant" + // constant in this mode are inlined in recipe
|
||||||
z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z +
|
z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z +
|
||||||
z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z +
|
z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z +
|
||||||
z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z +
|
z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z +
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
// KOTLIN_CONFIGURATION_FLAGS: RUNTIME_STRING_CONCAT=indy
|
||||||
|
// JVM_TARGET: 9
|
||||||
|
class A
|
||||||
|
|
||||||
|
inline fun test(s: (String) -> Unit) {
|
||||||
|
s("456")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(a: String, b: String?) {
|
||||||
|
val s = a + "1" + "2" + 3 + 4L + b + 5.0 + 6F + '7' + A() + true + false + 1u
|
||||||
|
|
||||||
|
a.plus(b)
|
||||||
|
b?.plus(a)
|
||||||
|
val ref1 = a::plus
|
||||||
|
val ref2 = b::plus
|
||||||
|
|
||||||
|
test("123"::plus)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 0 INVOKEDYNAMIC makeConcatWithConstants
|
||||||
|
// 6 INVOKEDYNAMIC makeConcat
|
||||||
|
// 0 append
|
||||||
|
// 0 stringPlus
|
||||||
+20
@@ -0,0 +1,20 @@
|
|||||||
|
// KOTLIN_CONFIGURATION_FLAGS: RUNTIME_STRING_CONCAT=indy
|
||||||
|
// JVM_TARGET: 9
|
||||||
|
fun box() {
|
||||||
|
val z = "0"
|
||||||
|
val result = z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z +
|
||||||
|
z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z +
|
||||||
|
z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z +
|
||||||
|
z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z +
|
||||||
|
z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z +
|
||||||
|
"some constant" +
|
||||||
|
z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z +
|
||||||
|
z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z +
|
||||||
|
z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z +
|
||||||
|
z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z +
|
||||||
|
z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z //200 + 1 constant
|
||||||
|
|
||||||
|
}
|
||||||
|
// 2 INVOKEDYNAMIC makeConcat
|
||||||
|
// 0 append
|
||||||
|
// 0 stringPlus
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
// KOTLIN_CONFIGURATION_FLAGS: RUNTIME_STRING_CONCAT=enable
|
||||||
|
// JVM_TARGET: 9
|
||||||
|
fun box(): String {
|
||||||
|
val p = 3147483648u
|
||||||
|
val a = "_"
|
||||||
|
val b = "_"
|
||||||
|
val s = a + "1" + "2" + 3 + 4L + b + 5.0 + 6F + '7' + true + false + 3147483647u + p
|
||||||
|
|
||||||
|
return if (s != "_1234_5.06.07truefalse31474836473147483648") "fail $s" else "OK"
|
||||||
|
}
|
||||||
|
|
||||||
|
fun main() {
|
||||||
|
box().let { if (it != "OK") throw AssertionError(it) }
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
// KOTLIN_CONFIGURATION_FLAGS: RUNTIME_STRING_CONCAT=indy
|
||||||
|
// JVM_TARGET: 9
|
||||||
|
fun box(): String {
|
||||||
|
val z = "0"
|
||||||
|
val result = z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z +
|
||||||
|
z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z +
|
||||||
|
z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z +
|
||||||
|
z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z +
|
||||||
|
z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z +
|
||||||
|
z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z +
|
||||||
|
z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z +
|
||||||
|
z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z +
|
||||||
|
z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z +
|
||||||
|
z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z //200
|
||||||
|
|
||||||
|
return if (result.length != 200)
|
||||||
|
"fail: ${result.length}" else "OK"
|
||||||
|
}
|
||||||
|
|
||||||
|
fun main() {
|
||||||
|
box().let { if (it != "OK") throw AssertionError(it) }
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
// KOTLIN_CONFIGURATION_FLAGS: RUNTIME_STRING_CONCAT=indy
|
||||||
|
// JVM_TARGET: 9
|
||||||
|
fun box(): String {
|
||||||
|
val z = "0"
|
||||||
|
val result = z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z +
|
||||||
|
z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z +
|
||||||
|
z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z +
|
||||||
|
z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z +
|
||||||
|
z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z +
|
||||||
|
z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z +
|
||||||
|
z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z +
|
||||||
|
z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z +
|
||||||
|
z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z +
|
||||||
|
z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + z + //200
|
||||||
|
z //201
|
||||||
|
|
||||||
|
return if (result.length != 201)
|
||||||
|
"fail: ${result.length}" else "OK"
|
||||||
|
}
|
||||||
|
|
||||||
|
fun main() {
|
||||||
|
box().let { if (it != "OK") throw AssertionError(it) }
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
// KOTLIN_CONFIGURATION_FLAGS: RUNTIME_STRING_CONCAT=enable
|
||||||
|
// JVM_TARGET: 9
|
||||||
|
inline class Str(val s: String)
|
||||||
|
inline class NStr(val s: String?)
|
||||||
|
|
||||||
|
fun testStr(s: Str?) = "1$s$s"
|
||||||
|
fun testNStr(ns: NStr?) = "2$ns$ns"
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
|
||||||
|
val test1 = testStr(Str("0"))
|
||||||
|
if (test1 != "1Str(s=0)Str(s=0)") return "fail 1: $test1"
|
||||||
|
|
||||||
|
val test2 = testStr(null)
|
||||||
|
if (test2 != "1nullnull") return "fail 2: $test2"
|
||||||
|
|
||||||
|
val test3 = testNStr(NStr(null))
|
||||||
|
if (test3 != "2NStr(s=null)NStr(s=null)") return "fail 3: $test3"
|
||||||
|
|
||||||
|
val test4 = testNStr(NStr("0"))
|
||||||
|
if (test4 != "2NStr(s=0)NStr(s=0)") return "fail 4: $test4"
|
||||||
|
|
||||||
|
val test5 = testNStr(null)
|
||||||
|
if (test5 != "2nullnull") return "fail 5: $test5"
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
|
|
||||||
|
fun main() {
|
||||||
|
box().let { if (it != "OK") throw AssertionError(it) }
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
// KOTLIN_CONFIGURATION_FLAGS: RUNTIME_STRING_CONCAT=enable
|
||||||
|
// JVM_TARGET: 9
|
||||||
|
inline fun test(crossinline s: (String) -> String): String {
|
||||||
|
var result = "1" + s("2") + "3" + 4 + {
|
||||||
|
"5" + s("6") + "7"
|
||||||
|
}()
|
||||||
|
|
||||||
|
result += object {
|
||||||
|
fun run() = "8" + s("9") + "10"
|
||||||
|
}.run()
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val result = test { it }
|
||||||
|
if (result != "12345678910") return "fail 1: $result"
|
||||||
|
|
||||||
|
val result2 = test { it + "_" }
|
||||||
|
return if (result2 != "12_3456_789_10") "fail 2: $result2" else "OK"
|
||||||
|
}
|
||||||
|
|
||||||
|
fun main() {
|
||||||
|
box().let { if (it != "OK") throw AssertionError(it) }
|
||||||
|
}
|
||||||
@@ -4538,6 +4538,16 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest {
|
|||||||
runTest("compiler/testData/codegen/bytecodeText/stringOperations/concatDynamicConstants.kt");
|
runTest("compiler/testData/codegen/bytecodeText/stringOperations/concatDynamicConstants.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("concatDynamicIndy.kt")
|
||||||
|
public void testConcatDynamicIndy() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/bytecodeText/stringOperations/concatDynamicIndy.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("concatDynamicIndy201.kt")
|
||||||
|
public void testConcatDynamicIndy201() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/bytecodeText/stringOperations/concatDynamicIndy201.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("concatNotDynamic.kt")
|
@TestMetadata("concatNotDynamic.kt")
|
||||||
public void testConcatNotDynamic() throws Exception {
|
public void testConcatNotDynamic() throws Exception {
|
||||||
runTest("compiler/testData/codegen/bytecodeText/stringOperations/concatNotDynamic.kt");
|
runTest("compiler/testData/codegen/bytecodeText/stringOperations/concatNotDynamic.kt");
|
||||||
|
|||||||
@@ -52,6 +52,11 @@ class Java9CodegenTest : AbstractBlackBoxCodegenTest() {
|
|||||||
blackBox(true)
|
blackBox(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun testConcatDynamic() {
|
||||||
|
loadFile()
|
||||||
|
blackBox(true)
|
||||||
|
}
|
||||||
|
|
||||||
fun testConcatDynamic200() {
|
fun testConcatDynamic200() {
|
||||||
loadFile()
|
loadFile()
|
||||||
blackBox(true)
|
blackBox(true)
|
||||||
@@ -61,4 +66,24 @@ class Java9CodegenTest : AbstractBlackBoxCodegenTest() {
|
|||||||
loadFile()
|
loadFile()
|
||||||
blackBox(true)
|
blackBox(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun testConcatDynamicIndy200() {
|
||||||
|
loadFile()
|
||||||
|
blackBox(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testConcatDynamicIndy201() {
|
||||||
|
loadFile()
|
||||||
|
blackBox(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testConcatDynamicWithInline() {
|
||||||
|
loadFile()
|
||||||
|
blackBox(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testConcatDynamicInlineClasses() {
|
||||||
|
loadFile()
|
||||||
|
blackBox(true)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+10
@@ -4506,6 +4506,16 @@ public class IrBytecodeTextTestGenerated extends AbstractIrBytecodeTextTest {
|
|||||||
runTest("compiler/testData/codegen/bytecodeText/stringOperations/concatDynamicConstants.kt");
|
runTest("compiler/testData/codegen/bytecodeText/stringOperations/concatDynamicConstants.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("concatDynamicIndy.kt")
|
||||||
|
public void testConcatDynamicIndy() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/bytecodeText/stringOperations/concatDynamicIndy.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("concatDynamicIndy201.kt")
|
||||||
|
public void testConcatDynamicIndy201() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/bytecodeText/stringOperations/concatDynamicIndy201.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("concatNotDynamic.kt")
|
@TestMetadata("concatNotDynamic.kt")
|
||||||
public void testConcatNotDynamic() throws Exception {
|
public void testConcatNotDynamic() throws Exception {
|
||||||
runTest("compiler/testData/codegen/bytecodeText/stringOperations/concatNotDynamic.kt");
|
runTest("compiler/testData/codegen/bytecodeText/stringOperations/concatNotDynamic.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user