forked from scala/scala
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request scala#27 from dotty-staging/port-4737
Port scala#4737 and scala#4944
- Loading branch information
Showing
9 changed files
with
189 additions
and
38 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
Processing 65536 items | ||
Boxed doubles: 0 | ||
Boxed ints: 2 | ||
Boxed ints: 0 | ||
Boxed longs: 1179811 |
133 changes: 133 additions & 0 deletions
133
test/junit/scala/tools/nsc/backend/jvm/StringConcatTest.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
package scala.tools.nsc | ||
package backend.jvm | ||
|
||
import org.junit.runner.RunWith | ||
import org.junit.runners.JUnit4 | ||
import org.junit.Test | ||
import scala.tools.asm.Opcodes._ | ||
import org.junit.Assert._ | ||
|
||
import scala.tools.testing.AssertUtil._ | ||
|
||
import CodeGenTools._ | ||
import scala.tools.partest.ASMConverters | ||
import ASMConverters._ | ||
import scala.tools.testing.ClearAfterClass | ||
|
||
object StringConcatTest extends ClearAfterClass.Clearable { | ||
var compiler = newCompiler() | ||
def clear(): Unit = { compiler = null } | ||
} | ||
|
||
@RunWith(classOf[JUnit4]) | ||
class StringConcatTest extends ClearAfterClass { | ||
ClearAfterClass.stateToClear = StringConcatTest | ||
val compiler = StringConcatTest.compiler | ||
|
||
@Test | ||
def appendOverloadNoBoxing(): Unit = { | ||
val code = | ||
"""class C { | ||
| def t1( | ||
| v: Unit, | ||
| z: Boolean, | ||
| c: Char, | ||
| b: Byte, | ||
| s: Short, | ||
| i: Int, | ||
| l: Long, | ||
| f: Float, | ||
| d: Double, | ||
| str: String, | ||
| sbuf: java.lang.StringBuffer, | ||
| chsq: java.lang.CharSequence, | ||
| chrs: Array[Char]) = str + this + v + z + c + b + s + i + f + l + d + sbuf + chsq + chrs | ||
| | ||
| // similar, but starting off with any2stringadd | ||
| def t2( | ||
| v: Unit, | ||
| z: Boolean, | ||
| c: Char, | ||
| b: Byte, | ||
| s: Short, | ||
| i: Int, | ||
| l: Long, | ||
| f: Float, | ||
| d: Double, | ||
| str: String, | ||
| sbuf: java.lang.StringBuffer, | ||
| chsq: java.lang.CharSequence, | ||
| chrs: Array[Char]) = this + str + v + z + c + b + s + i + f + l + d + sbuf + chsq + chrs | ||
|} | ||
""".stripMargin | ||
val List(c) = compileClasses(compiler)(code) | ||
|
||
def invokeNameDesc(m: String): List[String] = getSingleMethod(c, m).instructions collect { | ||
case Invoke(_, _, name, desc, _) => name + desc | ||
} | ||
assertEquals(invokeNameDesc("t1"), List( | ||
"<init>()V", | ||
"append(Ljava/lang/String;)Ljava/lang/StringBuilder;", | ||
"append(Ljava/lang/Object;)Ljava/lang/StringBuilder;", | ||
"append(Ljava/lang/Object;)Ljava/lang/StringBuilder;", | ||
"append(Z)Ljava/lang/StringBuilder;", | ||
"append(C)Ljava/lang/StringBuilder;", | ||
"append(I)Ljava/lang/StringBuilder;", | ||
"append(I)Ljava/lang/StringBuilder;", | ||
"append(I)Ljava/lang/StringBuilder;", | ||
"append(F)Ljava/lang/StringBuilder;", | ||
"append(J)Ljava/lang/StringBuilder;", | ||
"append(D)Ljava/lang/StringBuilder;", | ||
"append(Ljava/lang/StringBuffer;)Ljava/lang/StringBuilder;", | ||
"append(Ljava/lang/CharSequence;)Ljava/lang/StringBuilder;", | ||
"append(Ljava/lang/Object;)Ljava/lang/StringBuilder;", // test that we're not using the [C overload | ||
"toString()Ljava/lang/String;")) | ||
|
||
assertEquals(invokeNameDesc("t2"), List( | ||
"<init>()V", | ||
"any2stringadd(Ljava/lang/Object;)Ljava/lang/Object;", | ||
"$plus$extension(Ljava/lang/Object;Ljava/lang/String;)Ljava/lang/String;", | ||
"append(Ljava/lang/String;)Ljava/lang/StringBuilder;", | ||
"append(Ljava/lang/Object;)Ljava/lang/StringBuilder;", | ||
"append(Z)Ljava/lang/StringBuilder;", | ||
"append(C)Ljava/lang/StringBuilder;", | ||
"append(I)Ljava/lang/StringBuilder;", | ||
"append(I)Ljava/lang/StringBuilder;", | ||
"append(I)Ljava/lang/StringBuilder;", | ||
"append(F)Ljava/lang/StringBuilder;", | ||
"append(J)Ljava/lang/StringBuilder;", | ||
"append(D)Ljava/lang/StringBuilder;", | ||
"append(Ljava/lang/StringBuffer;)Ljava/lang/StringBuilder;", | ||
"append(Ljava/lang/CharSequence;)Ljava/lang/StringBuilder;", | ||
"append(Ljava/lang/Object;)Ljava/lang/StringBuilder;", // test that we're not using the [C overload | ||
"toString()Ljava/lang/String;")) | ||
} | ||
|
||
@Test | ||
def concatPrimitiveCorrectness(): Unit = { | ||
val obj: Object = new { override def toString = "TTT" } | ||
def t( | ||
v: Unit, | ||
z: Boolean, | ||
c: Char, | ||
b: Byte, | ||
s: Short, | ||
i: Int, | ||
l: Long, | ||
f: Float, | ||
d: Double, | ||
str: String, | ||
sbuf: java.lang.StringBuffer, | ||
chsq: java.lang.CharSequence, | ||
chrs: Array[Char]) = { | ||
val s1 = str + obj + v + z + c + b + s + i + f + l + d + sbuf + chsq + chrs | ||
val s2 = obj + str + v + z + c + b + s + i + f + l + d + sbuf + chsq + chrs | ||
s1 + "//" + s2 | ||
} | ||
def sbuf = { val r = new java.lang.StringBuffer(); r.append("sbuf"); r } | ||
def chsq: java.lang.CharSequence = "chsq" | ||
val s = t((), true, 'd', 3: Byte, 12: Short, 3, -32l, 12.3f, -4.2d, "me", sbuf, chsq, Array('a', 'b')) | ||
val r = s.replaceAll("""\[C@\w+""", "<ARRAY>") | ||
assertEquals(r, "meTTT()trued312312.3-32-4.2sbufchsq<ARRAY>//TTTme()trued312312.3-32-4.2sbufchsq<ARRAY>") | ||
} | ||
} |