bugfix: scoverage does not instrument pat-mat assignment properly #731
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Why
As mentioned in this issue, scoverage doesn't instrument its measure statement(s) into the RHS of pattern-matching assignment. This causes the coverage report to not include any of the user code inside that RHS and make the coverage score differs from the reality.
The root cause of this issue is due to the following match-case in
ScoveragePlugin.scala:Scala compiler compiles the pattern-matching assignment into the synthetic ValDef, so the above match-case causes scoverage to completely ignore that tree. For example:
User code
Compiled code
When scoverage encounters the
val x1 = ..., it completely ignore this and doesn't instrumentif (c) 1 -> 1 else 2 -> 2.What
This PR fixes this by adding an additional match-case specifically to handle this case:
In the example,
val x1 = ...will fall into this case since it's a synthetic code whose RHS contains some user code. With this fix, scoverage will now considerif (c) 1 -> 1 else 2 -> 2and include them in the coverage report.Note
For the above example, this fix also unintentionally introduce another 2 measure statements inside the
case scala.Tuple2((a @ _), (b @ _)) => scala.Tuple2(a, b).IMO, This is also a synthetic code and should not be included in the coverage report. However, I don't enough confidence to exclude this out since it might accidentally exclude some valid codes out of the report. And since the consequence of having this additional measure statements is just the dilution of the %coverage with 2 always-hit/always-miss statements. It's fine to just ignore them.