[JS IR] Explicitly cast to a string all types except specific ones
^KT-62763 Fixed
This commit is contained in:
committed by
Space Team
parent
70d99e1964
commit
41ebe498f2
+17
-7
@@ -26,17 +26,27 @@ class JsStringConcatenationLowering(val context: CommonBackendContext) : FileLow
|
||||
}
|
||||
|
||||
private class JsStringConcatenationTransformer(val context: CommonBackendContext) : IrElementTransformerVoid() {
|
||||
|
||||
private val IrType.shouldExplicitlyConvertToString: Boolean
|
||||
get() {
|
||||
// If the type is Long or a supertype of Long, we want to call toString() on values of that type.
|
||||
// See KT-39891
|
||||
if (this !is IrSimpleType) return false
|
||||
/**
|
||||
* The type may have a valueOf() function, meaning that in string concatenation,
|
||||
* the toString() function will be ignored, and the valueOf() function will be called instead.
|
||||
* Therefore, we have to wrap all types except those where we are sure that they don't have the valueOf() function.
|
||||
*
|
||||
* Note, that we do not check for the existence of the valueOf() function
|
||||
* in the class because it would complicate incremental compilation.
|
||||
*
|
||||
* Ignore [Long] and all its supertypes ([Any], [Comparable], [Number]) since [Long] has the valueOf() method.
|
||||
* Ignore [Char] since it requires an explicit conversion to string.
|
||||
*/
|
||||
return when (classifier.signature) {
|
||||
IdSignatureValues.any, IdSignatureValues.comparable, IdSignatureValues.number,
|
||||
IdSignatureValues._long, IdSignatureValues._char
|
||||
-> true
|
||||
else -> false
|
||||
IdSignatureValues._boolean, IdSignatureValues.string, IdSignatureValues.array,
|
||||
IdSignatureValues._byte, IdSignatureValues._short, IdSignatureValues._int,
|
||||
IdSignatureValues.uByte, IdSignatureValues.uShort, IdSignatureValues.uInt, IdSignatureValues.uLong,
|
||||
IdSignatureValues._float, IdSignatureValues._double,
|
||||
-> false
|
||||
else -> true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -66,7 +66,7 @@ fun box(): String {
|
||||
if (testUtils.isLegacyBackend()) {
|
||||
assertEquals("[...];1,2,3;[...];", pullLog(), "genericValueToString")
|
||||
} else {
|
||||
assertEquals("[...];1,2,3;1,2,3;", pullLog(), "genericValueToString")
|
||||
assertEquals("[...];[...];[...];", pullLog(), "genericValueToString")
|
||||
}
|
||||
|
||||
anyValueToString(a)
|
||||
|
||||
@@ -60,28 +60,26 @@ fun testInt() {
|
||||
|
||||
fun testLong() {
|
||||
val expectedMax = " 9223372036854775807 "
|
||||
val expectedMaxBUG = " 9223372036854776000 "
|
||||
val v1 = Long.MAX_VALUE
|
||||
|
||||
assertEquals(expectedMax, " $v1 ", "testLong - template v1")
|
||||
assertEquals(expectedMax, toStringTemplateAny(v1), "testLong - toStringTemplateAny(v1)")
|
||||
assertEquals(expectedMaxBUG, toStringTemplateGeneric(v1), "testLong - toStringTemplateGeneric(v1)")
|
||||
assertEquals(expectedMax, toStringTemplateGeneric(v1), "testLong - toStringTemplateGeneric(v1)")
|
||||
assertEquals(expectedMax, toStringTemplateInlineGeneric(v1), "testLong - toStringTemplateInlineGeneric(v1)")
|
||||
assertEquals(expectedMax, toStringTemplateInlineReifiedGeneric(v1), "testLong - toStringTemplateInlineReifiedGeneric(v1)")
|
||||
assertEquals(expectedMaxBUG, TestClass(v1).asString(), "testLong - TestClass(v1).asString()")
|
||||
assertEquals(expectedMaxBUG, TestClass(v1).asStringInline(), "testLong - TestClass(v1).asStringInline()")
|
||||
assertEquals(expectedMax, TestClass(v1).asString(), "testLong - TestClass(v1).asString()")
|
||||
assertEquals(expectedMax, TestClass(v1).asStringInline(), "testLong - TestClass(v1).asStringInline()")
|
||||
|
||||
val expectedMin = " -9223372036854775808 "
|
||||
val expectedMinBUG = " -9223372036854776000 "
|
||||
val v2 = Long.MIN_VALUE
|
||||
|
||||
assertEquals(expectedMin, " $v2 ", "testLong - template v2")
|
||||
assertEquals(expectedMin, toStringTemplateAny(v2), "testLong - toStringTemplateAny(v2)")
|
||||
assertEquals(expectedMinBUG, toStringTemplateGeneric(v2), "testLong - toStringTemplateGeneric(v2)")
|
||||
assertEquals(expectedMin, toStringTemplateGeneric(v2), "testLong - toStringTemplateGeneric(v2)")
|
||||
assertEquals(expectedMin, toStringTemplateInlineGeneric(v2), "testLong - toStringTemplateInlineGeneric(v2)")
|
||||
assertEquals(expectedMin, toStringTemplateInlineReifiedGeneric(v2), "testLong - toStringTemplateInlineReifiedGeneric(v2)")
|
||||
assertEquals(expectedMinBUG, TestClass(v2).asString(), "testLong - TestClass(v2).asString()")
|
||||
assertEquals(expectedMinBUG, TestClass(v2).asStringInline(), "testLong - TestClass(v2).asStringInline()")
|
||||
assertEquals(expectedMin, TestClass(v2).asString(), "testLong - TestClass(v2).asString()")
|
||||
assertEquals(expectedMin, TestClass(v2).asStringInline(), "testLong - TestClass(v2).asStringInline()")
|
||||
}
|
||||
|
||||
fun testULong() {
|
||||
@@ -117,11 +115,11 @@ fun testArrayInt() {
|
||||
|
||||
assertEquals(expected, " $v ", "testArrayInt - template")
|
||||
assertEquals(expectedShort, toStringTemplateAny(v), "testArrayInt - toStringTemplateAny")
|
||||
assertEquals(expected, toStringTemplateGeneric(v), "testArrayInt - toStringTemplateGeneric")
|
||||
assertEquals(expectedShort, toStringTemplateGeneric(v), "testArrayInt - toStringTemplateGeneric")
|
||||
assertEquals(expectedShort, toStringTemplateInlineGeneric(v), "testArrayInt - toStringTemplateInlineGeneric")
|
||||
assertEquals(expectedShort, toStringTemplateInlineReifiedGeneric(v), "testArrayInt - toStringTemplateInlineReifiedGeneric")
|
||||
assertEquals(expected, TestClass(v).asString(), "testArrayInt - TestClass::asString")
|
||||
assertEquals(expected, TestClass(v).asStringInline(), "testArrayInt - TestClass::asStringInline")
|
||||
assertEquals(expectedShort, TestClass(v).asString(), "testArrayInt - TestClass::asString")
|
||||
assertEquals(expectedShort, TestClass(v).asStringInline(), "testArrayInt - TestClass::asStringInline")
|
||||
}
|
||||
|
||||
fun testArrayLong() {
|
||||
@@ -131,11 +129,11 @@ fun testArrayLong() {
|
||||
|
||||
assertEquals(expected, " $v ", "testArrayLong - template")
|
||||
assertEquals(expectedShort, toStringTemplateAny(v), "testArrayLong - toStringTemplateAny")
|
||||
assertEquals(expected, toStringTemplateGeneric(v), "testArrayLong - toStringTemplateGeneric")
|
||||
assertEquals(expectedShort, toStringTemplateGeneric(v), "testArrayLong - toStringTemplateGeneric")
|
||||
assertEquals(expectedShort, toStringTemplateInlineGeneric(v), "testArrayLong - toStringTemplateInlineGeneric")
|
||||
assertEquals(expectedShort, toStringTemplateInlineReifiedGeneric(v), "testArrayLong - toStringTemplateInlineReifiedGeneric")
|
||||
assertEquals(expected, TestClass(v).asString(), "testArrayLong - TestClass::asString")
|
||||
assertEquals(expected, TestClass(v).asStringInline(), "testArrayLong - TestClass::asStringInline")
|
||||
assertEquals(expectedShort, TestClass(v).asString(), "testArrayLong - TestClass::asString")
|
||||
assertEquals(expectedShort, TestClass(v).asStringInline(), "testArrayLong - TestClass::asStringInline")
|
||||
}
|
||||
|
||||
class UserClass {
|
||||
@@ -147,16 +145,15 @@ class UserClass {
|
||||
|
||||
fun testUserClass() {
|
||||
val expected = " Hello World! "
|
||||
val expectedBUG = " NOT OK!!! "
|
||||
val v = UserClass()
|
||||
|
||||
assertEquals(expectedBUG, " $v ", "testUserClass - template")
|
||||
assertEquals(expected, " $v ", "testUserClass - template")
|
||||
assertEquals(expected, toStringTemplateAny(v), "testUserClass - toStringTemplateAny(v)")
|
||||
assertEquals(expectedBUG, toStringTemplateGeneric(v), "testUserClass - toStringTemplateGeneric(v)")
|
||||
assertEquals(expected, toStringTemplateGeneric(v), "testUserClass - toStringTemplateGeneric(v)")
|
||||
assertEquals(expected, toStringTemplateInlineGeneric(v), "testUserClass - toStringTemplateInlineGeneric(v)")
|
||||
assertEquals(expected, toStringTemplateInlineReifiedGeneric(v), "testUserClass - toStringTemplateInlineReifiedGeneric(v)")
|
||||
assertEquals(expectedBUG, TestClass(v).asString(), "testUserClass - TestClass(v).asString()")
|
||||
assertEquals(expectedBUG, TestClass(v).asStringInline(), "testUserClass - TestClass(v).asStringInline()")
|
||||
assertEquals(expected, TestClass(v).asString(), "testUserClass - TestClass(v).asString()")
|
||||
assertEquals(expected, TestClass(v).asStringInline(), "testUserClass - TestClass(v).asStringInline()")
|
||||
}
|
||||
|
||||
value class UserValueClass(val x: Int) {
|
||||
|
||||
@@ -3,7 +3,7 @@ package foo
|
||||
|
||||
fun box(): String {
|
||||
assertEquals(2, fizz(arrayOf(1, 2))[buzz(1)])
|
||||
assertEquals("fizz(1,2);buzz(1);", pullLog())
|
||||
assertEquals("fizz([...]);buzz(1);", pullLog())
|
||||
|
||||
return "OK"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user