Skip to content

Commit 817d72f

Browse files
committed
Fix macro suspensions breaking coverage
1 parent 1f0c576 commit 817d72f

File tree

3 files changed

+16
-12
lines changed

3 files changed

+16
-12
lines changed

compiler/src/dotty/tools/dotc/core/Contexts.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -982,6 +982,11 @@ object Contexts {
982982
/** Was best effort file used during compilation? */
983983
private[core] var usedBestEffortTasty = false
984984

985+
/** Counter to assign a unique id to each statement (for coverage) */
986+
private[dotc] var coverageStatementId = 0
987+
/** A variable denoting if the coverage file already written to (for coverage) */
988+
private[dotc] var coverageStartedWriting = false
989+
985990
// Types state
986991
/** A table for hash consing unique types */
987992
private[core] val uniques: Uniques = Uniques()

compiler/src/dotty/tools/dotc/coverage/Serializer.scala

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
package dotty.tools.dotc
22
package coverage
33

4-
import java.nio.file.{Path, Paths, Files}
4+
import java.nio.file.{Path, Paths, Files, StandardOpenOption}
55
import java.io.Writer
66
import scala.language.unsafeNulls
77
import scala.collection.mutable.StringBuilder
8+
import dotty.tools.dotc.core.Contexts.Context
89

910
/**
1011
* Serializes scoverage data.
@@ -16,20 +17,20 @@ object Serializer:
1617
private val CoverageDataFormatVersion = "3.0"
1718

1819
/** Write out coverage data to the given data directory, using the default coverage filename */
19-
def serialize(coverage: Coverage, dataDir: String, sourceRoot: String): Unit =
20+
def serialize(coverage: Coverage, dataDir: String, sourceRoot: String)(using Context): Unit =
2021
serialize(coverage, Paths.get(dataDir, CoverageFileName).toAbsolutePath, Paths.get(sourceRoot).toAbsolutePath)
2122

2223
/** Write out coverage data to a file. */
23-
def serialize(coverage: Coverage, file: Path, sourceRoot: Path): Unit =
24-
val writer = Files.newBufferedWriter(file)
24+
def serialize(coverage: Coverage, file: Path, sourceRoot: Path)(using Context): Unit =
25+
val writer = Files.newBufferedWriter(file, StandardOpenOption.CREATE, StandardOpenOption.APPEND)
2526
try
2627
serialize(coverage, writer, sourceRoot)
2728
finally
2829
writer.close()
2930

3031
/** Write out coverage data (info about each statement that can be covered) to a writer.
3132
*/
32-
def serialize(coverage: Coverage, writer: Writer, sourceRoot: Path): Unit =
33+
def serialize(coverage: Coverage, writer: Writer, sourceRoot: Path)(using ctx: Context): Unit =
3334

3435
def getRelativePath(filePath: Path): String =
3536
// We need to normalize the path here because the relativizing paths containing '.' or '..' differs between Java versions
@@ -81,7 +82,8 @@ object Serializer:
8182
|\f
8283
|""".stripMargin)
8384

84-
writeHeader(writer)
85+
if (!ctx.base.coverageStartedWriting) writeHeader(writer)
86+
ctx.base.coverageStartedWriting = true
8587
coverage.statements.toSeq
8688
.sortBy(_.id)
8789
.foreach(stmt => writeStatement(stmt, writer))

compiler/src/dotty/tools/dotc/transform/InstrumentCoverage.scala

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,6 @@ class InstrumentCoverage extends MacroTransform with IdentityDenotTransformer:
3838
override def isEnabled(using ctx: Context) =
3939
ctx.settings.coverageOutputDir.value.nonEmpty
4040

41-
// counter to assign a unique id to each statement
42-
private var statementId = 0
43-
4441
// stores all instrumented statements
4542
private val coverage = Coverage()
4643

@@ -54,7 +51,7 @@ class InstrumentCoverage extends MacroTransform with IdentityDenotTransformer:
5451
val dataDir = File(outputPath)
5552
val newlyCreated = dataDir.mkdirs()
5653

57-
if !newlyCreated then
54+
if !newlyCreated && !ctx.base.coverageStartedWriting then
5855
// If the directory existed before, let's clean it up.
5956
dataDir.listFiles.nn
6057
.filter(_.nn.getName.nn.startsWith("scoverage"))
@@ -110,8 +107,8 @@ class InstrumentCoverage extends MacroTransform with IdentityDenotTransformer:
110107
* @return the statement's id
111108
*/
112109
private def recordStatement(tree: Tree, pos: SourcePosition, branch: Boolean)(using ctx: Context): Int =
113-
val id = statementId
114-
statementId += 1
110+
val id = ctx.base.coverageStatementId
111+
ctx.base.coverageStatementId += 1
115112

116113
val sourceFile = pos.source
117114
val statement = Statement(

0 commit comments

Comments
 (0)