@@ -3,6 +3,10 @@ package dotty.tools.backend.jvm
3
3
import org .junit .Assert ._
4
4
import org .junit .Test
5
5
6
+ import scala .tools .asm .Opcodes ._
7
+
8
+ import scala .collection .JavaConverters ._
9
+
6
10
class InlineBytecodeTests extends DottyBytecodeTest {
7
11
import ASMConverters ._
8
12
@ Test def inlineUnit = {
@@ -37,4 +41,116 @@ class InlineBytecodeTests extends DottyBytecodeTest {
37
41
diffInstructions(instructions2, instructions3))
38
42
}
39
43
}
44
+
45
+ @ Test def i4947 = {
46
+ val source = """ class Foo {
47
+ | transparent def track[T](f: => T): T = {
48
+ | println("tracking") // line 3
49
+ | f // line 4
50
+ | }
51
+ | def main(args: Array[String]): Unit = { // line 6
52
+ | track { // line 7
53
+ | println("abc") // line 8
54
+ | track { // line 9
55
+ | println("inner") // line 10
56
+ | }
57
+ | } // line 11
58
+ | }
59
+ |}
60
+ """ .stripMargin
61
+
62
+ checkBCode(source) { dir =>
63
+ val clsIn = dir.lookupName(" Foo.class" , directory = false ).input
64
+ val clsNode = loadClassNode(clsIn, skipDebugInfo = false )
65
+
66
+ val track = clsNode.methods.asScala.find(_.name == " track" )
67
+ assert(track.isEmpty, " method `track` should have been erased" )
68
+
69
+ val main = getMethod(clsNode, " main" )
70
+ val instructions = instructionsFromMethod(main)
71
+ val expected =
72
+ List (
73
+ Label (0 ),
74
+ LineNumber (6 , Label (0 )), // Position of the method start
75
+ LineNumber (7 , Label (0 )), // Position of the call to `track`
76
+ Field (GETSTATIC , " scala/Predef$" , " MODULE$" , " Lscala/Predef$;" ),
77
+ Ldc (LDC , " tracking" ),
78
+ Invoke (INVOKEVIRTUAL , " scala/Predef$" , " println" , " (Ljava/lang/Object;)V" , false ),
79
+ Label (6 ),
80
+ LineNumber (8 , Label (6 )), // Actual position
81
+ Field (GETSTATIC , " scala/Predef$" , " MODULE$" , " Lscala/Predef$;" ),
82
+ Ldc (LDC , " abc" ),
83
+ Invoke (INVOKEVIRTUAL , " scala/Predef$" , " println" ," (Ljava/lang/Object;)V" , false ),
84
+ Label (11 ),
85
+ LineNumber (9 , Label (11 )), // Position of the call to `track`
86
+ Field (GETSTATIC , " scala/Predef$" , " MODULE$" , " Lscala/Predef$;" ),
87
+ Ldc (LDC , " tracking" ),
88
+ Invoke (INVOKEVIRTUAL , " scala/Predef$" , " println" ," (Ljava/lang/Object;)V" , false ),
89
+ Label (16 ),
90
+ LineNumber (10 , Label (16 )), // Actual position
91
+ Field (GETSTATIC , " scala/Predef$" , " MODULE$" , " Lscala/Predef$;" ),
92
+ Ldc (LDC , " inner" ),
93
+ Invoke (INVOKEVIRTUAL , " scala/Predef$" , " println" ," (Ljava/lang/Object;)V" , false ),
94
+ Op (RETURN ),
95
+ Label (22 )
96
+ )
97
+ assert(instructions == expected,
98
+ " `track` was not properly inlined in `main`\n " + diffInstructions(instructions, expected))
99
+
100
+ }
101
+ }
102
+
103
+ @ Test def i4947b = {
104
+ val source = """ class Foo {
105
+ | transparent def track2[T](f: => T): T = {
106
+ | println("tracking2") // line 3
107
+ | f // line 4
108
+ | }
109
+ | transparent def track[T](f: => T): T = {
110
+ | println("tracking") // line 7
111
+ | track2 { // line 8
112
+ | f // line 9
113
+ | }
114
+ | }
115
+ | def main(args: Array[String]): Unit = { // line 12
116
+ | track { // line 13
117
+ | println("abc") // line 14
118
+ | }
119
+ | }
120
+ |}
121
+ """ .stripMargin
122
+
123
+ checkBCode(source) { dir =>
124
+ val clsIn = dir.lookupName(" Foo.class" , directory = false ).input
125
+ val clsNode = loadClassNode(clsIn, skipDebugInfo = false )
126
+
127
+ val track = clsNode.methods.asScala.find(_.name == " track" )
128
+ assert(track.isEmpty, " method `track` should have been erased" )
129
+
130
+ val main = getMethod(clsNode, " main" )
131
+ val instructions = instructionsFromMethod(main)
132
+ val expected =
133
+ List (
134
+ Label (0 ),
135
+ LineNumber (12 , Label (0 )), // Position of the method start
136
+ LineNumber (13 , Label (0 )), // Position of the call to `track`
137
+ Field (GETSTATIC , " scala/Predef$" , " MODULE$" , " Lscala/Predef$;" ),
138
+ Ldc (LDC , " tracking" ),
139
+ Invoke (INVOKEVIRTUAL , " scala/Predef$" , " println" , " (Ljava/lang/Object;)V" , false ),
140
+ Field (GETSTATIC , " scala/Predef$" , " MODULE$" , " Lscala/Predef$;" ),
141
+ Ldc (LDC , " tracking2" ),
142
+ Invoke (INVOKEVIRTUAL , " scala/Predef$" , " println" ," (Ljava/lang/Object;)V" , false ),
143
+ Label (9 ),
144
+ LineNumber (14 , Label (9 )), // Actual position
145
+ Field (GETSTATIC , " scala/Predef$" , " MODULE$" , " Lscala/Predef$;" ),
146
+ Ldc (LDC , " abc" ),
147
+ Invoke (INVOKEVIRTUAL , " scala/Predef$" , " println" ," (Ljava/lang/Object;)V" , false ),
148
+ Op (RETURN ),
149
+ Label (15 )
150
+ )
151
+ assert(instructions == expected,
152
+ " `track` was not properly inlined in `main`\n " + diffInstructions(instructions, expected))
153
+
154
+ }
155
+ }
40
156
}
0 commit comments