or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

aggregation.mdcobertura-reports.mdcoverage-model.mdhtml-reports.mdindex.mdio-utils.mdplugin.mdruntime.mdserialization.mdxml-reports.md

plugin.mddocs/

0

# Compiler Plugin

1

2

The Scalac Scoverage Plugin is a Scala compiler plugin that instruments source code during compilation to enable coverage measurement. It adds instrumentation calls to statements and branches, allowing runtime collection of coverage data during test execution.

3

4

## Capabilities

5

6

### Main Plugin Class

7

8

The core compiler plugin that integrates with the Scala compiler.

9

10

```scala { .api }

11

/**

12

* Main Scoverage compiler plugin class

13

* @param global The Scala compiler's Global object

14

*/

15

class ScoveragePlugin(val global: Global) extends Plugin {

16

/** Plugin name identifier */

17

val name: String

18

19

/** Human-readable plugin description */

20

val description: String

21

22

/** List of plugin components that perform the instrumentation */

23

val components: List[PluginComponent]

24

25

/** Initialize plugin with command-line options */

26

def init(opts: List[String], error: String => Unit): Boolean

27

28

/** Help text for plugin options */

29

val optionsHelp: Option[String]

30

}

31

```

32

33

### Plugin Configuration

34

35

Configuration options for controlling plugin behavior.

36

37

```scala { .api }

38

/**

39

* Configuration options for the Scoverage plugin

40

* @param excludedPackages Regex patterns for packages to exclude from instrumentation

41

* @param excludedFiles Regex patterns for files to exclude from instrumentation

42

* @param excludedSymbols Regex patterns for symbols to exclude from instrumentation

43

* @param dataDir Directory where coverage data files are written

44

* @param reportTestName Whether to include test names in coverage reports

45

* @param sourceRoot Root directory for source files

46

*/

47

case class ScoverageOptions(

48

excludedPackages: Seq[String],

49

excludedFiles: Seq[String],

50

excludedSymbols: Seq[String],

51

dataDir: String,

52

reportTestName: Boolean,

53

sourceRoot: String

54

)

55

56

object ScoverageOptions {

57

/** Create default options */

58

def default(): ScoverageOptions

59

60

/** Parse command-line options into ScoverageOptions */

61

def parse(scalacOptions: List[String], errFn: String => Unit, base: ScoverageOptions): ScoverageOptions

62

63

/** Process phase options for before/after phase configuration */

64

def processPhaseOptions(opts: List[String]): (Option[String], Option[String])

65

66

/** Help text for all available options */

67

val help: Option[String]

68

}

69

```

70

71

**Usage Examples:**

72

73

```scala

74

import scoverage.ScoverageOptions

75

76

// Create custom configuration

77

val options = ScoverageOptions(

78

excludedPackages = Seq(".*\\.test\\..*", ".*\\.generated\\..*"),

79

excludedFiles = Seq(".*DatabaseMigrations.*"),

80

excludedSymbols = Seq(".*Logger.*"),

81

dataDir = "target/scoverage-data",

82

reportTestName = true,

83

sourceRoot = "src/main/scala"

84

)

85

86

// Parse from compiler options

87

val opts = List(

88

"-P:scoverage:dataDir:target/scoverage-data",

89

"-P:scoverage:excludedPackages:.*\\.test\\..*",

90

"-P:scoverage:reportTestName:true"

91

)

92

val parsed = ScoverageOptions.parse(opts, println, ScoverageOptions.default())

93

```

94

95

### Coverage Filtering

96

97

Control which code gets instrumented for coverage measurement.

98

99

```scala { .api }

100

/**

101

* Base trait for filtering what code should be included in coverage

102

*/

103

trait CoverageFilter {

104

/** Check if a class should be included in coverage */

105

def isClassIncluded(className: String): Boolean

106

107

/** Check if a source file should be included in coverage */

108

def isFileIncluded(file: SourceFile): Boolean

109

110

/** Check if a specific line position should be included */

111

def isLineIncluded(position: Position): Boolean

112

113

/** Check if a symbol should be included in coverage */

114

def isSymbolIncluded(symbolName: String): Boolean

115

116

/** Get line number ranges that are excluded from coverage */

117

def getExcludedLineNumbers(sourceFile: SourceFile): List[Range]

118

}

119

120

/**

121

* Filter that includes all code (no exclusions)

122

*/

123

object AllCoverageFilter extends CoverageFilter

124

125

/**

126

* Regex-based filter for excluding code from coverage

127

* @param excludedPackages Regex patterns for package exclusion

128

* @param excludedFiles Regex patterns for file exclusion

129

* @param excludedSymbols Regex patterns for symbol exclusion

130

* @param reporter Compiler reporter for error handling

131

*/

132

class RegexCoverageFilter(

133

excludedPackages: Seq[String],

134

excludedFiles: Seq[String],

135

excludedSymbols: Seq[String],

136

reporter: Reporter

137

) extends CoverageFilter

138

```

