summaryrefslogtreecommitdiff
path: root/test/junit/scala/tools/nsc/backend/jvm/StringConcatTest.scala
blob: af2c8f9ce008e1159589a994e97d592a1a5e945d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
package scala.tools.nsc
package backend.jvm

import org.junit.Assert._
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4

import scala.tools.partest.ASMConverters._
import scala.tools.testing.BytecodeTesting
import scala.tools.testing.BytecodeTesting._

@RunWith(classOf[JUnit4])
class StringConcatTest extends BytecodeTesting {
  import 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 c = compileClass(code)

    def invokeNameDesc(m: String): List[String] = getInstructions(c, m) 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>")
  }
}