Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Additional coverage reporting for properties and nested types #68

Merged
merged 7 commits into from May 1, 2018
Merged

Additional coverage reporting for properties and nested types #68

merged 7 commits into from May 1, 2018

Conversation

sjp
Copy link
Contributor

@sjp sjp commented Apr 30, 2018

This should fix #7 and #39.

Nested types were not being covered, which is probably why some LINQ code and anonymous types were not being marked as covered.

In addition to this I've also modified ExcludeFromCodeCoverageAttribute so that it can be applied to properties.

There have also been some other minor refactorings:

  • Inline functions to local functions.
  • Extract method for obtaining backup module path.
  • Avoid hard-coding coverlet assembly name.
  • Place the RetryHelper into an explicit namespace

Finally, I've improved performance by caching some reflection that retrieves CoverageTracker.MarkExecuted(). This should be a one-off operation instead of (potentially) once per sequence point.

sjp added 3 commits April 30, 2018 19:41
Minor refactorings elsewhere:
* Inline functions to local functions.
* Extract method for obtaining backup module path.
* Avoid hard-coding coverlet assembly name.
@hunterjm
Copy link
Contributor

hunterjm commented May 1, 2018

@sjp - Looks like one of us is going to have some merge fun depending on if this or #69 gets merged first. Cool stuff though! Hopefully between the two of these we'll see some better coverage.

@sjp
Copy link
Contributor Author

sjp commented May 1, 2018

@hunterjm Yeah that's true. I'm fine with merging as your changes look to be good improvements too.

@tonerdo
Copy link
Collaborator

tonerdo commented May 1, 2018

@hunterjm you're gonna have a lot of merge fun then 😛. This PR seems straightforward enough, need to review yours over coffee

@hunterjm
Copy link
Contributor

hunterjm commented May 1, 2018

That's fine @tonerdo, I'll keep an eye on this PR and when it get's merged I'll update mine.

@@ -95,7 +133,7 @@ private void InstrumentIL(MethodDefinition method)
{
var instruction = processor.Body.Instructions[index];
var sequencePoint = method.DebugInformation.GetSequencePoint(instruction);
if (sequencePoint == null || sequencePoint.StartLine == 16707566)
if (sequencePoint == null || sequencePoint.StartLine == HiddenSequencePoint)
Copy link
Contributor

@hunterjm hunterjm May 1, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would just use !sequencePoint.IsHidden instead of checking line numbers. Cecil already provides this info for us (and it basically does just that).

InstrumentMethod(method);
}

foreach (var property in type.Properties)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The C# compiler generates methods for properties. Those methods are returned as part of type.Methods, no need to explicitly instrument properties

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. You're right. I've removed enumeration of property methods.


// Restore the original module - retry up to 10 times, since the destination file could be locked
// See: https://github.com/tonerdo/coverlet/issues/25
var currentSleep = 6;
Func<TimeSpan> retryStrategy = () => {
TimeSpan retryStrategy()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the retry strategy is the same in InstrumentationHelper.cs, we can just create a single method and use that everywhere

if (type.HasNestedTypes)
{
foreach (var nestedType in type.NestedTypes)
InstrumentType(nestedType);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you confirm that this actually fixes the specified issues. It was my thinking that Cecil returned every type regardless of whether they were nested or not

Copy link
Contributor

@hunterjm hunterjm May 1, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Works for me. @sjp feel free to ignore this comment

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure. I've just changed the logic slightly to use module.Types instead of module.GetTypes() so that this logic for nested types can be retained without processing nested types more than once.

Copy link
Contributor

@hunterjm hunterjm May 1, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sjp - Actually, I think @tonerdo is correct. GetTypes() from Mono.Cecil already handles nested types. He was also correct that Properties were created as methods as seen in the attached screenshot (all that went up was hit count when properties were added).

I actually would kind of prefer letting Cecil handle type nesting.

slack - red ventures 2018-05-01 16-10-30

if (type.HasNestedTypes)
{
foreach (var nestedType in type.NestedTypes)
InstrumentType(nestedType);
Copy link
Contributor

@hunterjm hunterjm May 1, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sjp - Actually, I think @tonerdo is correct. GetTypes() from Mono.Cecil already handles nested types. He was also correct that Properties were created as methods as seen in the attached screenshot (all that went up was hit count when properties were added).

I actually would kind of prefer letting Cecil handle type nesting.

slack - red ventures 2018-05-01 16-10-30

@tonerdo tonerdo merged commit 9435f73 into coverlet-coverage:master May 1, 2018
NorekZ pushed a commit to NorekZ/coverlet that referenced this pull request Nov 8, 2018
Additional coverage reporting for properties and nested types
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Incorrect coverage reporting 🐛
3 participants