Skip to content

Commit 8756a0f

Browse files
committed
Coverage: mark case bodies as branches; don't ignore branches with synthetic spans
Marking bodies of CaseDefs as branches seems like an uncontroversial change, it was probably an oversight. Not ignoring synthetic spans when creating coverage calls in branches seems like a good trade off. There might be some auto-generated `else ()` interpreted as branches, but Scala introduces quite a lot of synthetic trees that wrap non-synthetic trees (e.g. implicit classes).
1 parent 41d45a7 commit 8756a0f

9 files changed

+576
-91
lines changed

Diff for: compiler/src/dotty/tools/dotc/transform/InstrumentCoverage.scala

+3-8
Original file line numberDiff line numberDiff line change
@@ -188,12 +188,9 @@ class InstrumentCoverage extends MacroTransform with IdentityDenotTransformer:
188188
* If the tree is empty, return itself and don't instrument.
189189
*/
190190
private def transformBranch(tree: Tree)(using Context): Tree =
191-
import dotty.tools.dotc.core.Decorators.{show,i}
192-
if tree.isEmpty || tree.span.isSynthetic then
191+
if tree.isEmpty then
193192
// - If t.isEmpty then `transform(t) == t` always hold,
194193
// so we can avoid calling transform in that case.
195-
// - If tree.span.isSynthetic then the branch has been generated
196-
// by the frontend phases, so we don't want to instrument it.
197194
tree
198195
else
199196
val transformed = transform(tree)
@@ -353,10 +350,8 @@ class InstrumentCoverage extends MacroTransform with IdentityDenotTransformer:
353350
// recursively transform the guard, but keep the pat
354351
val transformedGuard = transform(guard)
355352

356-
// ensure that the body is always instrumented by inserting a call to Invoker.invoked at its beginning
357-
val coverageCall = createInvokeCall(tree.body, pos)
358-
val transformedBody = transform(tree.body)
359-
val instrumentedBody = InstrumentedParts.singleExprTree(coverageCall, transformedBody)
353+
// ensure that the body is always instrumented as a branch
354+
val instrumentedBody = transformBranch(tree.body)
360355

361356
cpy.CaseDef(tree)(pat, transformedGuard, instrumentedBody)
362357

Diff for: tests/coverage/pos/Inlined.scoverage.check

+61-10
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,23 @@ Inlined$package$
5959
Object
6060
covtest.Inlined$package$
6161
testInlined
62+
330
63+
330
64+
10
65+
<none>
66+
Literal
67+
true
68+
0
69+
false
70+
71+
72+
3
73+
Inlined.scala
74+
covtest
75+
Inlined$package$
76+
Object
77+
covtest.Inlined$package$
78+
testInlined
6279
155
6380
162
6481
6
@@ -69,7 +86,7 @@ false
6986
false
7087
List(l)
7188

72-
3
89+
4
7390
Inlined.scala
7491
covtest
7592
Inlined$package$
@@ -86,7 +103,7 @@ false
86103
false
87104
List
88105

89-
4
106+
5
90107
Inlined.scala
91108
covtest
92109
Inlined$package$
@@ -103,7 +120,7 @@ false
103120
false
104121
List(l).length
105122

106-
5
123+
6
107124
Inlined.scala
108125
covtest
109126
Inlined$package$
@@ -120,7 +137,7 @@ false
120137
false
121138
scala.runtime.Scala3RunTime.assertFailed()
122139

123-
6
140+
7
124141
Inlined.scala
125142
covtest
126143
Inlined$package$
@@ -137,7 +154,24 @@ true
137154
false
138155
scala.runtime.Scala3RunTime.assertFailed()
139156

140-
7
157+
8
158+
Inlined.scala
159+
covtest
160+
Inlined$package$
161+
Object
162+
covtest.Inlined$package$
163+
testInlined
164+
330
165+
330
166+
10
167+
<none>
168+
Literal
169+
true
170+
0
171+
false
172+
173+
174+
9
141175
Inlined.scala
142176
covtest
143177
Inlined$package$
@@ -154,7 +188,7 @@ false
154188
false
155189
List(l)
156190

157-
8
191+
10
158192
Inlined.scala
159193
covtest
160194
Inlined$package$
@@ -171,7 +205,7 @@ false
171205
false
172206
List
173207

174-
9
208+
11
175209
Inlined.scala
176210
covtest
177211
Inlined$package$
@@ -188,7 +222,7 @@ false
188222
false
189223
List(l).length
190224

191-
10
225+
12
192226
Inlined.scala
193227
covtest
194228
Inlined$package$
@@ -205,7 +239,7 @@ false
205239
false
206240
scala.runtime.Scala3RunTime.assertFailed()
207241

208-
11
242+
13
209243
Inlined.scala
210244
covtest
211245
Inlined$package$
@@ -222,7 +256,24 @@ true
222256
false
223257
scala.runtime.Scala3RunTime.assertFailed()
224258