139

140

**Usage Examples:**

141

142

```scala

143

import scoverage.{RegexCoverageFilter, AllCoverageFilter}

144

145

// Create filter with exclusions

146

val filter = new RegexCoverageFilter(

147

excludedPackages = Seq(".*\\.test\\..*", ".*\\.generated\\..*"),

148

excludedFiles = Seq(".*Migration.*\\.scala"),

149

excludedSymbols = Seq(".*Logger.*", ".*Debug.*"),

150

reporter = global.reporter

151

)

152

153

// Check if class should be covered

154

val shouldCover = filter.isClassIncluded("com.example.service.UserService")

155

156

// Use no-exclusion filter

157

val allFilter = AllCoverageFilter

158

```

159

160

### Instrumentation Component

161

162

The component that performs the actual code instrumentation.

163

164

```scala { .api }

165

/**

166

* Compiler plugin component that performs code instrumentation

167

* @param global The Scala compiler's Global object

168

* @param extraAfterPhase Optional phase to run after

169

* @param extraBeforePhase Optional phase to run before

170

*/

171

class ScoverageInstrumentationComponent(

172

val global: Global,

173

extraAfterPhase: Option[String],

174

extraBeforePhase: Option[String]

175

) extends PluginComponent with TypingTransformers with Transform {

176

177

/** Phase name for the instrumentation */

178

val phaseName: String

179

180

/** Phases this component must run after */

181

val runsAfter: List[String]

182

183

/** Phases this component must run before */

184

val runsBefore: List[String]

185

186

/** Configure options for this component */

187

def setOptions(options: ScoverageOptions): Unit

188

189

/** Create new phase instance */

190

def newPhase(prev: scala.tools.nsc.Phase): Phase

191

}

192

```

193

194

### Location Utilities

195

196

Utilities for extracting location information from compiler AST nodes.

197

198

```scala { .api }

199

/**

200

* Utilities for extracting location information from compiler trees

201

*/

202

object Location {

203

/**

204

* Create location extractor function for a specific compiler instance

205

* @param global The compiler's Global object

206

* @returns Function to extract Location from compiler Tree nodes

207

*/

208

def fromGlobal(global: Global): global.Tree => Option[scoverage.domain.Location]

209

}

210

```

211

212

## Compiler Plugin Usage

213

214

### Command Line Options

215

216

The plugin accepts several command-line options via the `-P:scoverage:` prefix:

217

218

- `-P:scoverage:dataDir:<path>` - Directory for coverage data files

219

- `-P:scoverage:excludedPackages:<regex>` - Semicolon-separated regexes for package exclusion

220

- `-P:scoverage:excludedFiles:<regex>` - Semicolon-separated regexes for file exclusion

221

- `-P:scoverage:excludedSymbols:<regex>` - Semicolon-separated regexes for symbol exclusion

222

- `-P:scoverage:reportTestName:<boolean>` - Include test names in coverage data

223

- `-P:scoverage:sourceRoot:<path>` - Root directory for source files

224

225

### SBT Integration

226

227

```scala

228

// project/plugins.sbt

229

addSbtPlugin("org.scoverage" % "sbt-scoverage" % "2.3.0")

230

231

// build.sbt

232

scoverageExcludedPackages := ".*\\.test\\..*;.*\\.generated\\..*"

233

scoverageExcludedFiles := ".*DatabaseMigrations.*"

234

scoverageMinimumCoverage := 80.0

235

scoverageFailOnMinimumCoverage := true

236

```

237

238

### Manual Configuration

239

240

```scala

241

// Add to scalacOptions

242

scalacOptions ++= Seq(

243

"-Xplugin:/path/to/scalac-scoverage-plugin.jar",

244

"-P:scoverage:dataDir:target/scoverage-data",

245

"-P:scoverage:excludedPackages:.*\\.test\\..*;.*\\.generated\\..*",

246

"-P:scoverage:reportTestName:true",

247

"-P:scoverage:sourceRoot:src/main/scala"

248

)

249

```

250

251

### Exclusion Comments

252

253

Code can be excluded from coverage using special comments:

254

255

```scala

256

// $COVERAGE-OFF$

257

def debugOnlyMethod(): Unit = {

258

println("This won't be covered")

259

}

260

// $COVERAGE-ON$

261

262

def normalMethod(): Unit = {

263

// This will be covered normally

264

println("Normal method")

265

}

266

```

267

268

## Error Handling

269

270

- **PluginInitException**: Thrown when plugin fails to initialize with provided options

271

- **InstrumentationException**: Thrown when code instrumentation fails due to unsupported constructs

272

- **ConfigurationException**: Thrown when invalid configuration options are provided

273

- **FileSystemException**: Thrown when unable to create coverage data directory or write coverage files