diff --git a/compiler/src/dotty/tools/dotc/coverage/Coverage.scala b/compiler/src/dotty/tools/dotc/coverage/Coverage.scala index 8ae249c1f5a3..e41bfcd5d09a 100644 --- a/compiler/src/dotty/tools/dotc/coverage/Coverage.scala +++ b/compiler/src/dotty/tools/dotc/coverage/Coverage.scala @@ -13,7 +13,6 @@ class Coverage: /** A statement that can be invoked, and thus counted as "covered" by code coverage tools. */ case class Statement( - source: String, location: Location, id: Int, start: Int, diff --git a/compiler/src/dotty/tools/dotc/coverage/Location.scala b/compiler/src/dotty/tools/dotc/coverage/Location.scala index faf1e97d0c01..c565c2bb1116 100644 --- a/compiler/src/dotty/tools/dotc/coverage/Location.scala +++ b/compiler/src/dotty/tools/dotc/coverage/Location.scala @@ -5,6 +5,7 @@ import ast.tpd._ import dotty.tools.dotc.core.Contexts.Context import dotty.tools.dotc.core.Flags.* import java.nio.file.Path +import dotty.tools.dotc.util.SourceFile /** Information about the location of a coverable piece of code. * @@ -12,7 +13,7 @@ import java.nio.file.Path * @param className name of the closest enclosing class * @param fullClassName fully qualified name of the closest enclosing class * @param classType "type" of the closest enclosing class: Class, Trait or Object - * @param method name of the closest enclosing method + * @param method name of the closest enclosing method * @param sourcePath absolute path of the source file */ final case class Location( @@ -20,17 +21,19 @@ final case class Location( className: String, fullClassName: String, classType: String, - method: String, + methodName: String, sourcePath: Path ) object Location: /** Extracts the location info of a Tree. */ - def apply(tree: Tree)(using ctx: Context): Location = + def apply(tree: Tree, source: SourceFile)(using ctx: Context): Location = - val enclosingClass = ctx.owner.denot.enclosingClass - val packageName = ctx.owner.denot.enclosingPackageClass.name.toSimpleName.toString + val ownerDenot = ctx.owner.denot + val enclosingClass = ownerDenot.enclosingClass + val packageName = ownerDenot.enclosingPackageClass.fullName.toSimpleName.toString val className = enclosingClass.name.toSimpleName.toString + val methodName = ownerDenot.enclosingMethod.name.toSimpleName.toString val classType: String = if enclosingClass.is(Trait) then "Trait" @@ -42,6 +45,6 @@ object Location: className, s"$packageName.$className", classType, - ctx.owner.denot.enclosingMethod.name.toSimpleName.toString(), - ctx.source.file.absolute.jpath + methodName, + source.file.absolute.jpath ) diff --git a/compiler/src/dotty/tools/dotc/coverage/Serializer.scala b/compiler/src/dotty/tools/dotc/coverage/Serializer.scala index 23ab73f6d42e..26efa8934e00 100644 --- a/compiler/src/dotty/tools/dotc/coverage/Serializer.scala +++ b/compiler/src/dotty/tools/dotc/coverage/Serializer.scala @@ -4,6 +4,7 @@ package coverage import java.nio.file.{Path, Paths, Files} import java.io.Writer import scala.language.unsafeNulls +import scala.collection.mutable.StringBuilder /** * Serializes scoverage data. @@ -62,21 +63,21 @@ object Serializer: def writeStatement(stmt: Statement, writer: Writer): Unit = // Note: we write 0 for the count because we have not measured the actual coverage at this point writer.write(s"""${stmt.id} - |${getRelativePath(stmt.location.sourcePath)} - |${stmt.location.packageName} - |${stmt.location.className} + |${getRelativePath(stmt.location.sourcePath).escaped} + |${stmt.location.packageName.escaped} + |${stmt.location.className.escaped} |${stmt.location.classType} - |${stmt.location.fullClassName} - |${stmt.location.method} + |${stmt.location.fullClassName.escaped} + |${stmt.location.methodName.escaped} |${stmt.start} |${stmt.end} |${stmt.line} - |${stmt.symbolName} + |${stmt.symbolName.escaped} |${stmt.treeName} |${stmt.branch} |0 |${stmt.ignored} - |${stmt.desc} + |${stmt.desc.escaped} |\f |""".stripMargin) @@ -84,3 +85,27 @@ object Serializer: coverage.statements.toSeq .sortBy(_.id) .foreach(stmt => writeStatement(stmt, writer)) + + /** Makes a String suitable for output in the coverage statement data as a single line. + * Escaped characters: '\\' (backslash), '\n', '\r', '\f' + */ + extension (str: String) def escaped: String = + val builder = StringBuilder(str.length) + var i = 0 + while + i < str.length + do + str.charAt(i) match + case '\\' => + builder ++= "\\\\" + case '\n' => + builder ++= "\\n" + case '\r' => + builder ++= "\\r" + case '\f' => + builder ++= "\\f" + case c => + builder += c + i += 1 + end while + builder.result() diff --git a/compiler/src/dotty/tools/dotc/transform/InstrumentCoverage.scala b/compiler/src/dotty/tools/dotc/transform/InstrumentCoverage.scala index 1cc1340ad7c7..c69b342b9a01 100644 --- a/compiler/src/dotty/tools/dotc/transform/InstrumentCoverage.scala +++ b/compiler/src/dotty/tools/dotc/transform/InstrumentCoverage.scala @@ -14,15 +14,17 @@ import core.NameOps.isContextFunction import core.Types.* import coverage.* import typer.LiftCoverage -import util.SourcePosition +import util.{SourcePosition, SourceFile} import util.Spans.Span import localopt.StringInterpolatorOpt +import inlines.Inlines /** Implements code coverage by inserting calls to scala.runtime.coverage.Invoker * ("instruments" the source code). * The result can then be consumed by the Scoverage tool. */ class InstrumentCoverage extends MacroTransform with IdentityDenotTransformer: + import InstrumentCoverage.{InstrumentedParts, ExcludeMethodFlags} override def phaseName = InstrumentCoverage.name @@ -55,186 +57,335 @@ class InstrumentCoverage extends MacroTransform with IdentityDenotTransformer: Serializer.serialize(coverage, outputPath, ctx.settings.sourceroot.value) - override protected def newTransformer(using Context) = CoverageTransformer() + override protected def newTransformer(using Context) = + CoverageTransformer(ctx.settings.coverageOutputDir.value) /** Transforms trees to insert calls to Invoker.invoked to compute the coverage when the code is called */ - private class CoverageTransformer extends Transformer: + private class CoverageTransformer(outputPath: String) extends Transformer: + private val ConstOutputPath = Constant(outputPath) + + /** Generates the tree for: + * ``` + * Invoker.invoked(id, DIR) + * ``` + * where DIR is the _outputPath_ defined by the coverage settings. + */ + private def invokeCall(id: Int, span: Span)(using Context): Apply = + ref(defn.InvokedMethodRef).withSpan(span) + .appliedToArgs( + Literal(Constant(id)) :: Literal(ConstOutputPath) :: Nil + ).withSpan(span) + .asInstanceOf[Apply] + + /** + * Records information about a new coverable statement. Generates a unique id for it. + * + * @param tree the tree to add to the coverage report + * @param pos the position to save in the report + * @param branch true if it's a branch (branches are considered differently by most coverage analysis tools) + * @param ctx the current context + * @return the statement's id + */ + private def recordStatement(tree: Tree, pos: SourcePosition, branch: Boolean)(using ctx: Context): Int = + val id = statementId + statementId += 1 + + val sourceFile = pos.source + val statement = Statement( + location = Location(tree, sourceFile), + id = id, + start = pos.start, + end = pos.end, + line = pos.line, + desc = sourceFile.content.slice(pos.start, pos.end).mkString, + symbolName = tree.symbol.name.toSimpleName.toString, + treeName = tree.getClass.getSimpleName.nn, + branch + ) + coverage.addStatement(statement) + id + + /** + * Adds a new statement to the current `Coverage` and creates a corresponding call + * to `Invoker.invoke` with its id, and the given position. + * + * Note that the entire tree won't be saved in the coverage analysis, only some + * data related to the tree is recorded (e.g. its type, its parent class, ...). + * + * @param tree the tree to add to the coverage report + * @param pos the position to save in the report + * @param branch true if it's a branch + * @return the tree corresponding to the call to `Invoker.invoke` + */ + private def createInvokeCall(tree: Tree, pos: SourcePosition, branch: Boolean = false)(using Context): Apply = + val statementId = recordStatement(tree, pos, branch) + val span = pos.span.toSynthetic + invokeCall(statementId, span) + + /** + * Tries to instrument an `Apply`. + * These "tryInstrument" methods are useful to tweak the generation of coverage instrumentation, + * in particular in `case TypeApply` in the [[transform]] method. + * + * @param tree the tree to instrument + * @return instrumentation result, with the preparation statement, coverage call and tree separated + */ + private def tryInstrument(tree: Apply)(using Context): InstrumentedParts = + if canInstrumentApply(tree) then + // Create a call to Invoker.invoked(coverageDirectory, newStatementId) + val coverageCall = createInvokeCall(tree, tree.sourcePos) + + if needsLift(tree) then + // Transform args and fun, i.e. instrument them if needed (and if possible) + val app = cpy.Apply(tree)(transform(tree.fun), tree.args.map(transform)) + + // Lifts the arguments. Note that if only one argument needs to be lifted, we lift them all. + // Also, tree.fun can be lifted too. + // See LiftCoverage for the internal working of this lifting. + val liftedDefs = mutable.ListBuffer[Tree]() + val liftedApp = LiftCoverage.liftForCoverage(liftedDefs, app) + + InstrumentedParts(liftedDefs.toList, coverageCall, liftedApp) + else + // Instrument without lifting + val transformed = cpy.Apply(tree)(transform(tree.fun), transform(tree.args)) + InstrumentedParts.singleExpr(coverageCall, transformed) + else + // Transform recursively but don't instrument the tree itself + val transformed = cpy.Apply(tree)(transform(tree.fun), transform(tree.args)) + InstrumentedParts.notCovered(transformed) + + private def tryInstrument(tree: Ident)(using Context): InstrumentedParts = + val sym = tree.symbol + if canInstrumentParameterless(sym) then + // call to a local parameterless method f + val coverageCall = createInvokeCall(tree, tree.sourcePos) + InstrumentedParts.singleExpr(coverageCall, tree) + else + InstrumentedParts.notCovered(tree) + + private def tryInstrument(tree: Select)(using Context): InstrumentedParts = + val sym = tree.symbol + val transformed = cpy.Select(tree)(transform(tree.qualifier), tree.name) + if canInstrumentParameterless(sym) then + // call to a parameterless method + val coverageCall = createInvokeCall(tree, tree.sourcePos) + InstrumentedParts.singleExpr(coverageCall, transformed) + else + InstrumentedParts.notCovered(transformed) + + /** Generic tryInstrument */ + private def tryInstrument(tree: Tree)(using Context): InstrumentedParts = + tree match + case t: Apply => tryInstrument(t) + case t: Ident => tryInstrument(t) + case t: Select => tryInstrument(t) + case _ => InstrumentedParts.notCovered(transform(tree)) + + /** + * Transforms and instruments a branch if it's non-empty. + * If the tree is empty, return itself and don't instrument. + */ + private def transformBranch(tree: Tree)(using Context): Tree = + import dotty.tools.dotc.core.Decorators.{show,i} + if tree.isEmpty || tree.span.isSynthetic then + // - If t.isEmpty then `transform(t) == t` always hold, + // so we can avoid calling transform in that case. + // - If tree.span.isSynthetic then the branch has been generated + // by the frontend phases, so we don't want to instrument it. + tree + else + val transformed = transform(tree) + val coverageCall = createInvokeCall(tree, tree.sourcePos, branch = true) + InstrumentedParts.singleExprTree(coverageCall, transformed) + override def transform(tree: Tree)(using Context): Tree = inContext(transformCtx(tree)) { // necessary to position inlined code properly tree match // simple cases case tree: (Import | Export | Literal | This | Super | New) => tree case tree if tree.isEmpty || tree.isType => tree // empty Thicket, Ident (referring to a type), TypeTree, ... + case tree if !tree.span.exists || tree.span.isZeroExtent => tree // no meaningful position // identifier case tree: Ident => - val sym = tree.symbol - if canInstrumentParameterless(sym) then - // call to a local parameterless method f - instrument(tree) - else - tree + tryInstrument(tree).toTree // branches case tree: If => cpy.If(tree)( cond = transform(tree.cond), - thenp = instrument(transform(tree.thenp), branch = true), - elsep = instrument(transform(tree.elsep), branch = true) + thenp = transformBranch(tree.thenp), + elsep = transformBranch(tree.elsep) ) case tree: Try => cpy.Try(tree)( - expr = instrument(transform(tree.expr), branch = true), - cases = instrumentCases(tree.cases), - finalizer = instrument(transform(tree.finalizer), branch = true) + expr = transformBranch(tree.expr), + cases = tree.cases.map(transformCaseDef), + finalizer = transformBranch(tree.finalizer) ) // f(args) case tree: Apply => - if canInstrumentApply(tree) then - if needsLift(tree) then - instrumentLifted(tree) - else - instrument(transformApply(tree)) - else - transformApply(tree) + tryInstrument(tree).toTree // (fun)[args] case TypeApply(fun, args) => - val tfun = transform(fun) - tfun match - case InstrumentCoverage.InstrumentedBlock(invokeCall, expr) => - // expr[T] shouldn't be transformed to - // {invoked(...), expr}[T] - // - // but to - // {invoked(...), expr[T]} - // - // This is especially important for trees like (expr[T])(args), - // for which the wrong transformation crashes the compiler. - // See tests/coverage/pos/PolymorphicExtensions.scala - Block( - invokeCall :: Nil, - cpy.TypeApply(tree)(expr, args) - ) - case _ => - cpy.TypeApply(tree)(tfun, args) + // Here is where `InstrumentedParts` becomes useful! + // We extract its components and act carefully. + val InstrumentedParts(pre, coverageCall, expr) = tryInstrument(fun) - // a.b - case Select(qual, name) => - val transformed = cpy.Select(tree)(transform(qual), name) - val sym = tree.symbol - if canInstrumentParameterless(sym) then - // call to a parameterless method - instrument(transformed) + if coverageCall.isEmpty then + // `fun` cannot be instrumented, and `args` is a type so we keep this tree as it is + tree else - transformed + // expr[T] shouldn't be transformed to: + // {invoked(...), expr}[T] + // + // but to: + // {invoked(...), expr[T]} + // + // This is especially important for trees like (expr[T])(args), + // for which the wrong transformation crashes the compiler. + // See tests/coverage/pos/PolymorphicExtensions.scala + Block( + pre :+ coverageCall, + cpy.TypeApply(tree)(expr, args) + ) + + // a.b + case tree: Select => + tryInstrument(tree).toTree + + case tree: CaseDef => + transformCaseDef(tree) - case tree: CaseDef => instrumentCaseDef(tree) case tree: ValDef => // only transform the rhs val rhs = transform(tree.rhs) cpy.ValDef(tree)(rhs = rhs) case tree: DefDef => - if tree.symbol.isOneOf(Inline | Erased) then - // Inline and erased definitions will not be in the generated code and therefore do not need to be instrumented. - // Note that a retained inline method will have a `$retained` variant that will be instrumented. - tree - else - // Only transform the params (for the default values) and the rhs. - val paramss = transformParamss(tree.paramss) - val rhs = transform(tree.rhs) - val finalRhs = - if canInstrumentDefDef(tree) then - // Ensure that the rhs is always instrumented, if possible. - // This is useful because methods can be stored and called later, or called by reflection, - // and if the rhs is too simple to be instrumented (like `def f = this`), the method won't show up as covered. - instrumentBody(tree, rhs) - else - rhs - cpy.DefDef(tree)(tree.name, paramss, tree.tpt, finalRhs) - end if + transformDefDef(tree) + case tree: PackageDef => // only transform the statements of the package cpy.PackageDef(tree)(tree.pid, transform(tree.stats)) + case tree: Assign => // only transform the rhs cpy.Assign(tree)(tree.lhs, transform(tree.rhs)) + case tree: Return => + // only transform the expr, because `from` is a "pointer" + // to the enclosing method, not a tree to instrument. + cpy.Return(tree)(expr = transform(tree.expr), from = tree.from) + + case tree: Template => + // only transform: + // - the arguments of the `Apply` trees in the parents + // - the template body + cpy.Template(tree)( + transformSub(tree.constr), + transformTemplateParents(tree.parents)(using ctx.superCallContext), + tree.derived, + tree.self, + transformStats(tree.body, tree.symbol) + ) + + case tree: Inlined => + // Ideally, tree.call would provide precise information about the inlined call, + // and we would use this information for the coverage report. + // But PostTyper simplifies tree.call, so we can't report the actual method that was inlined. + // In any case, the subtrees need to be repositioned right now, otherwise the + // coverage statement will point to a potentially unreachable source file. + val dropped = Inlines.dropInlined(tree) // drop and reposition + transform(dropped) // transform the content of the Inlined + // For everything else just recurse and transform - // Special care for Templates: it's important to set the owner of the `stats`, like super.transform case _ => super.transform(tree) } - /** Lifts and instruments an application. - * Note that if only one arg needs to be lifted, we just lift everything (see LiftCoverage). + /** Transforms a `def lhs = rhs` and instruments its body (rhs). + * + * The rhs is always transformed recursively. + * + * If possible, a coverage call is inserted at the beginning of the body + * (never outside of the DefDef tree). Therefore, this method always returns a `DefDef`. + * Thanks to this, it doesn't need to be wrapped in an`InstrumentedParts`. */ - private def instrumentLifted(tree: Apply)(using Context) = - // lifting - val buffer = mutable.ListBuffer[Tree]() - val liftedApply = LiftCoverage.liftForCoverage(buffer, tree) - - // instrumentation - val instrumentedArgs = buffer.toList.map(transform) - val instrumentedApply = instrument(liftedApply) - Block( - instrumentedArgs, - instrumentedApply - ) - - private inline def transformApply(tree: Apply)(using Context): Apply = - cpy.Apply(tree)(transform(tree.fun), transform(tree.args)) - - private inline def instrumentCases(cases: List[CaseDef])(using Context): List[CaseDef] = - cases.map(instrumentCaseDef) - - private def instrumentCaseDef(tree: CaseDef)(using Context): CaseDef = + private def transformDefDef(tree: DefDef)(using Context): DefDef = + val sym = tree.symbol + if sym.isOneOf(Inline | Erased) then + // Inline and erased definitions will not be in the generated code and therefore do not need to be instrumented. + // (Note that a retained inline method will have a `$retained` variant that will be instrumented.) + tree + else + // Only transform the params (for the default values) and the rhs, not the name and tpt. + val transformedParamss = transformParamss(tree.paramss) + val transformedRhs = + if !sym.isOneOf(Accessor | Artifact | Synthetic) && !tree.rhs.isEmpty then + // If the body can be instrumented, do it (i.e. insert a "coverage call" at the beginning) + // This is useful because methods can be stored and called later, or called by reflection, + // and if the rhs is too simple to be instrumented (like `def f = this`), + // the method won't show up as covered if we don't insert a call at its beginning. + instrumentBody(tree, transform(tree.rhs)) + else + transform(tree.rhs) + + cpy.DefDef(tree)(tree.name, transformedParamss, tree.tpt, transformedRhs) + + /** Transforms a `case ...` and instruments the parts that can be. */ + private def transformCaseDef(tree: CaseDef)(using Context): CaseDef = val pat = tree.pat val guard = tree.guard + + // compute a span that makes sense for the user that will read the coverage results val friendlyEnd = if guard.span.exists then guard.span.end else pat.span.end val pos = tree.sourcePos.withSpan(tree.span.withEnd(friendlyEnd)) // user-friendly span - // ensure that the body is always instrumented by inserting a call to Invoker.invoked at its beginning - val instrumentedBody = instrument(transform(tree.body), pos, false) - cpy.CaseDef(tree)(tree.pat, transform(tree.guard), instrumentedBody) - /** Records information about a new coverable statement. Generates a unique id for it. - * @return the statement's id - */ - private def recordStatement(tree: Tree, pos: SourcePosition, branch: Boolean)(using ctx: Context): Int = - val id = statementId - statementId += 1 - val statement = Statement( - source = ctx.source.file.name, - location = Location(tree), - id = id, - start = pos.start, - end = pos.end, - line = pos.line, - desc = tree.source.content.slice(pos.start, pos.end).mkString, - symbolName = tree.symbol.name.toSimpleName.toString, - treeName = tree.getClass.getSimpleName.nn, - branch - ) - coverage.addStatement(statement) - id - - private inline def syntheticSpan(pos: SourcePosition): Span = pos.span.toSynthetic - - /** Shortcut for instrument(tree, tree.sourcePos, branch) */ - private inline def instrument(tree: Tree, branch: Boolean = false)(using Context): Tree = - instrument(tree, tree.sourcePos, branch) + // recursively transform the guard, but keep the pat + val transformedGuard = transform(guard) - /** Instruments a statement, if it has a position. */ - private def instrument(tree: Tree, pos: SourcePosition, branch: Boolean)(using Context): Tree = - if pos.exists && !pos.span.isZeroExtent then - val statementId = recordStatement(tree, pos, branch) - insertInvokeCall(tree, pos, statementId) - else - tree - - /** Instruments the body of a DefDef. Handles corner cases. */ + // ensure that the body is always instrumented by inserting a call to Invoker.invoked at its beginning + val coverageCall = createInvokeCall(tree.body, pos) + val transformedBody = transform(tree.body) + val instrumentedBody = InstrumentedParts.singleExprTree(coverageCall, transformedBody) + + cpy.CaseDef(tree)(pat, transformedGuard, instrumentedBody) + + /** Transforms the parents of a Template. */ + private def transformTemplateParents(parents: List[Tree])(using Context): List[Tree] = + def transformParent(parent: Tree): Tree = parent match + case tree: Apply => + // only instrument the args, not the constructor call + cpy.Apply(tree)(tree.fun, tree.args.mapConserve(transform)) + case tree: TypeApply => + // args are types, instrument the fun with transformParent + cpy.TypeApply(tree)(transformParent(tree.fun), tree.args) + case other => + // should always be a TypeTree, nothing to instrument + other + + parents.mapConserve(transformParent) + + /** Instruments the body of a DefDef. Handles corner cases. + * Given a DefDef f like this: + * ``` + * def f(params) = rhs + * ``` + * + * It generally inserts a "coverage call" before rhs: + * ``` + * def f(params) = + * Invoker.invoked(id, DIR) + * rhs + * ``` + * + * But in some cases (e.g. closures), this would be invalid (see the comment below), + * and the call is inserted at another place. + */ private def instrumentBody(parent: DefDef, body: Tree)(using Context): Tree = /* recurse on closures, so that we insert the call at the leaf: @@ -256,21 +407,8 @@ class InstrumentCoverage extends MacroTransform with IdentityDenotTransformer: val namePos = parent.namePos val pos = namePos.withSpan(namePos.span.withStart(parent.span.start)) // record info and insert call to Invoker.invoked - val statementId = recordStatement(parent, pos, false) - insertInvokeCall(body, pos, statementId) - - /** Returns the tree, prepended by a call to Invoker.invoked */ - private def insertInvokeCall(tree: Tree, pos: SourcePosition, statementId: Int)(using Context): Tree = - val callSpan = syntheticSpan(pos) - Block(invokeCall(statementId, callSpan) :: Nil, tree).withSpan(callSpan.union(tree.span)) - - /** Generates Invoker.invoked(id, DIR) */ - private def invokeCall(id: Int, span: Span)(using Context): Tree = - val outputPath = ctx.settings.coverageOutputDir.value - ref(defn.InvokedMethodRef).withSpan(span) - .appliedToArgs( - List(Literal(Constant(id)), Literal(Constant(outputPath))) - ).withSpan(span) + val coverageCall = createInvokeCall(parent, pos) + InstrumentedParts.singleExprTree(coverageCall, body) /** * Checks if the apply needs a lift in the coverage phase. @@ -307,19 +445,12 @@ class InstrumentCoverage extends MacroTransform with IdentityDenotTransformer: nestedApplyNeedsLift || !isUnliftableFun(fun) && !tree.args.isEmpty && !tree.args.forall(LiftCoverage.noLift) - /** Check if the body of a DefDef can be instrumented with instrumentBody. */ - private def canInstrumentDefDef(tree: DefDef)(using Context): Boolean = - // No need to force the instrumentation of synthetic definitions - // (it would work, but it looks better without). - !tree.symbol.isOneOf(Accessor | Synthetic | Artifact) && - !tree.rhs.isEmpty - /** Check if an Apply can be instrumented. Prevents this phase from generating incorrect code. */ private def canInstrumentApply(tree: Apply)(using Context): Boolean = val sym = tree.symbol - !sym.isOneOf(Synthetic | Artifact) && // no need to instrument synthetic apply - !isCompilerIntrinsicMethod(sym) && - (tree.typeOpt match + !sym.isOneOf(ExcludeMethodFlags) + && !isCompilerIntrinsicMethod(sym) + && (tree.typeOpt match case AppliedType(tycon: NamedType, _) => /* If the last expression in a block is a context function, we'll try to summon its arguments at the current point, even if the expected type @@ -351,9 +482,10 @@ class InstrumentCoverage extends MacroTransform with IdentityDenotTransformer: * in post-erasure checking. */ private def canInstrumentParameterless(sym: Symbol)(using Context): Boolean = - sym.is(Method, butNot = Synthetic | Artifact) && - sym.info.isParameterless && - !isCompilerIntrinsicMethod(sym) + sym.is(Method, butNot = ExcludeMethodFlags) + && sym.info.isParameterless + && !isCompilerIntrinsicMethod(sym) + && !sym.info.typeSymbol.name.isContextFunction // exclude context functions like in canInstrumentApply /** Does sym refer to a "compiler intrinsic" method, which only exist during compilation, * like Any.isInstanceOf? @@ -370,15 +502,27 @@ class InstrumentCoverage extends MacroTransform with IdentityDenotTransformer: object InstrumentCoverage: val name: String = "instrumentCoverage" val description: String = "instrument code for coverage checking" - - /** Extractor object for trees produced by `insertInvokeCall`. */ - object InstrumentedBlock: - private def isInvokedCall(app: Apply)(using Context): Boolean = - app.span.isSynthetic && app.symbol == defn.InvokedMethodRef.symbol - - def unapply(t: Tree)(using Context): Option[(Apply, Tree)] = - t match - case Block((app: Apply) :: Nil, expr) if isInvokedCall(app) => - Some((app, expr)) - case _ => - None + val ExcludeMethodFlags: FlagSet = Synthetic | Artifact | Erased + + /** + * An instrumented Tree, in 3 parts. + * @param pre preparation code, e.g. lifted arguments. May be empty. + * @param invokeCall call to Invoker.invoked(dir, id), or an empty tree. + * @param expr the instrumented expression, executed just after the invokeCall + */ + case class InstrumentedParts(pre: List[Tree], invokeCall: Apply | EmptyTree.type, expr: Tree): + require(pre.isEmpty || (pre.nonEmpty && !invokeCall.isEmpty), "if pre isn't empty then invokeCall shouldn't be empty") + + /** Turns this into an actual Tree. */ + def toTree(using Context): Tree = + if invokeCall.isEmpty then expr + else if pre.isEmpty then Block(invokeCall :: Nil, expr) + else Block(pre :+ invokeCall, expr) + + object InstrumentedParts: + def notCovered(expr: Tree) = InstrumentedParts(Nil, EmptyTree, expr) + def singleExpr(invokeCall: Apply, expr: Tree) = InstrumentedParts(Nil, invokeCall, expr) + + /** Shortcut for `singleExpr(call, expr).toTree` */ + def singleExprTree(invokeCall: Apply, expr: Tree)(using Context): Tree = + Block(invokeCall :: Nil, expr) diff --git a/tests/coverage/pos/Constructor.scoverage.check b/tests/coverage/pos/Constructor.scoverage.check index 1aaf414006cd..678da472fd4c 100644 --- a/tests/coverage/pos/Constructor.scoverage.check +++ b/tests/coverage/pos/Constructor.scoverage.check @@ -59,15 +59,15 @@ C Class covtest.C -62 -63 +60 +64 5 -x -Select +f +Apply false 0 false -x +f(x) 3 Constructor.scala @@ -76,15 +76,15 @@ C Class covtest.C -60 -64 +62 +63 5 -f -Apply +x +Select false 0 false -f(x) +x 4 Constructor.scala @@ -127,15 +127,15 @@ O$ Object covtest.O$ -112 -113 +110 +114 10 -y -Ident +g +Apply false 0 false -y +g(y) 7 Constructor.scala @@ -144,13 +144,13 @@ O$ Object covtest.O$ -110 -114 +112 +113 10 -g -Apply +y +Ident false 0 false -g(y) +y diff --git a/tests/coverage/pos/ContextFunctions.scoverage.check b/tests/coverage/pos/ContextFunctions.scoverage.check index 26391cfad536..5f2a5f8e14f3 100644 --- a/tests/coverage/pos/ContextFunctions.scoverage.check +++ b/tests/coverage/pos/ContextFunctions.scoverage.check @@ -76,6 +76,40 @@ Imperative Class covtest.Imperative readPerson +252 +295 +13 + +Apply +false +0 +false +OnError((e) => readName2(using e)(using s)) + +4 +ContextFunctions.scala +covtest +Imperative +Class +covtest.Imperative +$anonfun +267 +294 +13 +apply +Apply +false +0 +false +readName2(using e)(using s) + +5 +ContextFunctions.scala +covtest +Imperative +Class +covtest.Imperative +readPerson 192 206 11 diff --git a/tests/coverage/pos/Enum.scoverage.check b/tests/coverage/pos/Enum.scoverage.check index b5bf6e7ed6a9..7e9b69be2d31 100644 --- a/tests/coverage/pos/Enum.scoverage.check +++ b/tests/coverage/pos/Enum.scoverage.check @@ -72,142 +72,23 @@ def surfaceWeight 3 Enum.scala covtest -$anon -Class -covtest.$anon - -485 -512 -17 - +EnumTypes$ +Object +covtest.EnumTypes$ +test +1043 +1077 +30 +println Apply false 0 false -Planet(3.303e+23, 2.4397e6) +println("Example 1: \\n"+emptyList) 4 Enum.scala covtest -$anon -Class -covtest.$anon - -538 -565 -18 - -Apply -false -0 -false -Planet(4.869e+24, 6.0518e6) - -5 -Enum.scala -covtest -$anon -Class -covtest.$anon - -591 -619 -19 - -Apply -false -0 -false -Planet(5.976e+24, 6.37814e6) - -6 -Enum.scala -covtest -$anon -Class -covtest.$anon - -645 -672 -20 - -Apply -false -0 -false -Planet(6.421e+23, 3.3972e6) - -7 -Enum.scala -covtest -$anon -Class -covtest.$anon - -698 -725 -21 - -Apply -false -0 -false -Planet(1.9e+27, 7.1492e7) - -8 -Enum.scala -covtest -$anon -Class -covtest.$anon - -751 -778 -22 - -Apply -false -0 -false -Planet(5.688e+26, 6.0268e7) - -9 -Enum.scala -covtest -$anon -Class -covtest.$anon - -804 -831 -23 - -Apply -false -0 -false -Planet(8.686e+25, 2.5559e7) - -10 -Enum.scala -covtest -$anon -Class -covtest.$anon - -857 -884 -24 - -Apply -false -0 -false -Planet(1.024e+26, 2.4746e7) - -11 -Enum.scala -covtest EnumTypes$ Object covtest.EnumTypes$ @@ -220,26 +101,26 @@ Apply false 0 false -"Example 1: \n"+emptyList +"Example 1: \\n"+emptyList -12 +5 Enum.scala covtest EnumTypes$ Object covtest.EnumTypes$ test -1043 -1077 -30 +1082 +1103 +31 println Apply false 0 false -println("Example 1: \n"+emptyList) +println(s"${list}\\n") -13 +6 Enum.scala covtest EnumTypes$ @@ -254,43 +135,43 @@ Apply false 0 false -s"${list}\n" +s"${list}\\n" -14 +7 Enum.scala covtest EnumTypes$ Object covtest.EnumTypes$ -test -1082 -1103 -31 -println -Apply +calculateEarthWeightOnPlanets +1195 +1222 +34 +surfaceGravity +Select false 0 false -println(s"${list}\n") +Planet.Earth.surfaceGravity -15 +8 Enum.scala covtest EnumTypes$ Object covtest.EnumTypes$ calculateEarthWeightOnPlanets -1195 -1222 -34 -surfaceGravity -Select +1229 +1320 +35 +foreach +Apply false 0 false -Planet.Earth.surfaceGravity +for p <- Planet.values do\n println(s"Your weight on $p is ${p.surfaceWeight(mass)}") -16 +9 Enum.scala covtest EnumTypes$ @@ -307,24 +188,24 @@ false false Planet.values -17 +10 Enum.scala covtest EnumTypes$ Object covtest.EnumTypes$ $anonfun -1296 -1317 +1263 +1320 36 -surfaceWeight +println Apply false 0 false -p.surfaceWeight(mass) +println(s"Your weight on $p is ${p.surfaceWeight(mass)}") -18 +11 Enum.scala covtest EnumTypes$ @@ -341,42 +222,24 @@ false false s"Your weight on $p is ${p.surfaceWeight(mass)}" -19 +12 Enum.scala covtest EnumTypes$ Object covtest.EnumTypes$ $anonfun -1263 -1320 +1296 +1317 36 -println -Apply -false -0 -false -println(s"Your weight on $p is ${p.surfaceWeight(mass)}") - -20 -Enum.scala -covtest -EnumTypes$ -Object -covtest.EnumTypes$ -calculateEarthWeightOnPlanets -1229 -1320 -35 -foreach +surfaceWeight Apply false 0 false -for p <- Planet.values do - println(s"Your weight on $p is ${p.surfaceWeight(mass)}") +p.surfaceWeight(mass) -21 +13 Enum.scala covtest EnumTypes$ @@ -393,7 +256,7 @@ false false def calculateEarthWeightOnPlanets -22 +14 Enum.scala covtest EnumTypes$ @@ -410,7 +273,7 @@ false false println("Example 2:") -23 +15 Enum.scala covtest EnumTypes$ @@ -427,7 +290,7 @@ false false calculateEarthWeightOnPlanets(80) -24 +16 Enum.scala covtest EnumTypes$ diff --git a/tests/coverage/pos/EnumJava.scala b/tests/coverage/pos/EnumJava.scala new file mode 100644 index 000000000000..3a37cc096685 --- /dev/null +++ b/tests/coverage/pos/EnumJava.scala @@ -0,0 +1,6 @@ +package covtest + +enum MyLogLevel extends java.lang.Enum[MyLogLevel]: + case Warn extends MyLogLevel + case Error extends MyLogLevel + case Fatal extends MyLogLevel diff --git a/tests/coverage/pos/EnumJava.scoverage.check b/tests/coverage/pos/EnumJava.scoverage.check new file mode 100644 index 000000000000..1bdba951d6ae --- /dev/null +++ b/tests/coverage/pos/EnumJava.scoverage.check @@ -0,0 +1,20 @@ +# Coverage data, format version: 3.0 +# Statement data: +# - id +# - source path +# - package name +# - class name +# - class type (Class, Object or Trait) +# - full class name +# - method name +# - start offset +# - end offset +# - line number +# - symbol name +# - tree name +# - is branch +# - invocations count +# - is ignored +# - description (can be multi-line) +# ' ' sign +# ------------------------------------------ diff --git a/tests/coverage/pos/Escaping.scala b/tests/coverage/pos/Escaping.scala new file mode 100644 index 000000000000..bdde94290251 --- /dev/null +++ b/tests/coverage/pos/Escaping.scala @@ -0,0 +1,4 @@ +package covtest.`\n` + +class `\r\n\f`: + def `\r\n\f`(`\\`: String) = `\\`.length diff --git a/tests/coverage/pos/Escaping.scoverage.check b/tests/coverage/pos/Escaping.scoverage.check new file mode 100644 index 000000000000..ecb907a9d222 --- /dev/null +++ b/tests/coverage/pos/Escaping.scoverage.check @@ -0,0 +1,54 @@ +# Coverage data, format version: 3.0 +# Statement data: +# - id +# - source path +# - package name +# - class name +# - class type (Class, Object or Trait) +# - full class name +# - method name +# - start offset +# - end offset +# - line number +# - symbol name +# - tree name +# - is branch +# - invocations count +# - is ignored +# - description (can be multi-line) +# ' ' sign +# ------------------------------------------ +0 +Escaping.scala +covtest.\n +\r\n\f +Class +covtest.\n.\r\n\f +\r\n\f +69 +80 +3 +length +Apply +false +0 +false +`\\\\`.length + +1 +Escaping.scala +covtest.\n +\r\n\f +Class +covtest.\n.\r\n\f +\r\n\f +40 +48 +3 +\r\n\f +DefDef +false +0 +false +def `\\r\\ + diff --git a/tests/coverage/pos/For.scala b/tests/coverage/pos/For.scala new file mode 100644 index 000000000000..21ef5407c60f --- /dev/null +++ b/tests/coverage/pos/For.scala @@ -0,0 +1,14 @@ +package covtest + +def testForLoop: Unit = + for i <- 1 to 10 do + println(i) + +def testForAdvanced: Unit = + def f(x: Int): Boolean = true + for j <- 1 to 10 if f(j) do + println(j) + +def testForeach: Unit = + // An anonymous function is created here, but the user code must still be instrumented! + Nil.foreach(_ => println("user code here")) diff --git a/tests/coverage/pos/For.scoverage.check b/tests/coverage/pos/For.scoverage.check new file mode 100644 index 000000000000..9fdc9a7e9d80 --- /dev/null +++ b/tests/coverage/pos/For.scoverage.check @@ -0,0 +1,309 @@ +# Coverage data, format version: 3.0 +# Statement data: +# - id +# - source path +# - package name +# - class name +# - class type (Class, Object or Trait) +# - full class name +# - method name +# - start offset +# - end offset +# - line number +# - symbol name +# - tree name +# - is branch +# - invocations count +# - is ignored +# - description (can be multi-line) +# ' ' sign +# ------------------------------------------ +0 +For.scala +covtest +For$package$ +Object +covtest.For$package$ +testForLoop +43 +77 +3 +foreach +Apply +false +0 +false +for i <- 1 to 10 do\n println(i) + +1 +For.scala +covtest +For$package$ +Object +covtest.For$package$ +testForLoop +52 +59 +3 +to +Apply +false +0 +false +1 to 10 + +2 +For.scala +covtest +For$package$ +Object +covtest.For$package$ +testForLoop +52 +53 +3 +intWrapper +Apply +false +0 +false +1 + +3 +For.scala +covtest +For$package$ +Object +covtest.For$package$ +$anonfun +67 +77 +4 +println +Apply +false +0 +false +println(i) + +4 +For.scala +covtest +For$package$ +Object +covtest.For$package$ +testForLoop +17 +32 +2 +testForLoop +DefDef +false +0 +false +def testForLoop + +5 +For.scala +covtest +For$package$ +Object +covtest.For$package$ +f +109 +114 +7 +f +DefDef +false +0 +false +def f + +6 +For.scala +covtest +For$package$ +Object +covtest.For$package$ +testForAdvanced +141 +183 +8 +foreach +Apply +false +0 +false +for j <- 1 to 10 if f(j) do\n println(j) + +7 +For.scala +covtest +For$package$ +Object +covtest.For$package$ +testForAdvanced +145 +165 +8 +withFilter +Apply +false +0 +false +j <- 1 to 10 if f(j) + +8 +For.scala +covtest +For$package$ +Object +covtest.For$package$ +testForAdvanced +150 +157 +8 +to +Apply +false +0 +false +1 to 10 + +9 +For.scala +covtest +For$package$ +Object +covtest.For$package$ +testForAdvanced +150 +151 +8 +intWrapper +Apply +false +0 +false +1 + +10 +For.scala +covtest +For$package$ +Object +covtest.For$package$ +$anonfun +161 +165 +8 +f +Apply +false +0 +false +f(j) + +11 +For.scala +covtest +For$package$ +Object +covtest.For$package$ +$anonfun +173 +183 +9 +println +Apply +false +0 +false +println(j) + +12 +For.scala +covtest +For$package$ +Object +covtest.For$package$ +testForAdvanced +79 +98 +6 +testForAdvanced +DefDef +false +0 +false +def testForAdvanced + +13 +For.scala +covtest +For$package$ +Object +covtest.For$package$ +testForeach +301 +344 +13 +foreach +Apply +false +0 +false +Nil.foreach(_ => println("user code here")) + +14 +For.scala +covtest +For$package$ +Object +covtest.For$package$ +testForeach +301 +304 +13 +Nil +Ident +false +0 +false +Nil + +15 +For.scala +covtest +For$package$ +Object +covtest.For$package$ +$anonfun +318 +343 +13 +println +Apply +false +0 +false +println("user code here") + +16 +For.scala +covtest +For$package$ +Object +covtest.For$package$ +testForeach +185 +200 +11 +testForeach +DefDef +false +0 +false +def testForeach + diff --git a/tests/coverage/pos/Givens.scoverage.check b/tests/coverage/pos/Givens.scoverage.check index ac8fcd9e379e..15f8f02c378f 100644 --- a/tests/coverage/pos/Givens.scoverage.check +++ b/tests/coverage/pos/Givens.scoverage.check @@ -178,15 +178,15 @@ Givens Class covtest.Givens test2 -461 -476 +448 +477 22 -getMessage +printContext Apply false 0 false -getMessage(123) +printContext(getMessage(123)) 10 Givens.scala @@ -195,15 +195,15 @@ Givens Class covtest.Givens test2 -448 -477 +461 +476 22 -printContext +getMessage Apply false 0 false -printContext(getMessage(123)) +getMessage(123) 11 Givens.scala diff --git a/tests/coverage/pos/Inlined.scoverage.check b/tests/coverage/pos/Inlined.scoverage.check index 6a4aac8ced8d..85393db11a8f 100644 --- a/tests/coverage/pos/Inlined.scoverage.check +++ b/tests/coverage/pos/Inlined.scoverage.check @@ -45,8 +45,8 @@ testInlined 288 330 10 - -Block +assertFailed +Apply true 0 false @@ -77,6 +77,23 @@ Object covtest.Inlined$package$ testInlined 155 +159 +6 +List +Ident +false +0 +false +List + +4 +Inlined.scala +covtest +Inlined$package$ +Object +covtest.Inlined$package$ +testInlined +155 169 6 length @@ -86,7 +103,7 @@ false false List(l).length -4 +5 Inlined.scala covtest Inlined$package$ @@ -103,7 +120,7 @@ false false scala.runtime.Scala3RunTime.assertFailed() -5 +6 Inlined.scala covtest Inlined$package$ @@ -113,14 +130,14 @@ testInlined 288 330 10 - -Block +assertFailed +Apply true 0 false scala.runtime.Scala3RunTime.assertFailed() -6 +7 Inlined.scala covtest Inlined$package$ @@ -137,7 +154,24 @@ false false List(l) +8 +Inlined.scala +covtest +Inlined$package$ +Object +covtest.Inlined$package$ +testInlined +180 +184 7 +List +Ident +false +0 +false +List + +9 Inlined.scala covtest Inlined$package$ @@ -154,7 +188,7 @@ false false List(l).length -8 +10 Inlined.scala covtest Inlined$package$ @@ -171,7 +205,7 @@ false false scala.runtime.Scala3RunTime.assertFailed() -9 +11 Inlined.scala covtest Inlined$package$ @@ -181,14 +215,14 @@ testInlined 288 330 10 - -Block +assertFailed +Apply true 0 false scala.runtime.Scala3RunTime.assertFailed() -10 +12 Inlined.scala covtest Inlined$package$ diff --git a/tests/coverage/pos/InlinedFromLib.scala b/tests/coverage/pos/InlinedFromLib.scala new file mode 100644 index 000000000000..1b05e11b7558 --- /dev/null +++ b/tests/coverage/pos/InlinedFromLib.scala @@ -0,0 +1,9 @@ +package covtest + +// assert is a `transparent inline` in Predef, +// but its source path should not appear in the coverage report. +def testInlined(): Unit = + val l = 1 + assert(l == 1) + assert(l == List(l).length) + assert(List(l).length == 1) diff --git a/tests/coverage/pos/InlinedFromLib.scoverage.check b/tests/coverage/pos/InlinedFromLib.scoverage.check new file mode 100644 index 000000000000..d7b2a42cd3b3 --- /dev/null +++ b/tests/coverage/pos/InlinedFromLib.scoverage.check @@ -0,0 +1,292 @@ +# Coverage data, format version: 3.0 +# Statement data: +# - id +# - source path +# - package name +# - class name +# - class type (Class, Object or Trait) +# - full class name +# - method name +# - start offset +# - end offset +# - line number +# - symbol name +# - tree name +# - is branch +# - invocations count +# - is ignored +# - description (can be multi-line) +# ' ' sign +# ------------------------------------------ +0 +InlinedFromLib.scala +covtest +InlinedFromLib$package$ +Object +covtest.InlinedFromLib$package$ +testInlined +169 +183 +6 +assertFailed +Apply +false +0 +false +assert(l == 1) + +1 +InlinedFromLib.scala +covtest +InlinedFromLib$package$ +Object +covtest.InlinedFromLib$package$ +testInlined +169 +183 +6 +assertFailed +Apply +true +0 +false +assert(l == 1) + +2 +InlinedFromLib.scala +covtest +InlinedFromLib$package$ +Object +covtest.InlinedFromLib$package$ +testInlined +169 +183 +6 + +Literal +true +0 +false +assert(l == 1) + +3 +InlinedFromLib.scala +covtest +InlinedFromLib$package$ +Object +covtest.InlinedFromLib$package$ +testInlined +198 +205 +7 +apply +Apply +false +0 +false +List(l) + +4 +InlinedFromLib.scala +covtest +InlinedFromLib$package$ +Object +covtest.InlinedFromLib$package$ +testInlined +198 +202 +7 +List +Ident +false +0 +false +List + +5 +InlinedFromLib.scala +covtest +InlinedFromLib$package$ +Object +covtest.InlinedFromLib$package$ +testInlined +198 +212 +7 +length +Select +false +0 +false +List(l).length + +6 +InlinedFromLib.scala +covtest +InlinedFromLib$package$ +Object +covtest.InlinedFromLib$package$ +testInlined +186 +213 +7 +assertFailed +Apply +false +0 +false +assert(l == List(l).length) + +7 +InlinedFromLib.scala +covtest +InlinedFromLib$package$ +Object +covtest.InlinedFromLib$package$ +testInlined +186 +213 +7 +assertFailed +Apply +true +0 +false +assert(l == List(l).length) + +8 +InlinedFromLib.scala +covtest +InlinedFromLib$package$ +Object +covtest.InlinedFromLib$package$ +testInlined +186 +213 +7 + +Literal +true +0 +false +assert(l == List(l).length) + +9 +InlinedFromLib.scala +covtest +InlinedFromLib$package$ +Object +covtest.InlinedFromLib$package$ +testInlined +223 +230 +8 +apply +Apply +false +0 +false +List(l) + +10 +InlinedFromLib.scala +covtest +InlinedFromLib$package$ +Object +covtest.InlinedFromLib$package$ +testInlined +223 +227 +8 +List +Ident +false +0 +false +List + +11 +InlinedFromLib.scala +covtest +InlinedFromLib$package$ +Object +covtest.InlinedFromLib$package$ +testInlined +223 +237 +8 +length +Select +false +0 +false +List(l).length + +12 +InlinedFromLib.scala +covtest +InlinedFromLib$package$ +Object +covtest.InlinedFromLib$package$ +testInlined +216 +243 +8 +assertFailed +Apply +false +0 +false +assert(List(l).length == 1) + +13 +InlinedFromLib.scala +covtest +InlinedFromLib$package$ +Object +covtest.InlinedFromLib$package$ +testInlined +216 +243 +8 +assertFailed +Apply +true +0 +false +assert(List(l).length == 1) + +14 +InlinedFromLib.scala +covtest +InlinedFromLib$package$ +Object +covtest.InlinedFromLib$package$ +testInlined +216 +243 +8 + +Literal +true +0 +false +assert(List(l).length == 1) + +15 +InlinedFromLib.scala +covtest +InlinedFromLib$package$ +Object +covtest.InlinedFromLib$package$ +testInlined +129 +144 +4 +testInlined +DefDef +false +0 +false +def testInlined + diff --git a/tests/coverage/pos/Lift.scala b/tests/coverage/pos/Lift.scala new file mode 100644 index 000000000000..86f8e4e1fe0e --- /dev/null +++ b/tests/coverage/pos/Lift.scala @@ -0,0 +1,8 @@ +package covtest + +class SomeFunctions: + def f(x: Int) = () + def g() = 0 + def c = SomeFunctions() + + def test = c.f(g()) diff --git a/tests/coverage/pos/Lift.scoverage.check b/tests/coverage/pos/Lift.scoverage.check new file mode 100644 index 000000000000..a1c656cbdb67 --- /dev/null +++ b/tests/coverage/pos/Lift.scoverage.check @@ -0,0 +1,156 @@ +# Coverage data, format version: 3.0 +# Statement data: +# - id +# - source path +# - package name +# - class name +# - class type (Class, Object or Trait) +# - full class name +# - method name +# - start offset +# - end offset +# - line number +# - symbol name +# - tree name +# - is branch +# - invocations count +# - is ignored +# - description (can be multi-line) +# ' ' sign +# ------------------------------------------ +0 +Lift.scala +covtest +SomeFunctions +Class +covtest.SomeFunctions +f +40 +45 +3 +f +DefDef +false +0 +false +def f + +1 +Lift.scala +covtest +SomeFunctions +Class +covtest.SomeFunctions +g +61 +66 +4 +g +DefDef +false +0 +false +def g + +2 +Lift.scala +covtest +SomeFunctions +Class +covtest.SomeFunctions +c +83 +98 +5 + +Apply +false +0 +false +SomeFunctions() + +3 +Lift.scala +covtest +SomeFunctions +Class +covtest.SomeFunctions +c +75 +80 +5 +c +DefDef +false +0 +false +def c + +4 +Lift.scala +covtest +SomeFunctions +Class +covtest.SomeFunctions +test +113 +121 +7 +f +Apply +false +0 +false +c.f(g()) + +5 +Lift.scala +covtest +SomeFunctions +Class +covtest.SomeFunctions +test +113 +114 +7 +c +Select +false +0 +false +c + +6 +Lift.scala +covtest +SomeFunctions +Class +covtest.SomeFunctions +test +117 +120 +7 +g +Apply +false +0 +false +g() + +7 +Lift.scala +covtest +SomeFunctions +Class +covtest.SomeFunctions +test +102 +110 +7 +test +DefDef +false +0 +false +def test + diff --git a/tests/coverage/pos/MatchCaseClasses.scoverage.check b/tests/coverage/pos/MatchCaseClasses.scoverage.check index 0e469fc86b7c..5440c2e3098d 100644 --- a/tests/coverage/pos/MatchCaseClasses.scoverage.check +++ b/tests/coverage/pos/MatchCaseClasses.scoverage.check @@ -25,6 +25,23 @@ MatchCaseClasses$ Object covtest.MatchCaseClasses$ f +135 +147 +7 + +Block +false +0 +false +case Pat1(0) + +1 +MatchCaseClasses.scala +covtest +MatchCaseClasses$ +Object +covtest.MatchCaseClasses$ +f 151 163 7 @@ -35,24 +52,24 @@ false false println("a") -1 +2 MatchCaseClasses.scala covtest MatchCaseClasses$ Object covtest.MatchCaseClasses$ f -135 -147 -7 +168 +180 +8 Block false 0 false -case Pat1(0) +case Pat1(_) -2 +3 MatchCaseClasses.scala covtest MatchCaseClasses$ @@ -69,24 +86,24 @@ false false println("b") -3 +4 MatchCaseClasses.scala covtest MatchCaseClasses$ Object covtest.MatchCaseClasses$ f -168 -180 -8 +201 +221 +9 Block false 0 false -case Pat1(_) +case p @ Pat2(1, -1) -4 +5 MatchCaseClasses.scala covtest MatchCaseClasses$ @@ -103,24 +120,24 @@ false false println("c") -5 +6 MatchCaseClasses.scala covtest MatchCaseClasses$ Object covtest.MatchCaseClasses$ f -201 -221 -9 +242 +265 +10 Block false 0 false -case p @ Pat2(1, -1) +case Pat2(_, y: String) -6 +7 MatchCaseClasses.scala covtest MatchCaseClasses$ @@ -137,7 +154,7 @@ false false println(y) -7 +8 MatchCaseClasses.scala covtest MatchCaseClasses$ @@ -154,24 +171,24 @@ false false println("d") -8 +9 MatchCaseClasses.scala covtest MatchCaseClasses$ Object covtest.MatchCaseClasses$ f -242 -265 -10 +309 +321 +13 Block false 0 false -case Pat2(_, y: String) +case p: Pat2 -9 +10 MatchCaseClasses.scala covtest MatchCaseClasses$ @@ -188,24 +205,24 @@ false false println("e") -10 +11 MatchCaseClasses.scala covtest MatchCaseClasses$ Object covtest.MatchCaseClasses$ f -309 -321 -13 +342 +348 +14 Block false 0 false -case p: Pat2 +case _ -11 +12 MatchCaseClasses.scala covtest MatchCaseClasses$ @@ -222,23 +239,6 @@ false false println("other") -12 -MatchCaseClasses.scala -covtest -MatchCaseClasses$ -Object -covtest.MatchCaseClasses$ -f -342 -348 -14 - -Block -false -0 -false -case _ - 13 MatchCaseClasses.scala covtest diff --git a/tests/coverage/pos/PolymorphicExtensions.scala b/tests/coverage/pos/PolymorphicExtensions.scala index a2bafc451606..51c55f424ac9 100644 --- a/tests/coverage/pos/PolymorphicExtensions.scala +++ b/tests/coverage/pos/PolymorphicExtensions.scala @@ -6,6 +6,10 @@ object PolyExt: extension [A](i: Int) def get(x: A): A = x + def tap[U](f: Int => U): Int = ??? "str".foo(0) // ({foo("str")}[type])(0) i.e. Apply(TypeApply( Apply(foo, "str"), type ), List(0)) 123.get(0) // {(get[type])(123)}(0) i.e. Apply(Apply(TypeApply(...), List(123)), List(0)) + + def foo: Int = 42 + def bar: Int = foo.tap(println) diff --git a/tests/coverage/pos/PolymorphicExtensions.scoverage.check b/tests/coverage/pos/PolymorphicExtensions.scoverage.check index e244b529ce0a..495ddf037d3e 100644 --- a/tests/coverage/pos/PolymorphicExtensions.scoverage.check +++ b/tests/coverage/pos/PolymorphicExtensions.scoverage.check @@ -58,16 +58,16 @@ covtest PolyExt$ Object covtest.PolyExt$ - -138 -147 -9 -foo -Apply +tap +170 +173 +8 +??? +Ident false 0 false -"str".foo +??? 3 PolymorphicExtensions.scala @@ -75,27 +75,61 @@ covtest PolyExt$ Object covtest.PolyExt$ +tap +139 +146 +8 +tap +DefDef +false +0 +false +def tap + +4 +PolymorphicExtensions.scala +covtest +PolyExt$ +Object +covtest.PolyExt$ -138 -150 -9 - +177 +189 +10 +foo Apply false 0 false "str".foo(0) -4 +5 PolymorphicExtensions.scala covtest PolyExt$ Object covtest.PolyExt$ -238 -248 +177 +186 10 +foo +Apply +false +0 +false +"str".foo + +6 +PolymorphicExtensions.scala +covtest +PolyExt$ +Object +covtest.PolyExt$ + +277 +287 +11 get Apply false @@ -103,3 +137,105 @@ false false 123.get(0) +7 +PolymorphicExtensions.scala +covtest +PolyExt$ +Object +covtest.PolyExt$ +foo +370 +377 +13 +foo +DefDef +false +0 +false +def foo + +8 +PolymorphicExtensions.scala +covtest +PolyExt$ +Object +covtest.PolyExt$ +bar +405 +421 +14 +tap +Apply +false +0 +false +foo.tap(println) + +9 +PolymorphicExtensions.scala +covtest +PolyExt$ +Object +covtest.PolyExt$ +bar +405 +412 +14 +tap +Apply +false +0 +false +foo.tap + +10 +PolymorphicExtensions.scala +covtest +PolyExt$ +Object +covtest.PolyExt$ +bar +405 +408 +14 +foo +Ident +false +0 +false +foo + +11 +PolymorphicExtensions.scala +covtest +PolyExt$ +Object +covtest.PolyExt$ +$anonfun +413 +420 +14 +println +Apply +false +0 +false +println + +12 +PolymorphicExtensions.scala +covtest +PolyExt$ +Object +covtest.PolyExt$ +bar +390 +397 +14 +bar +DefDef +false +0 +false +def bar + diff --git a/tests/coverage/pos/PolymorphicMethods.scoverage.check b/tests/coverage/pos/PolymorphicMethods.scoverage.check index 77615cc6f0bc..5bcfe254ffe2 100644 --- a/tests/coverage/pos/PolymorphicMethods.scoverage.check +++ b/tests/coverage/pos/PolymorphicMethods.scoverage.check @@ -60,14 +60,14 @@ Object covtest.PolyMeth$ 147 -158 +170 6 - +f Apply false 0 false -C[String]() +C[String]().f("str", 0) 3 PolymorphicMethods.scala @@ -77,14 +77,14 @@ Object covtest.PolyMeth$ 147 -170 +158 6 -f + Apply false 0 false -C[String]().f("str", 0) +C[String]() 4 PolymorphicMethods.scala diff --git a/tests/coverage/pos/Select.scoverage.check b/tests/coverage/pos/Select.scoverage.check index 94b693f0e639..183ba7395de0 100644 --- a/tests/coverage/pos/Select.scoverage.check +++ b/tests/coverage/pos/Select.scoverage.check @@ -75,16 +75,16 @@ covtest B Class covtest.B - -134 -135 -9 - +print +166 +179 +11 +print Apply false 0 false -A +super.print() 4 Select.scala @@ -93,15 +93,15 @@ B Class covtest.B print -166 -179 -11 -print +184 +206 +12 +println Apply false 0 false -super.print() +println(this.instance) 5 Select.scala @@ -127,23 +127,6 @@ B Class covtest.B print -184 -206 -12 -println -Apply -false -0 -false -println(this.instance) - -7 -Select.scala -covtest -B -Class -covtest.B -print 139 157 10 @@ -154,7 +137,7 @@ false false override def print -8 +7 Select.scala covtest Select$package$ @@ -171,7 +154,7 @@ false false A() -9 +8 Select.scala covtest Select$package$ @@ -188,7 +171,7 @@ false false new A -10 +9 Select.scala covtest Select$package$ @@ -196,16 +179,16 @@ Object covtest.Select$package$ test 263 -273 +281 18 -instance -Select +print +Apply false 0 false -a.instance +a.instance.print() -11 +10 Select.scala covtest Select$package$ @@ -213,16 +196,16 @@ Object covtest.Select$package$ test 263 -281 +273 18 -print -Apply +instance +Select false 0 false -a.instance.print() +a.instance -12 +11 Select.scala covtest Select$package$ @@ -239,7 +222,7 @@ false false a.print() -13 +12 Select.scala covtest Select$package$ diff --git a/tests/coverage/pos/SimpleMethods.scala b/tests/coverage/pos/SimpleMethods.scala index 510a86799b32..876a952f63be 100644 --- a/tests/coverage/pos/SimpleMethods.scala +++ b/tests/coverage/pos/SimpleMethods.scala @@ -15,6 +15,9 @@ class C: if false then true else false + def partialCond: Unit = + if false then () + def new1: C = new {} def tryCatch: Unit = diff --git a/tests/coverage/pos/SimpleMethods.scoverage.check b/tests/coverage/pos/SimpleMethods.scoverage.check index f2d9d61a1cd4..dc68258f9a66 100644 --- a/tests/coverage/pos/SimpleMethods.scoverage.check +++ b/tests/coverage/pos/SimpleMethods.scoverage.check @@ -177,10 +177,44 @@ covtest C Class covtest.C -new1 +partialCond +271 +273 +18 + +Literal +true +0 +false +() + +10 +SimpleMethods.scala +covtest +C +Class +covtest.C +partialCond 229 -237 +244 17 +partialCond +DefDef +false +0 +false +def partialCond + +11 +SimpleMethods.scala +covtest +C +Class +covtest.C +new1 +277 +285 +20 new1 DefDef false @@ -188,16 +222,16 @@ false false def new1 -10 +12 SimpleMethods.scala covtest C Class covtest.C tryCatch -282 -284 -20 +330 +332 +23 Literal true @@ -205,16 +239,16 @@ true false () -11 +13 SimpleMethods.scala covtest C Class covtest.C tryCatch -301 -318 -22 +349 +366 +25 Block false @@ -222,16 +256,16 @@ false false case e: Exception -12 +14 SimpleMethods.scala covtest C Class covtest.C tryCatch -253 -265 -19 +301 +313 +22 tryCatch DefDef false diff --git a/tests/coverage/pos/StructuralTypes.scoverage.check b/tests/coverage/pos/StructuralTypes.scoverage.check index 1e9650ce17a3..6108c83b08d6 100644 --- a/tests/coverage/pos/StructuralTypes.scoverage.check +++ b/tests/coverage/pos/StructuralTypes.scoverage.check @@ -24,16 +24,16 @@ covtest Record Class covtest.Record -$anonfun -159 -163 +selectDynamic +148 +172 5 -_1 -Select +find +Apply false 0 false -_._1 +elems.find(_._1 == name) 1 StructuralTypes.scala @@ -41,16 +41,16 @@ covtest Record Class covtest.Record -selectDynamic -148 -172 +$anonfun +159 +163 5 -find -Apply +_1 +Select false 0 false -elems.find(_._1 == name) +_._1 2 StructuralTypes.scala diff --git a/tests/coverage/pos/TypeLambdas.scoverage.check b/tests/coverage/pos/TypeLambdas.scoverage.check index f97d5285cf06..4085c3e41f18 100644 --- a/tests/coverage/pos/TypeLambdas.scoverage.check +++ b/tests/coverage/pos/TypeLambdas.scoverage.check @@ -25,15 +25,15 @@ TypeLambdas$ Object covtest.TypeLambdas$ test -310 -318 +306 +319 13 --> +apply Apply false 0 false -1 -> "1" +Map(1 -> "1") 1 TypeLambdas.scala @@ -43,14 +43,14 @@ Object covtest.TypeLambdas$ test 306 -319 +309 13 -apply -Apply +Map +Ident false 0 false -Map(1 -> "1") +Map 2 TypeLambdas.scala @@ -59,6 +59,23 @@ TypeLambdas$ Object covtest.TypeLambdas$ test +310 +318 +13 +-> +Apply +false +0 +false +1 -> "1" + +3 +TypeLambdas.scala +covtest +TypeLambdas$ +Object +covtest.TypeLambdas$ +test 324 334 14 @@ -69,7 +86,7 @@ false false println(m) -3 +4 TypeLambdas.scala covtest TypeLambdas$ @@ -86,7 +103,7 @@ false false println(tuple) -4 +5 TypeLambdas.scala covtest TypeLambdas$ diff --git a/tests/coverage/run/currying/test.scoverage.check b/tests/coverage/run/currying/test.scoverage.check index d60d2f088a78..591bf44c17fd 100644 --- a/tests/coverage/run/currying/test.scoverage.check +++ b/tests/coverage/run/currying/test.scoverage.check @@ -93,15 +93,15 @@ Test$ Object .Test$ main -285 -296 +277 +297 11 -f1 +println Apply false 0 false -f1(0)(1)(2) +println(f1(0)(1)(2)) 5 currying/test.scala @@ -110,15 +110,15 @@ Test$ Object .Test$ main -277 -297 +285 +296 11 -println +f1 Apply false 0 false -println(f1(0)(1)(2)) +f1(0)(1)(2) 6 currying/test.scala @@ -127,15 +127,15 @@ Test$ Object .Test$ main -310 -312 +302 +322 12 -f2 -Ident +println +Apply false 0 false -f2 +println(f2(0)(1)(2)) 7 currying/test.scala @@ -145,14 +145,14 @@ Object .Test$ main 310 -315 +321 12 apply Apply false 0 false -f2(0) +f2(0)(1)(2) 8 currying/test.scala @@ -179,14 +179,14 @@ Object .Test$ main 310 -321 +315 12 apply Apply false 0 false -f2(0)(1)(2) +f2(0) 10 currying/test.scala @@ -195,15 +195,15 @@ Test$ Object .Test$ main -302 -322 +310 +312 12 -println -Apply +f2 +Ident false 0 false -println(f2(0)(1)(2)) +f2 11 currying/test.scala @@ -212,15 +212,15 @@ Test$ Object .Test$ main -335 -337 +327 +365 13 -g1 -Ident +println +Apply false 0 false -g1 +println(g1(using 0)(using 1)(using 2)) 12 currying/test.scala @@ -246,15 +246,15 @@ Test$ Object .Test$ main -327 -365 -13 +370 +408 +14 println Apply false 0 false -println(g1(using 0)(using 1)(using 2)) +println(g2(using 0)(using 1)(using 2)) 14 currying/test.scala @@ -280,23 +280,6 @@ Test$ Object .Test$ main -370 -408 -14 -println -Apply -false -0 -false -println(g2(using 0)(using 1)(using 2)) - -16 -currying/test.scala - -Test$ -Object -.Test$ -main 235 243 10 diff --git a/tests/coverage/run/erased/test.check b/tests/coverage/run/erased/test.check index 3e287ad0ce91..8a87e0e34c16 100644 --- a/tests/coverage/run/erased/test.check +++ b/tests/coverage/run/erased/test.check @@ -1,3 +1,4 @@ foo(a)(b) +foo(a)(b) identity(idem) -foo(a)(idem) \ No newline at end of file +foo(a)(idem) diff --git a/tests/coverage/run/erased/test.scala b/tests/coverage/run/erased/test.scala index 9419d68f955c..15a067e9ed50 100644 --- a/tests/coverage/run/erased/test.scala +++ b/tests/coverage/run/erased/test.scala @@ -1,5 +1,7 @@ import scala.language.experimental.erasedDefinitions +erased def parameterless: String = "y" + erased def e(x: String): String = "x" def foo(erased a: String)(b: String): String = println(s"foo(a)($b)") @@ -11,5 +13,6 @@ def identity(s: String): String = @main def Test: Unit = + foo(parameterless)("b") foo(e("a"))("b") foo(e("a"))(identity("idem")) diff --git a/tests/coverage/run/erased/test.scoverage.check b/tests/coverage/run/erased/test.scoverage.check index 3cd9ff86c40a..f31c1a2418a9 100644 --- a/tests/coverage/run/erased/test.scoverage.check +++ b/tests/coverage/run/erased/test.scoverage.check @@ -25,15 +25,15 @@ test$package$ Object .test$package$ foo -149 -162 -4 -s +181 +203 +6 +println Apply false 0 false -s"foo(a)($b)" +println(s"foo(a)($b)") 1 erased/test.scala @@ -42,15 +42,15 @@ test$package$ Object .test$package$ foo -141 -163 -4 -println +189 +202 +6 +s Apply false 0 false -println(s"foo(a)($b)") +s"foo(a)($b)" 2 erased/test.scala @@ -59,9 +59,9 @@ test$package$ Object .test$package$ foo -92 -99 -3 +132 +139 +5 foo DefDef false @@ -76,15 +76,15 @@ test$package$ Object .test$package$ identity -213 -228 -8 -s +245 +269 +10 +println Apply false 0 false -s"identity($s)" +println(s"identity($s)") 4 erased/test.scala @@ -93,15 +93,15 @@ test$package$ Object .test$package$ identity -205 -229 -8 -println +253 +268 +10 +s Apply false 0 false -println(s"identity($s)") +s"identity($s)" 5 erased/test.scala @@ -110,9 +110,9 @@ test$package$ Object .test$package$ identity -169 -181 -7 +209 +221 +9 identity DefDef false @@ -127,15 +127,15 @@ test$package$ Object .test$package$ Test -264 -270 -13 -e +300 +323 +15 +foo Apply false 0 false -e("a") +foo(parameterless)("b") 7 erased/test.scala @@ -144,9 +144,9 @@ test$package$ Object .test$package$ Test -260 -276 -13 +326 +342 +16 foo Apply false @@ -161,15 +161,15 @@ test$package$ Object .test$package$ Test -291 -307 -14 -identity +345 +374 +17 +foo Apply false 0 false -identity("idem") +foo(e("a"))(identity("idem")) 9 erased/test.scala @@ -178,15 +178,15 @@ test$package$ Object .test$package$ Test -279 -308 -14 -foo +357 +373 +17 +identity Apply false 0 false -foo(e("a"))(identity("idem")) +identity("idem") 10 erased/test.scala @@ -195,14 +195,13 @@ test$package$ Object .test$package$ Test -235 -249 -12 +275 +289 +14 Test DefDef false 0 false -@main -def Test +@main\ndef Test diff --git a/tests/coverage/run/extend-case-class/test.check b/tests/coverage/run/extend-case-class/test.check new file mode 100644 index 000000000000..aa960ae5a323 --- /dev/null +++ b/tests/coverage/run/extend-case-class/test.check @@ -0,0 +1,2 @@ +1 +6178 \ No newline at end of file diff --git a/tests/coverage/run/extend-case-class/test.scala b/tests/coverage/run/extend-case-class/test.scala new file mode 100644 index 000000000000..be9c666b4f55 --- /dev/null +++ b/tests/coverage/run/extend-case-class/test.scala @@ -0,0 +1,10 @@ +// see issue 15835 +import java.math.MathContext +case class DecimalConf(mathContext: MathContext, scaleLimit: Int, digitsLimit: Int) +object DecimalConf extends DecimalConf(MathContext.UNLIMITED, 6178, 308) + +@main +def Test: Unit = + val c = DecimalConf(MathContext.DECIMAL32, 1, 0) + println(c.scaleLimit) + println(DecimalConf.scaleLimit) diff --git a/tests/coverage/run/extend-case-class/test.scoverage.check b/tests/coverage/run/extend-case-class/test.scoverage.check new file mode 100644 index 000000000000..69da960e4f6a --- /dev/null +++ b/tests/coverage/run/extend-case-class/test.scoverage.check @@ -0,0 +1,71 @@ +# Coverage data, format version: 3.0 +# Statement data: +# - id +# - source path +# - package name +# - class name +# - class type (Class, Object or Trait) +# - full class name +# - method name +# - start offset +# - end offset +# - line number +# - symbol name +# - tree name +# - is branch +# - invocations count +# - is ignored +# - description (can be multi-line) +# ' ' sign +# ------------------------------------------ +0 +extend-case-class/test.scala + +test$package$ +Object +.test$package$ +Test +282 +303 +8 +println +Apply +false +0 +false +println(c.scaleLimit) + +1 +extend-case-class/test.scala + +test$package$ +Object +.test$package$ +Test +306 +337 +9 +println +Apply +false +0 +false +println(DecimalConf.scaleLimit) + +2 +extend-case-class/test.scala + +test$package$ +Object +.test$package$ +Test +206 +220 +6 +Test +DefDef +false +0 +false +@main\ndef Test + diff --git a/tests/coverage/run/inheritance/test.scoverage.check b/tests/coverage/run/inheritance/test.scoverage.check index 5744f4b5eb3b..4b75764fcef2 100644 --- a/tests/coverage/run/inheritance/test.scoverage.check +++ b/tests/coverage/run/inheritance/test.scoverage.check @@ -21,23 +21,6 @@ 0 inheritance/test.scala -B -Class -.B - -56 -63 -1 - -Apply -false -0 -false -A(x, 0) - -1 -inheritance/test.scala - C1 Class .C1 @@ -52,24 +35,7 @@ false false println("block") -2 -inheritance/test.scala - -C1 -Class -.C1 - -81 -105 -2 - -Apply -false -0 -false -B({println("block"); 1}) - -3 +1 inheritance/test.scala C2 @@ -86,24 +52,24 @@ false false A(2,2) -4 +2 inheritance/test.scala -C2 -Class -.C2 - -123 -134 -3 - +test$package$ +Object +.test$package$ +Test +161 +176 +7 +println Apply false 0 false -B(A(2,2).x) +println(C1().x) -5 +3 inheritance/test.scala test$package$ @@ -120,24 +86,24 @@ false false C1() -6 +4 inheritance/test.scala test$package$ Object .test$package$ Test -161 -176 -7 +211 +226 +9 println Apply false 0 false -println(C1().x) +println(C2().x) -7 +5 inheritance/test.scala test$package$ @@ -154,24 +120,7 @@ false false C2() -8 -inheritance/test.scala - -test$package$ -Object -.test$package$ -Test -211 -226 -9 -println -Apply -false -0 -false -println(C2().x) - -9 +6 inheritance/test.scala test$package$ @@ -186,6 +135,5 @@ DefDef false 0 false -@main -def Test +@main\ndef Test diff --git a/tests/coverage/run/inline-def/test.scoverage.check b/tests/coverage/run/inline-def/test.scoverage.check index ec336127385a..784c0a00b62b 100644 --- a/tests/coverage/run/inline-def/test.scoverage.check +++ b/tests/coverage/run/inline-def/test.scoverage.check @@ -21,57 +21,6 @@ 0 inline-def/test.scala -A -Class -.A - -66 -67 -4 - -Apply -false -0 -false -B - -1 -inline-def/test.scala - -A -Class -.A -foo$retainedBody -134 -148 -7 -toString -Apply -false -0 -false -"foo".toString - -2 -inline-def/test.scala - -A -Class -.A -foo$retainedBody -134 -134 -7 -foo$retainedBody -DefDef -false -0 -false - - -3 -inline-def/test.scala - test$package$ Object .test$package$ @@ -86,7 +35,7 @@ false false A() -4 +1 inline-def/test.scala test$package$ @@ -103,7 +52,24 @@ false false println(a.x) -5 +2 +inline-def/test.scala + +test$package$ +Object +.test$package$ +Test +246 +260 +14 +println +Apply +false +0 +false +println(a.foo) + +3 inline-def/test.scala test$package$ @@ -120,24 +86,24 @@ false false "foo".toString -6 +4 inline-def/test.scala test$package$ Object .test$package$ Test -246 -260 -14 +263 +277 +15 println Apply false 0 false -println(a.foo) +println(a.bar) -7 +5 inline-def/test.scala test$package$ @@ -154,24 +120,24 @@ false false "bar".toString -8 +6 inline-def/test.scala test$package$ Object .test$package$ Test -263 -277 -15 +295 +309 +17 println Apply false 0 false -println(a.bar) +println(b.foo) -9 +7 inline-def/test.scala test$package$ @@ -188,24 +154,7 @@ false false b.foo -10 -inline-def/test.scala - -test$package$ -Object -.test$package$ -Test -295 -309 -17 -println -Apply -false -0 -false -println(b.foo) - -11 +8 inline-def/test.scala test$package$ @@ -220,6 +169,5 @@ DefDef false 0 false -@main -def Test +@main\ndef Test diff --git a/tests/coverage/run/interpolation/test.scoverage.check b/tests/coverage/run/interpolation/test.scoverage.check index 1f16d03cc7df..6b38152cdcc1 100644 --- a/tests/coverage/run/interpolation/test.scoverage.check +++ b/tests/coverage/run/interpolation/test.scoverage.check @@ -25,15 +25,15 @@ Test$ Object .Test$ simple -68 -76 +60 +78 3 -length +s Apply false 0 false -b.length +s"$a, ${b.length}" 1 interpolation/test.scala @@ -42,15 +42,15 @@ Test$ Object .Test$ simple -60 -78 +68 +76 3 -s +length Apply false 0 false -s"$a, ${b.length}" +b.length 2 interpolation/test.scala @@ -127,15 +127,15 @@ Test$ Object .Test$ main -229 -244 -10 -zipWithIndex -Select +195 +199 +9 +List +Ident false 0 false -xs.zipWithIndex +List 7 interpolation/test.scala @@ -143,16 +143,16 @@ interpolation/test.scala Test$ Object .Test$ -$anonfun -267 -276 +main +229 +278 10 -s +map Apply false 0 false -s"$i: $s" +xs.zipWithIndex.map((s, i) => println(s"$i: $s")) 8 interpolation/test.scala @@ -160,16 +160,16 @@ interpolation/test.scala Test$ Object .Test$ -$anonfun -259 -277 +main +229 +244 10 -println -Apply +zipWithIndex +Select false 0 false -println(s"$i: $s") +xs.zipWithIndex 9 interpolation/test.scala @@ -177,16 +177,16 @@ interpolation/test.scala Test$ Object .Test$ -main -229 -278 +$anonfun +259 +277 10 -map +println Apply false 0 false -xs.zipWithIndex.map((s, i) => println(s"$i: $s")) +println(s"$i: $s") 10 interpolation/test.scala @@ -194,16 +194,16 @@ interpolation/test.scala Test$ Object .Test$ -main -292 -308 -12 -simple +$anonfun +267 +276 +10 +s Apply false 0 false -simple(1, "abc") +s"$i: $s" 11 interpolation/test.scala @@ -229,15 +229,15 @@ Test$ Object .Test$ main -322 -331 -13 -hexa +292 +308 +12 +simple Apply false 0 false -hexa(127) +simple(1, "abc") 13 interpolation/test.scala @@ -263,15 +263,15 @@ Test$ Object .Test$ main -345 -354 -14 -raw +322 +331 +13 +hexa Apply false 0 false -raw"a\nb" +hexa(127) 15 interpolation/test.scala @@ -288,7 +288,7 @@ Apply false 0 false -println(raw"a\nb") +println(raw"a\\nb") 16 interpolation/test.scala @@ -297,6 +297,23 @@ Test$ Object .Test$ main +345 +354 +14 +raw +Apply +false +0 +false +raw"a\\nb" + +17 +interpolation/test.scala + +Test$ +Object +.Test$ +main 130 138 8 diff --git a/tests/coverage/run/java-methods/test.scoverage.check b/tests/coverage/run/java-methods/test.scoverage.check index c1038d4a4dad..7d3752c8db20 100644 --- a/tests/coverage/run/java-methods/test.scoverage.check +++ b/tests/coverage/run/java-methods/test.scoverage.check @@ -93,15 +93,15 @@ test$package$ Object .test$package$ Test -173 -193 +165 +194 8 -identity +println Apply false 0 false -obj.identity[Int](0) +println(obj.identity[Int](0)) 5 java-methods/test.scala @@ -110,15 +110,15 @@ test$package$ Object .test$package$ Test -165 -194 +173 +193 8 -println +identity Apply false 0 false -println(obj.identity[Int](0)) +obj.identity[Int](0) 6 java-methods/test.scala @@ -152,6 +152,5 @@ DefDef false 0 false -@main -def Test +@main\ndef Test diff --git a/tests/coverage/run/lifting-bool/test.scoverage.check b/tests/coverage/run/lifting-bool/test.scoverage.check index 93321474a6a7..9d2a3d0f0162 100644 --- a/tests/coverage/run/lifting-bool/test.scoverage.check +++ b/tests/coverage/run/lifting-bool/test.scoverage.check @@ -161,15 +161,15 @@ test$package$ Object .test$package$ Test -349 -366 +341 +367 12 -s +println Apply false 0 false -s"$a $b $c $d $e" +println(s"$a $b $c $d $e") 9 lifting-bool/test.scala @@ -178,15 +178,15 @@ test$package$ Object .test$package$ Test -341 -367 +349 +366 12 -println +s Apply false 0 false -println(s"$a $b $c $d $e") +s"$a $b $c $d $e" 10 lifting-bool/test.scala @@ -229,15 +229,15 @@ test$package$ Object .test$package$ Test -432 -443 +422 +466 17 -notCalled +f Apply false 0 false -notCalled() +f(true || notCalled(), false && notCalled()) 13 lifting-bool/test.scala @@ -246,8 +246,8 @@ test$package$ Object .test$package$ Test -454 -465 +432 +443 17 notCalled Apply @@ -263,15 +263,15 @@ test$package$ Object .test$package$ Test -422 -466 +454 +465 17 -f +notCalled Apply false 0 false -f(true || notCalled(), false && notCalled()) +notCalled() 15 lifting-bool/test.scala @@ -305,6 +305,5 @@ DefDef false 0 false -@main -def Test +@main\ndef Test diff --git a/tests/coverage/run/lifting/test.scoverage.check b/tests/coverage/run/lifting/test.scoverage.check index e8b470202d40..536c5ab0cf1b 100644 --- a/tests/coverage/run/lifting/test.scoverage.check +++ b/tests/coverage/run/lifting/test.scoverage.check @@ -42,15 +42,15 @@ Vals Class .Vals -46 -57 -2 -apply -Apply +22 +26 +1 +List +Ident false 0 false -List(1,2,3) +List 2 lifting/test.scala @@ -72,21 +72,55 @@ l :: List(1,2,3) 3 lifting/test.scala +Vals +Class +.Vals + +46 +57 +2 +apply +Apply +false +0 +false +List(1,2,3) + +4 +lifting/test.scala + +Vals +Class +.Vals + +46 +50 +2 +List +Ident +false +0 +false +List + +5 +lifting/test.scala + A Class .A msg 104 -116 +136 5 + Apply false 0 false -"string" + a +"string" + a + "." + b + "." + c -4 +6 lifting/test.scala A @@ -94,16 +128,16 @@ Class .A msg 104 -122 +132 5 + Apply false 0 false -"string" + a + "." +"string" + a + "." + b + "." -5 +7 lifting/test.scala A @@ -120,7 +154,7 @@ false false "string" + a + "." + b -6 +8 lifting/test.scala A @@ -128,16 +162,16 @@ Class .A msg 104 -132 +122 5 + Apply false 0 false -"string" + a + "." + b + "." +"string" + a + "." -7 +9 lifting/test.scala A @@ -145,16 +179,16 @@ Class .A msg 104 -136 +116 5 + Apply false 0 false -"string" + a + "." + b + "." + c +"string" + a -8 +10 lifting/test.scala A @@ -171,7 +205,7 @@ false false def msg -9 +11 lifting/test.scala A @@ -188,7 +222,7 @@ false false def integer -10 +12 lifting/test.scala A @@ -205,7 +239,7 @@ false false def ex -11 +13 lifting/test.scala test$package$ @@ -222,7 +256,7 @@ false false A() -12 +14 lifting/test.scala test$package$ @@ -239,41 +273,41 @@ false false def f -13 +15 lifting/test.scala test$package$ Object .test$package$ Test -276 -285 +264 +286 14 -integer -Select +msg +Apply false 0 false -a.integer +a.msg(i, 0, a.integer) -14 +16 lifting/test.scala test$package$ Object .test$package$ Test -264 -286 +276 +285 14 -msg -Apply +integer +Select false 0 false -a.msg(i, 0, a.integer) +a.integer -15 +17 lifting/test.scala test$package$ @@ -290,7 +324,7 @@ false false println(x) -16 +18 lifting/test.scala test$package$ @@ -298,24 +332,24 @@ Object .test$package$ Test 306 -310 +334 16 -ex -Select +msg +Apply false 0 false -a.ex +a.ex.msg(i, 0, a.ex.integer) -17 +19 lifting/test.scala test$package$ Object .test$package$ Test -321 -325 +306 +310 16 ex Select @@ -324,7 +358,7 @@ false false a.ex -18 +20 lifting/test.scala test$package$ @@ -332,33 +366,33 @@ Object .test$package$ Test 321 -333 +325 16 -integer +ex Select false 0 false -a.ex.integer +a.ex -19 +21 lifting/test.scala test$package$ Object .test$package$ Test -306 -334 +321 +333 16 -msg -Apply +integer +Select false 0 false -a.ex.msg(i, 0, a.ex.integer) +a.ex.integer -20 +22 lifting/test.scala test$package$ @@ -375,41 +409,41 @@ false false println(x) -21 +23 lifting/test.scala test$package$ Object .test$package$ Test -360 -363 +354 +370 18 -f +msg Apply false 0 false -f() +a.msg(f(), 0, i) -22 +24 lifting/test.scala test$package$ Object .test$package$ Test -354 -370 +360 +363 18 -msg +f Apply false 0 false -a.msg(f(), 0, i) +f() -23 +25 lifting/test.scala test$package$ @@ -426,7 +460,7 @@ false false println(x) -24 +26 lifting/test.scala test$package$ @@ -441,6 +475,5 @@ DefDef false 0 false -@main -def Test +@main\ndef Test diff --git a/tests/coverage/run/parameterless/test.scoverage.check b/tests/coverage/run/parameterless/test.scoverage.check index dae3f6775e60..91a9b1d6597f 100644 --- a/tests/coverage/run/parameterless/test.scoverage.check +++ b/tests/coverage/run/parameterless/test.scoverage.check @@ -195,6 +195,23 @@ test$package$ Object .test$package$ Test +265 +275 +21 +println +Apply +false +0 +false +println(f) + +11 +parameterless/test.scala + +test$package$ +Object +.test$package$ +Test 273 274 21 @@ -205,24 +222,24 @@ false false f -11 +12 parameterless/test.scala test$package$ Object .test$package$ Test -265 -275 -21 +278 +288 +22 println Apply false 0 false -println(f) +println(g) -12 +13 parameterless/test.scala test$package$ @@ -239,24 +256,24 @@ false false g -13 +14 parameterless/test.scala test$package$ Object .test$package$ Test -278 -288 -22 +291 +303 +23 println Apply false 0 false -println(g) +println(O.f) -14 +15 parameterless/test.scala test$package$ @@ -273,24 +290,24 @@ false false O.f -15 +16 parameterless/test.scala test$package$ Object .test$package$ Test -291 -303 -23 +306 +318 +24 println Apply false 0 false -println(O.f) +println(O.g) -16 +17 parameterless/test.scala test$package$ @@ -307,23 +324,6 @@ false false O.g -17 -parameterless/test.scala - -test$package$ -Object -.test$package$ -Test -306 -318 -24 -println -Apply -false -0 -false -println(O.g) - 18 parameterless/test.scala @@ -339,6 +339,5 @@ DefDef false 0 false -@main -def Test +@main\ndef Test diff --git a/tests/coverage/run/trait/test.scoverage.check b/tests/coverage/run/trait/test.scoverage.check index d48e14eacf08..8dbf64238cfa 100644 --- a/tests/coverage/run/trait/test.scoverage.check +++ b/tests/coverage/run/trait/test.scoverage.check @@ -38,23 +38,6 @@ def x 1 trait/test.scala -Impl2 -Class -.Impl2 - -91 -101 -6 - -Apply -false -0 -false -T2("test") - -2 -trait/test.scala - Impl3 Class .Impl3 @@ -69,24 +52,24 @@ false false Impl2() -3 +2 trait/test.scala -Impl3 -Class -.Impl3 - -130 -143 -7 - +test$package$ +Object +.test$package$ +Test +170 +188 +11 +println Apply false 0 false -T2(Impl2().p) +println(Impl1().x) -4 +3 trait/test.scala test$package$ @@ -103,7 +86,7 @@ false false Impl1() -5 +4 trait/test.scala test$package$ @@ -120,24 +103,24 @@ false false Impl1().x -6 +5 trait/test.scala test$package$ Object .test$package$ Test -170 -188 -11 +196 +214 +12 println Apply false 0 false -println(Impl1().x) +println(Impl2().p) -7 +6 trait/test.scala test$package$ @@ -154,24 +137,24 @@ false false Impl2() -8 +7 trait/test.scala test$package$ Object .test$package$ Test -196 -214 -12 +225 +243 +13 println Apply false 0 false -println(Impl2().p) +println(Impl3().p) -9 +8 trait/test.scala test$package$ @@ -188,24 +171,7 @@ false false Impl3() -10 -trait/test.scala - -test$package$ -Object -.test$package$ -Test -225 -243 -13 -println -Apply -false -0 -false -println(Impl3().p) - -11 +9 trait/test.scala test$package$ @@ -220,6 +186,5 @@ DefDef false 0 false -@main -def Test +@main\ndef Test diff --git a/tests/coverage/run/varargs/test_1.scoverage.check b/tests/coverage/run/varargs/test_1.scoverage.check index 3a242f7a97a4..2c4edea68fcc 100644 --- a/tests/coverage/run/varargs/test_1.scoverage.check +++ b/tests/coverage/run/varargs/test_1.scoverage.check @@ -76,15 +76,15 @@ test_1$package$ Object .test_1$package$ Test -142 -147 +133 +153 10 -f +repeated Apply false 0 false -f("") +repeated(f(""), "b") 4 varargs/test_1.scala @@ -93,15 +93,15 @@ test_1$package$ Object .test_1$package$ Test -133 -153 +142 +147 10 -repeated +f Apply false 0 false -repeated(f(""), "b") +f("") 5 varargs/test_1.scala @@ -178,15 +178,15 @@ test_1$package$ Object .test_1$package$ Test -291 -301 +268 +302 16 -f +multiple Apply false 0 false -f("first") +JavaVarargs_1.multiple(f("first")) 10 varargs/test_1.scala @@ -195,15 +195,15 @@ test_1$package$ Object .test_1$package$ Test -268 -302 +291 +301 16 -multiple +f Apply false 0 false -JavaVarargs_1.multiple(f("first")) +f("first") 11 varargs/test_1.scala @@ -229,15 +229,15 @@ test_1$package$ Object .test_1$package$ Test -345 -355 +322 +371 18 -f +multiple Apply false 0 false -f("first") +JavaVarargs_1.multiple(f("first"), "a", "b", "c") 13 varargs/test_1.scala @@ -246,15 +246,15 @@ test_1$package$ Object .test_1$package$ Test -322 -371 +345 +355 18 -multiple +f Apply false 0 false -JavaVarargs_1.multiple(f("first"), "a", "b", "c") +f("first") 14 varargs/test_1.scala @@ -288,6 +288,5 @@ DefDef false 0 false -@main -def Test +@main\ndef Test