225-
12
259+
14
260+
Inlined.scala
261+
covtest
262+
Inlined$package$
263+
Object
264+
covtest.Inlined$package$
265+
testInlined
266+
330
267+
330
268+
10
269+
<none>
270+
Literal
271+
true
272+
0
273+
false
274+
275+
276+
15
226277
Inlined.scala
227278
covtest
228279
Inlined$package$

Diff for: tests/coverage/pos/MatchCaseClasses.scoverage.check

+53-53
Original file line numberDiff line numberDiff line change
@@ -25,23 +25,6 @@ MatchCaseClasses$
2525
Object
2626
covtest.MatchCaseClasses$
2727
f
28-
135
29-
147
30-
7
31-
<none>
32-
Block
33-
false
34-
0
35-
false
36-
case Pat1(0)
37-
38-
1
39-
MatchCaseClasses.scala
40-
covtest
41-
MatchCaseClasses$
42-
Object
43-
covtest.MatchCaseClasses$
44-
f
4528
151
4629
163
4730
7
@@ -52,24 +35,24 @@ false
5235
false
5336
println("a")
5437

55-
2
38+
1
5639
MatchCaseClasses.scala
5740
covtest
5841
MatchCaseClasses$
5942
Object
6043
covtest.MatchCaseClasses$
6144
f
62-
168
63-
180
64-
8
45+
148
46+
163
47+
7
6548
<none>
6649
Block
67-
false
50+
true
6851
0
6952
false
70-
case Pat1(_)
53+
=> println("a")
7154

72-
3
55+
2
7356
MatchCaseClasses.scala
7457
covtest
7558
MatchCaseClasses$
@@ -86,24 +69,24 @@ false
8669
false
8770
println("b")
8871

89-
4
72+
3
9073
MatchCaseClasses.scala
9174
covtest
9275
MatchCaseClasses$
9376
Object
9477
covtest.MatchCaseClasses$
9578
f
96-
201
97-
221
98-
9
79+
181
80+
196
81+
8
9982
<none>
10083
Block
101-
false
84+
true
10285
0
10386
false
104-
case p @ Pat2(1, -1)
87+
=> println("b")
10588

106-
5
89+
4
10790
MatchCaseClasses.scala
10891
covtest
10992
MatchCaseClasses$
@@ -120,24 +103,24 @@ false
120103
false
121104
println("c")
122105

123-
6
106+
5
124107
MatchCaseClasses.scala
125108
covtest
126109
MatchCaseClasses$
127110
Object
128111
covtest.MatchCaseClasses$
129112
f
130-
242
131-
265
132-
10
113+
222
114+
237
115+
9
133116
<none>
134117
Block
135-
false
118+
true
136119
0
137120
false
138-
case Pat2(_, y: String)
121+
=> println("c")
139122

140-
7
123+
6
141124
MatchCaseClasses.scala
142125
covtest
143126
MatchCaseClasses$
@@ -154,7 +137,7 @@ false
154137
false
155138
println(y)
156139

157-
8
140+
7
158141
MatchCaseClasses.scala
159142
covtest
160143
MatchCaseClasses$
@@ -171,24 +154,24 @@ false
171154
false
172155
println("d")
173156

174-
9
157+
8
175158
MatchCaseClasses.scala
176159
covtest
177160
MatchCaseClasses$
178161
Object
179162
covtest.MatchCaseClasses$
180163
f
181-
309
182-
321
183-
13
164+
275
165+
304
166+
11
184167
<none>
185168
Block
186-
false
169+
true
187170
0
188171
false
189-
case p: Pat2
172+
println(y)\n println("d")
190173

191-
10
174+
9
192175
MatchCaseClasses.scala
193176
covtest
194177
MatchCaseClasses$
@@ -205,24 +188,24 @@ false
205188
false
206189
println("e")
207190

208-
11
191+
10
209192
MatchCaseClasses.scala
210193
covtest
211194
MatchCaseClasses$
212195
Object
213196
covtest.MatchCaseClasses$
214197
f
215-
342
216-
348
217-
14
198+
322
199+
337
200+
13
218201
<none>
219202
Block
220-
false
203+
true
221204
0
222205
false
223-
case _
206+
=> println("e")
224207

225-
12
208+
11
226209
MatchCaseClasses.scala
227210
covtest
228211
MatchCaseClasses$
@@ -239,6 +222,23 @@ false
239222
false
240223
println("other")
241224

225+
12
226+
MatchCaseClasses.scala
227+
covtest
228+
MatchCaseClasses$
229+
Object
230+
covtest.MatchCaseClasses$
231+
f
232+
349
233+
368
234+
14
235+
<none>
236+
Block
237+
true
238+
0
239+
false
240+
=> println("other")
241+
242242
13
243243
MatchCaseClasses.scala
244244
covtest

0 commit comments

Comments
 (0)