@@ -24,47 +24,110 @@ class StringConcatTest extends ClearAfterClass {
24
24
ClearAfterClass .stateToClear = StringConcatTest
25
25
val compiler = StringConcatTest .compiler
26
26
27
- val commonPreInstructions = List (Label (0 ), LineNumber (1 , Label (0 )), TypeOp (NEW , " java/lang/StringBuilder" ), Op (DUP ), Invoke (INVOKESPECIAL , " java/lang/StringBuilder" , " <init>" , " ()V" , false ), Ldc (LDC , " abc" ), Invoke (INVOKEVIRTUAL , " java/lang/StringBuilder" , " append" , " (Ljava/lang/String;)Ljava/lang/StringBuilder;" , false ), VarOp (ALOAD , 0 ))
28
-
29
- val commonPostInstructions = List (Invoke (INVOKEVIRTUAL , " java/lang/StringBuilder" , " toString" , " ()Ljava/lang/String;" , false ), Op (ARETURN ), Label (12 ))
30
-
31
- def instructionsWithCommonParts (instructions : List [Instruction ]) = commonPreInstructions ++ instructions ++ commonPostInstructions
32
-
33
- def instructionsForResultMethod (code : String ): List [Instruction ] = {
34
- val methods = compileMethods(compiler)(code)
35
- val resultMethod = methods.find(_.name == " result" ).get
36
- instructionsFromMethod(resultMethod)
37
- }
38
-
39
27
@ Test
40
- def concatStringToStringBuilder : Unit = {
41
- val code = """ def string = "def"; def result = "abc" + string """
42
- val actualInstructions = instructionsForResultMethod(code)
43
- val expectedInstructions = instructionsWithCommonParts(List (Invoke (INVOKEVIRTUAL , " C" , " string" , " ()Ljava/lang/String;" , false ), Invoke (INVOKEVIRTUAL , " java/lang/StringBuilder" , " append" , " (Ljava/lang/String;)Ljava/lang/StringBuilder;" , false )))
44
- assertSameCode(actualInstructions, expectedInstructions)
45
- }
28
+ def appendOverloadNoBoxing (): Unit = {
29
+ val code =
30
+ """ class C {
31
+ | def t1(
32
+ | v: Unit,
33
+ | z: Boolean,
34
+ | c: Char,
35
+ | b: Byte,
36
+ | s: Short,
37
+ | i: Int,
38
+ | l: Long,
39
+ | f: Float,
40
+ | d: Double,
41
+ | str: String,
42
+ | sbuf: java.lang.StringBuffer,
43
+ | chsq: java.lang.CharSequence,
44
+ | chrs: Array[Char]) = str + this + v + z + c + b + s + i + f + l + d + sbuf + chsq + chrs
45
+ |
46
+ | // similar, but starting off with any2stringadd
47
+ | def t2(
48
+ | v: Unit,
49
+ | z: Boolean,
50
+ | c: Char,
51
+ | b: Byte,
52
+ | s: Short,
53
+ | i: Int,
54
+ | l: Long,
55
+ | f: Float,
56
+ | d: Double,
57
+ | str: String,
58
+ | sbuf: java.lang.StringBuffer,
59
+ | chsq: java.lang.CharSequence,
60
+ | chrs: Array[Char]) = this + str + v + z + c + b + s + i + f + l + d + sbuf + chsq + chrs
61
+ |}
62
+ """ .stripMargin
63
+ val List (c) = compileClasses(compiler)(code)
46
64
47
- @ Test
48
- def concatStringBufferToStringBuilder : Unit = {
49
- val code = """ def stringBuffer = new java.lang.StringBuffer("def"); def result = "abc" + stringBuffer """
50
- val actualInstructions = instructionsForResultMethod(code)
51
- val expectedInstructions = instructionsWithCommonParts(List (Invoke (INVOKEVIRTUAL , " C" , " stringBuffer" , " ()Ljava/lang/StringBuffer;" , false ), Invoke (INVOKEVIRTUAL , " java/lang/StringBuilder" , " append" , " (Ljava/lang/StringBuffer;)Ljava/lang/StringBuilder;" , false )))
52
- assertSameCode(actualInstructions, expectedInstructions)
53
- }
65
+ def invokeNameDesc (m : String ): List [String ] = getSingleMethod(c, m).instructions collect {
66
+ case Invoke (_, _, name, desc, _) => name + desc
67
+ }
68
+ assertEquals(invokeNameDesc(" t1" ), List (
69
+ " <init>()V" ,
70
+ " append(Ljava/lang/String;)Ljava/lang/StringBuilder;" ,
71
+ " append(Ljava/lang/Object;)Ljava/lang/StringBuilder;" ,
72
+ " append(Ljava/lang/Object;)Ljava/lang/StringBuilder;" ,
73
+ " append(Z)Ljava/lang/StringBuilder;" ,
74
+ " append(C)Ljava/lang/StringBuilder;" ,
75
+ " append(I)Ljava/lang/StringBuilder;" ,
76
+ " append(I)Ljava/lang/StringBuilder;" ,
77
+ " append(I)Ljava/lang/StringBuilder;" ,
78
+ " append(F)Ljava/lang/StringBuilder;" ,
79
+ " append(J)Ljava/lang/StringBuilder;" ,
80
+ " append(D)Ljava/lang/StringBuilder;" ,
81
+ " append(Ljava/lang/StringBuffer;)Ljava/lang/StringBuilder;" ,
82
+ " append(Ljava/lang/CharSequence;)Ljava/lang/StringBuilder;" ,
83
+ " append(Ljava/lang/Object;)Ljava/lang/StringBuilder;" , // test that we're not using the [C overload
84
+ " toString()Ljava/lang/String;" ))
54
85
55
- @ Test
56
- def concatCharSequenceToStringBuilder : Unit = {
57
- val code = """ def charSequence: CharSequence = "def"; def result = "abc" + charSequence """
58
- val actualInstructions = instructionsForResultMethod(code)
59
- val expectedInstructions = instructionsWithCommonParts(List (Invoke (INVOKEVIRTUAL , " C" , " charSequence" , " ()Ljava/lang/CharSequence;" , false ), Invoke (INVOKEVIRTUAL , " java/lang/StringBuilder" , " append" , " (Ljava/lang/CharSequence;)Ljava/lang/StringBuilder;" , false )))
60
- assertSameCode(actualInstructions, expectedInstructions)
86
+ assertEquals(invokeNameDesc(" t2" ), List (
87
+ " <init>()V" ,
88
+ " any2stringadd(Ljava/lang/Object;)Ljava/lang/Object;" ,
89
+ " $plus$extension(Ljava/lang/Object;Ljava/lang/String;)Ljava/lang/String;" ,
90
+ " append(Ljava/lang/String;)Ljava/lang/StringBuilder;" ,
91
+ " append(Ljava/lang/Object;)Ljava/lang/StringBuilder;" ,
92
+ " append(Z)Ljava/lang/StringBuilder;" ,
93
+ " append(C)Ljava/lang/StringBuilder;" ,
94
+ " append(I)Ljava/lang/StringBuilder;" ,
95
+ " append(I)Ljava/lang/StringBuilder;" ,
96
+ " append(I)Ljava/lang/StringBuilder;" ,
97
+ " append(F)Ljava/lang/StringBuilder;" ,
98
+ " append(J)Ljava/lang/StringBuilder;" ,
99
+ " append(D)Ljava/lang/StringBuilder;" ,
100
+ " append(Ljava/lang/StringBuffer;)Ljava/lang/StringBuilder;" ,
101
+ " append(Ljava/lang/CharSequence;)Ljava/lang/StringBuilder;" ,
102
+ " append(Ljava/lang/Object;)Ljava/lang/StringBuilder;" , // test that we're not using the [C overload
103
+ " toString()Ljava/lang/String;" ))
61
104
}
62
105
63
106
@ Test
64
- def concatIntToStringBuilder : Unit = {
65
- val code = """ def int = 123; def result = "abc" + int """
66
- val actualInstructions = instructionsForResultMethod(code)
67
- val expectedInstructions = instructionsWithCommonParts(List (Invoke (INVOKEVIRTUAL , " C" , " int" , " ()I" , false ), Invoke (INVOKESTATIC , " scala/runtime/BoxesRunTime" , " boxToInteger" , " (I)Ljava/lang/Integer;" , false ), Invoke (INVOKEVIRTUAL , " java/lang/StringBuilder" , " append" , " (Ljava/lang/Object;)Ljava/lang/StringBuilder;" , false )))
68
- assertSameCode(actualInstructions, expectedInstructions)
107
+ def concatPrimitiveCorrectness (): Unit = {
108
+ val obj : Object = new { override def toString = " TTT" }
109
+ def t (
110
+ v : Unit ,
111
+ z : Boolean ,
112
+ c : Char ,
113
+ b : Byte ,
114
+ s : Short ,
115
+ i : Int ,
116
+ l : Long ,
117
+ f : Float ,
118
+ d : Double ,
119
+ str : String ,
120
+ sbuf : java.lang.StringBuffer ,
121
+ chsq : java.lang.CharSequence ,
122
+ chrs : Array [Char ]) = {
123
+ val s1 = str + obj + v + z + c + b + s + i + f + l + d + sbuf + chsq + chrs
124
+ val s2 = obj + str + v + z + c + b + s + i + f + l + d + sbuf + chsq + chrs
125
+ s1 + " //" + s2
126
+ }
127
+ def sbuf = { val r = new java.lang.StringBuffer (); r.append(" sbuf" ); r }
128
+ def chsq : java.lang.CharSequence = " chsq"
129
+ val s = t((), true , 'd' , 3 : Byte , 12 : Short , 3 , - 32l , 12.3f , - 4.2d , " me" , sbuf, chsq, Array ('a' , 'b' ))
130
+ val r = s.replaceAll(""" \[C@\w+""" , " <ARRAY>" )
131
+ assertEquals(r, " meTTT()trued312312.3-32-4.2sbufchsq<ARRAY>//TTTme()trued312312.3-32-4.2sbufchsq<ARRAY>" )
69
132
}
70
133
}
0 commit comments