diff --git a/plugin/src/main/scala/scoverage/ScoveragePlugin.scala b/plugin/src/main/scala/scoverage/ScoveragePlugin.scala index ca3064f1..bedc079d 100644 --- a/plugin/src/main/scala/scoverage/ScoveragePlugin.scala +++ b/plugin/src/main/scala/scoverage/ScoveragePlugin.scala @@ -842,6 +842,23 @@ class ScoverageInstrumentationComponent( */ case v: ValDef if v.symbol.isLazy => tree + /** Pattern matching assignment instrumentation (see https://github.com/scoverage/scalac-scoverage-plugin/issues/123) + * + * User code: val (a, b) = { if (c) 1 -> 1 else 2 -> 2 } + * + * After typer, this desugars to: + * val x$1 = (if (c) 1 -> 1 else 2 -> 2) match { case (a, b) => Tuple2(a, b) } + * val a = x$1._1 + * val b = x$1._2 + * + * This will instrument the user expression (if-else with arrow calls). + */ + case v: ValDef + if v.symbol.isSynthetic && v.rhs.pos.isDefined && containsNonSynthetic( + v.rhs + ) => + treeCopy.ValDef(tree, v.mods, v.name, v.tpt, process(v.rhs)) + /** val default: A1 => B1 = * val x1: Any = _ */ diff --git a/plugin/src/test/scala/scoverage/PluginCoverageTest.scala b/plugin/src/test/scala/scoverage/PluginCoverageTest.scala index 15a85146..eab838f4 100644 --- a/plugin/src/test/scala/scoverage/PluginCoverageTest.scala +++ b/plugin/src/test/scala/scoverage/PluginCoverageTest.scala @@ -380,4 +380,34 @@ class PluginCoverageTest extends FunSuite with MacroSupport { assert(!compiler.reporter.hasWarnings) compiler.assertNMeasuredStatements(11) } + + test( + "plugin should handle return pattern matching assignment https://github.com/scoverage/scalac-scoverage-plugin/issues/123" + ) { + val compiler = ScoverageCompiler.default + compiler.compileCodeSnippet( + """ + |object TestObject { + | def test(c: Boolean): Unit = { + | val (a, b) = { + | if (c) 1 -> 1 else 2 -> 2 + | } + | } + |} + """.stripMargin + ) + assert(!compiler.reporter.hasErrors) + assert(!compiler.reporter.hasWarnings) + + /** WITHOUT the bugfix: + * 2 when assigning value to "a" and "b" + * 1 at the end of the function + * WITH the bugfix, it will additionally include + * 2 from then branch + * 2 from else branch + * 2 from synthetic code generated for pattern matching assignment + */ + compiler.assertNMeasuredStatements(9) + } + }