Skip to content

Commit 624f048

Browse files
committed
Added pretty output for scoverage XML. Added symbol info to measured statements.
1 parent eacaf79 commit 624f048

File tree

3 files changed

+50
-29
lines changed

3 files changed

+50
-29
lines changed

src/main/scala/scoverage/coverage.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ case class MeasuredStatement(source: String,
8080
end: Int,
8181
line: Int,
8282
desc: String,
83+
symbolName: String,
8384
branch: Boolean,
8485
var count: Int = 0) extends java.io.Serializable {
8586
def invoked(): Unit = count = count + 1

src/main/scala/scoverage/plugin.scala

Lines changed: 44 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -88,11 +88,13 @@ class ScoverageComponent(val global: Global)
8888
val id = statementIds.incrementAndGet
8989
val statement = MeasuredStatement(
9090
source.path,
91-
location, id,
91+
location,
92+
id,
9293
safeStart(tree),
9394
safeEnd(tree),
9495
safeLine(tree),
9596
tree.toString(),
97+
tree.symbol.fullNameString,
9698
branch
9799
)
98100
coverage.add(statement)
@@ -103,6 +105,13 @@ class ScoverageComponent(val global: Global)
103105
}
104106
}
105107

108+
def className(s: Symbol): String = {
109+
if (s.enclClass.isAnonymousFunction || s.enclClass.isAnonymousFunction)
110+
className(s.owner)
111+
else
112+
s.enclClass.fullNameString
113+
}
114+
106115
def updateLocation(s: Symbol) {
107116
val classType = {
108117
if (s.owner.enclClass.isTrait) ClassType.Trait
@@ -111,7 +120,7 @@ class ScoverageComponent(val global: Global)
111120
}
112121
location = Location(
113122
s.owner.enclosingPackage.fullName,
114-
s.owner.enclClass.fullNameString,
123+
className(s),
115124
classType,
116125
Option(s.owner.enclMethod.nameString).getOrElse("<none>")
117126
)
@@ -126,9 +135,15 @@ class ScoverageComponent(val global: Global)
126135
case apply: Apply =>
127136
instrument(treeCopy.Apply(apply, apply.fun, transformStatements(apply.args)))
128137

129-
// just carry on as normal with a block, we'll process the children
130-
case b: Block =>
131-
treeCopy.Block(b, transformStatements(b.stats), transform(b.expr))
138+
/** pattern match with syntax `Block(stats, expr)`.
139+
* This AST node corresponds to the following Scala code:
140+
*
141+
* { stats; expr }
142+
*
143+
* If the block is empty, the `expr` is set to `Literal(Constant(()))`.
144+
*/
145+
case b: Block => super.transform(tree)
146+
//treeCopy.Block(b, transformStatements(b.stats), transform(b.expr))
132147

133148
case _: Import => super.transform(tree)
134149
case p: PackageDef => super.transform(tree)
@@ -142,18 +157,13 @@ class ScoverageComponent(val global: Global)
142157
updateLocation(c.symbol)
143158
super.transform(tree)
144159

145-
case t: Template =>
146-
treeCopy.Template(tree, t.parents, t.self, transformStatements(t.body))
147-
148-
case _: TypeTree => super.transform(tree)
149-
150160
case d: DefDef if tree.symbol.isConstructor && (tree.symbol.isTrait || tree.symbol.isModule) => tree
151161

152162
// todo handle constructors, as a method?
153-
case d: DefDef if tree.symbol.isConstructor => tree
163+
case d: DefDef if tree.symbol.isConstructor => super.transform(tree)
154164

155165
// ignore case param/accessors
156-
case d: DefDef if d.symbol.isCaseAccessor => tree
166+
case d: DefDef if d.symbol.isCaseAccessor => super.transform(tree)
157167

158168
// ignore accessors as they are generated
159169
case d: DefDef if d.symbol.isStable && d.symbol.isAccessor => tree // hidden accessor methods
@@ -165,32 +175,37 @@ class ScoverageComponent(val global: Global)
165175
case d: DefDef if d.symbol.isAccessor && d.symbol.isSetter => tree
166176

167177
// abstract methods ??
168-
case d: DefDef if tree.symbol.isDeferred => tree
178+
case d: DefDef if tree.symbol.isDeferred => super.transform(tree)
169179

170180
// generated methods
171-
case d: DefDef if d.symbol.isSynthetic =>
172-
super.transform(tree)
181+
case d: DefDef if d.symbol.isSynthetic => super.transform(tree)
173182

174183
case d: DefDef if d.symbol.isCaseApplyOrUnapply =>
175-
println("Case apply/unapply " + d)
176184
updateLocation(d.symbol)
177185
super.transform(tree)
178186

187+
/** pattern match with syntax `DefDef(mods, name, tparams, vparamss, tpt, rhs)`.
188+
* This AST node corresponds to the following Scala code:
189+
*
190+
* mods `def` name[tparams](vparams_1)...(vparams_n): tpt = rhs
191+
*
192+
* If the return type is not specified explicitly (i.e. is meant to be inferred),
193+
* this is expressed by having `tpt` set to `TypeTree()` (but not to an `EmptyTree`!).
194+
*/
179195
// user defined methods
180196
case d: DefDef =>
181197
updateLocation(d.symbol)
182198
super.transform(tree)
183199

184-
case _: Ident =>
185-
super.transform(tree)
186-
187-
case i: If =>
188-
treeCopy.If(i, process(i.cond), transformIf(i.thenp), transformIf(i.elsep))
189-
190200
// handle function bodies. This AST node corresponds to the following Scala code: vparams => body
191201
case f: Function =>
192202
treeCopy.Function(tree, f.vparams, process(f.body))
193203

204+
case _: Ident => super.transform(tree)
205+
206+
case i: If =>
207+
treeCopy.If(i, process(i.cond), transformIf(i.thenp), transformIf(i.elsep))
208+
194209
// labeldefs are never written natively in scala
195210
case l: LabelDef =>
196211
treeCopy.LabelDef(tree, l.name, l.params, transform(l.rhs))
@@ -203,7 +218,7 @@ class ScoverageComponent(val global: Global)
203218
treeCopy.Match(tree, instrument(clause), transformCases(cases))
204219

205220
// a synthetic object is a generated object, such as case class companion
206-
case m: ModuleDef if m.symbol.isSynthetic => tree
221+
case m: ModuleDef if m.symbol.isSynthetic => super.transform(tree)
207222

208223
// user defined objects
209224
case m: ModuleDef =>
@@ -218,8 +233,7 @@ class ScoverageComponent(val global: Global)
218233
case t: Typed => super.transform(tree)
219234

220235
// should only occur inside something we are instrumenting.
221-
case s: Select =>
222-
super.transform(tree)
236+
case s: Select => super.transform(tree)
223237

224238
//case s: Super =>
225239
// treeCopy.Super(s, s.qual, s.mix)
@@ -237,6 +251,11 @@ class ScoverageComponent(val global: Global)
237251
// type aliases, type parameters, abstract types
238252
case t: TypeDef => super.transform(tree)
239253

254+
case t: Template =>
255+
treeCopy.Template(tree, t.parents, t.self, transformStatements(t.body))
256+
257+
case _: TypeTree => super.transform(tree)
258+
240259
// case param accessors are auto generated
241260
case v: ValDef if v.symbol.isCaseAccessor => super.transform(tree)
242261

src/main/scala/scoverage/report/ScoverageXmlWriter.scala

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package scoverage.report
22

3-
import scala.xml.Node
3+
import scala.xml.{PrettyPrinter, Node}
44
import java.io.File
55
import org.apache.commons.io.FileUtils
66
import scoverage._
@@ -12,7 +12,7 @@ import scoverage.MeasuredMethod
1212
object ScoverageXmlWriter extends CoverageWriter {
1313

1414
def write(coverage: Coverage, dir: File): Unit = {
15-
FileUtils.write(new File(dir.getAbsolutePath + "/scoverage.xml"), xml(coverage).toString())
15+
FileUtils.write(new File(dir.getAbsolutePath + "/scoverage.xml"), new PrettyPrinter(120, 4).format(xml(coverage)))
1616
}
1717

1818
def statement(stmt: MeasuredStatement): Node = {
@@ -21,6 +21,7 @@ object ScoverageXmlWriter extends CoverageWriter {
2121
method={stmt.location.method}
2222
start={stmt.start.toString}
2323
line={stmt.line.toString}
24+
symbol={stmt.symbolName}
2425
invocation-count={stmt.count.toString}>
2526
{stmt.desc}
2627
</statement>
@@ -55,8 +56,8 @@ object ScoverageXmlWriter extends CoverageWriter {
5556

5657
def xml(coverage: Coverage): Node = {
5758
<scoverage statement-rate={coverage.statementCoverage.toString}
58-
version="1.0"
59-
timestamp={System.currentTimeMillis.toString}>
59+
version="1.0"
60+
timestamp={System.currentTimeMillis.toString}>
6061
<packages>
6162
{coverage.packages.map(pack)}
6263
</packages>

0 commit comments

Comments
 (0)