Skip to content

Commit 4974550

Browse files
authored
Change CecilSymbolHelper to instance class (#846)
Change CecilSymbolHelper to instance class
1 parent 8cf2b3c commit 4974550

File tree

16 files changed

+102
-67
lines changed

16 files changed

+102
-67
lines changed

src/coverlet.collector/DataCollection/CoverageManager.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ internal class CoverageManager
2323
public IReporter[] Reporters { get; }
2424

2525
public CoverageManager(CoverletSettings settings, TestPlatformEqtTrace eqtTrace, TestPlatformLogger logger, ICoverageWrapper coverageWrapper,
26-
IInstrumentationHelper instrumentationHelper, IFileSystem fileSystem, ISourceRootTranslator sourceRootTranslator)
26+
IInstrumentationHelper instrumentationHelper, IFileSystem fileSystem, ISourceRootTranslator sourceRootTranslator, ICecilSymbolHelper cecilSymbolHelper)
2727
: this(settings,
2828
settings.ReportFormats.Select(format =>
2929
{
@@ -39,19 +39,19 @@ public CoverageManager(CoverletSettings settings, TestPlatformEqtTrace eqtTrace,
3939
}
4040
}).Where(r => r != null).ToArray(),
4141
new CoverletLogger(eqtTrace, logger),
42-
coverageWrapper, instrumentationHelper, fileSystem, sourceRootTranslator)
42+
coverageWrapper, instrumentationHelper, fileSystem, sourceRootTranslator, cecilSymbolHelper)
4343
{
4444
}
4545

4646
public CoverageManager(CoverletSettings settings, IReporter[] reporters, ILogger logger, ICoverageWrapper coverageWrapper,
47-
IInstrumentationHelper instrumentationHelper, IFileSystem fileSystem, ISourceRootTranslator sourceRootTranslator)
47+
IInstrumentationHelper instrumentationHelper, IFileSystem fileSystem, ISourceRootTranslator sourceRootTranslator, ICecilSymbolHelper cecilSymbolHelper)
4848
{
4949
// Store input vars
5050
Reporters = reporters;
5151
_coverageWrapper = coverageWrapper;
5252

5353
// Coverage object
54-
_coverage = _coverageWrapper.CreateCoverage(settings, logger, instrumentationHelper, fileSystem, sourceRootTranslator);
54+
_coverage = _coverageWrapper.CreateCoverage(settings, logger, instrumentationHelper, fileSystem, sourceRootTranslator, cecilSymbolHelper);
5555
}
5656

5757
/// <summary>

src/coverlet.collector/DataCollection/CoverageWrapper.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ internal class CoverageWrapper : ICoverageWrapper
1515
/// <param name="settings">Coverlet settings</param>
1616
/// <param name="coverletLogger">Coverlet logger</param>
1717
/// <returns>Coverage object</returns>
18-
public Coverage CreateCoverage(CoverletSettings settings, ILogger coverletLogger, IInstrumentationHelper instrumentationHelper, IFileSystem fileSystem, ISourceRootTranslator sourceRootTranslator)
18+
public Coverage CreateCoverage(CoverletSettings settings, ILogger coverletLogger, IInstrumentationHelper instrumentationHelper, IFileSystem fileSystem, ISourceRootTranslator sourceRootTranslator, ICecilSymbolHelper cecilSymbolHelper)
1919
{
2020
return new Coverage(
2121
settings.TestModule,
@@ -31,7 +31,8 @@ public Coverage CreateCoverage(CoverletSettings settings, ILogger coverletLogger
3131
coverletLogger,
3232
instrumentationHelper,
3333
fileSystem,
34-
sourceRootTranslator);
34+
sourceRootTranslator,
35+
cecilSymbolHelper);
3536
}
3637

3738
/// <summary>

src/coverlet.collector/DataCollection/CoverletCoverageCollector.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using Coverlet.Collector.Utilities.Interfaces;
88
using Coverlet.Core.Abstractions;
99
using Coverlet.Core.Helpers;
10+
using Coverlet.Core.Symbols;
1011
using Microsoft.Extensions.DependencyInjection;
1112
using Microsoft.VisualStudio.TestPlatform.ObjectModel.DataCollection;
1213

@@ -133,7 +134,7 @@ private void OnSessionStart(object sender, SessionStartEventArgs sessionStartEve
133134
// Get coverage and attachment managers
134135
_coverageManager = new CoverageManager(coverletSettings, _eqtTrace, _logger, _coverageWrapper,
135136
_serviceProvider.GetRequiredService<IInstrumentationHelper>(), _serviceProvider.GetRequiredService<IFileSystem>(),
136-
_serviceProvider.GetRequiredService<ISourceRootTranslator>());
137+
_serviceProvider.GetRequiredService<ISourceRootTranslator>(), _serviceProvider.GetRequiredService<ICecilSymbolHelper>());
137138

138139
// Instrument modules
139140
_coverageManager.InstrumentModules();
@@ -227,6 +228,7 @@ private static IServiceCollection GetDefaultServiceCollection(TestPlatformEqtTra
227228
serviceCollection.AddSingleton<IInstrumentationHelper, InstrumentationHelper>();
228229
// We cache resolutions
229230
serviceCollection.AddSingleton<ISourceRootTranslator, SourceRootTranslator>(serviceProvider => new SourceRootTranslator(testModule, serviceProvider.GetRequiredService<ILogger>(), serviceProvider.GetRequiredService<IFileSystem>()));
231+
serviceCollection.AddSingleton<ICecilSymbolHelper, CecilSymbolHelper>();
230232
return serviceCollection;
231233
}
232234
}

src/coverlet.collector/Utilities/Interfaces/ICoverageWrapper.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,13 @@ internal interface ICoverageWrapper
1414
/// Creates a coverage object from given coverlet settings
1515
/// </summary>
1616
/// <param name="settings">Coverlet settings</param>
17-
/// <param name="coverletLogger">Coverlet logger</param>
17+
/// <param name="logger">Coverlet logger</param>
1818
/// <param name="instrumentationHelper">Coverlet instrumentationHelper</param>
1919
/// <param name="fileSystem">Coverlet fileSystem</param>
2020
/// <param name="sourceRootTranslator">Coverlet sourceRootTranslator</param>
21+
/// <param name="cecilSymbolHelper"></param>
2122
/// <returns>Coverage object</returns>
22-
Coverage CreateCoverage(CoverletSettings settings, ILogger logger, IInstrumentationHelper instrumentationHelper, IFileSystem fileSystem, ISourceRootTranslator sourceRootTranslator);
23+
Coverage CreateCoverage(CoverletSettings settings, ILogger logger, IInstrumentationHelper instrumentationHelper, IFileSystem fileSystem, ISourceRootTranslator sourceRootTranslator, ICecilSymbolHelper cecilSymbolHelper);
2324

2425
/// <summary>
2526
/// Gets the coverage result from provided coverage object

src/coverlet.console/Program.cs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
using Coverlet.Core.Enums;
1313
using Coverlet.Core.Helpers;
1414
using Coverlet.Core.Reporters;
15+
using Coverlet.Core.Symbols;
1516
using McMaster.Extensions.CommandLineUtils;
1617
using Microsoft.Extensions.DependencyInjection;
1718

@@ -29,12 +30,12 @@ static int Main(string[] args)
2930
// We need to keep singleton/static semantics
3031
serviceCollection.AddSingleton<IInstrumentationHelper, InstrumentationHelper>();
3132
serviceCollection.AddSingleton<ISourceRootTranslator, SourceRootTranslator>(provider => new SourceRootTranslator(provider.GetRequiredService<ILogger>(), provider.GetRequiredService<IFileSystem>()));
33+
serviceCollection.AddSingleton<ICecilSymbolHelper, CecilSymbolHelper>();
3234

3335
ServiceProvider serviceProvider = serviceCollection.BuildServiceProvider();
3436

3537
var logger = (ConsoleLogger) serviceProvider.GetService<ILogger>();
3638
var fileSystem = serviceProvider.GetService<IFileSystem>();
37-
var sourceTranslator = serviceProvider.GetService<ISourceRootTranslator>();
3839

3940
var app = new CommandLineApplication();
4041
app.Name = "coverlet";
@@ -86,9 +87,10 @@ static int Main(string[] args)
8687
mergeWith.Value(),
8788
useSourceLink.HasValue(),
8889
logger,
89-
serviceProvider.GetService<IInstrumentationHelper>(),
90+
serviceProvider.GetRequiredService<IInstrumentationHelper>(),
9091
fileSystem,
91-
sourceTranslator);
92+
serviceProvider.GetRequiredService<ISourceRootTranslator>(),
93+
serviceProvider.GetRequiredService<ICecilSymbolHelper>());
9294
coverage.PrepareModules();
9395

9496
Process process = new Process();
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
using System.Collections.Generic;
2+
using Coverlet.Core.Symbols;
3+
using Mono.Cecil;
4+
using Mono.Cecil.Cil;
5+
6+
namespace Coverlet.Core.Abstractions
7+
{
8+
internal interface ICecilSymbolHelper
9+
{
10+
IReadOnlyList<BranchPoint> GetBranchPoints(MethodDefinition methodDefinition);
11+
bool SkipNotCoverableInstruction(MethodDefinition methodDefinition, Instruction instruction);
12+
}
13+
}

src/coverlet.core/Coverage.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ internal class Coverage
2727
private IInstrumentationHelper _instrumentationHelper;
2828
private IFileSystem _fileSystem;
2929
private ISourceRootTranslator _sourceRootTranslator;
30+
private ICecilSymbolHelper _cecilSymbolHelper;
3031
private List<InstrumenterResult> _results;
3132

3233
public string Identifier
@@ -47,7 +48,8 @@ public Coverage(string module,
4748
ILogger logger,
4849
IInstrumentationHelper instrumentationHelper,
4950
IFileSystem fileSystem,
50-
ISourceRootTranslator sourceRootTranslator)
51+
ISourceRootTranslator sourceRootTranslator,
52+
ICecilSymbolHelper cecilSymbolHelper)
5153
{
5254
_module = module;
5355
_includeFilters = includeFilters;
@@ -63,6 +65,7 @@ public Coverage(string module,
6365
_instrumentationHelper = instrumentationHelper;
6466
_fileSystem = fileSystem;
6567
_sourceRootTranslator = sourceRootTranslator;
68+
_cecilSymbolHelper = cecilSymbolHelper;
6669

6770
_identifier = Guid.NewGuid().ToString();
6871
_results = new List<InstrumenterResult>();
@@ -100,7 +103,7 @@ public CoveragePrepareResult PrepareModules()
100103
continue;
101104
}
102105

103-
var instrumenter = new Instrumenter(module, _identifier, _excludeFilters, _includeFilters, _excludedSourceFiles, _excludeAttributes, _singleHit, _logger, _instrumentationHelper, _fileSystem, _sourceRootTranslator);
106+
var instrumenter = new Instrumenter(module, _identifier, _excludeFilters, _includeFilters, _excludedSourceFiles, _excludeAttributes, _singleHit, _logger, _instrumentationHelper, _fileSystem, _sourceRootTranslator, _cecilSymbolHelper);
104107

105108
if (instrumenter.CanInstrument())
106109
{

src/coverlet.core/Instrumentation/Instrumenter.cs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ internal class Instrumenter
3030
private readonly IInstrumentationHelper _instrumentationHelper;
3131
private readonly IFileSystem _fileSystem;
3232
private readonly ISourceRootTranslator _sourceRootTranslator;
33+
private readonly ICecilSymbolHelper _cecilSymbolHelper;
3334
private InstrumenterResult _result;
3435
private FieldDefinition _customTrackerHitsArray;
3536
private FieldDefinition _customTrackerHitsFilePath;
@@ -57,7 +58,8 @@ public Instrumenter(
5758
ILogger logger,
5859
IInstrumentationHelper instrumentationHelper,
5960
IFileSystem fileSystem,
60-
ISourceRootTranslator sourceRootTranslator)
61+
ISourceRootTranslator sourceRootTranslator,
62+
ICecilSymbolHelper cecilSymbolHelper)
6163
{
6264
_module = module;
6365
_identifier = identifier;
@@ -71,6 +73,7 @@ public Instrumenter(
7173
_instrumentationHelper = instrumentationHelper;
7274
_fileSystem = fileSystem;
7375
_sourceRootTranslator = sourceRootTranslator;
76+
_cecilSymbolHelper = cecilSymbolHelper;
7477
}
7578

7679
public bool CanInstrument()
@@ -486,7 +489,7 @@ private void InstrumentIL(MethodDefinition method)
486489
var index = 0;
487490
var count = processor.Body.Instructions.Count;
488491

489-
var branchPoints = CecilSymbolHelper.GetBranchPoints(method);
492+
var branchPoints = _cecilSymbolHelper.GetBranchPoints(method);
490493

491494
for (int n = 0; n < count; n++)
492495
{
@@ -495,7 +498,7 @@ private void InstrumentIL(MethodDefinition method)
495498
var targetedBranchPoints = branchPoints.Where(p => p.EndOffset == instruction.Offset);
496499

497500
// Check if the instruction is coverable
498-
if (CecilSymbolHelper.SkipNotCoverableInstruction(method, instruction))
501+
if (_cecilSymbolHelper.SkipNotCoverableInstruction(method, instruction))
499502
{
500503
index++;
501504
continue;

src/coverlet.core/Symbols/CecilSymbolHelper.cs

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
using System.Collections.Generic;
88
using System.Linq;
99
using System.Runtime.CompilerServices;
10-
10+
using Coverlet.Core.Abstractions;
1111
using Coverlet.Core.Extensions;
1212

1313
using Mono.Cecil;
@@ -16,16 +16,11 @@
1616

1717
namespace Coverlet.Core.Symbols
1818
{
19-
internal static class CecilSymbolHelper
19+
internal class CecilSymbolHelper : ICecilSymbolHelper
2020
{
2121
private const int StepOverLineCode = 0xFEEFEE;
22-
private static ConcurrentDictionary<string, int[]> CompilerGeneratedBranchesToExclude = null;
23-
24-
static CecilSymbolHelper()
25-
{
26-
// Create single instance, we cannot collide because we use full method name as key
27-
CompilerGeneratedBranchesToExclude = new ConcurrentDictionary<string, int[]>();
28-
}
22+
// Create single instance, we cannot collide because we use full method name as key
23+
private readonly ConcurrentDictionary<string, int[]> _compilerGeneratedBranchesToExclude = new ConcurrentDictionary<string, int[]>();
2924

3025
// In case of nested compiler generated classes, only the root one presents the CompilerGenerated attribute.
3126
// So let's search up to the outermost declaring type to find the attribute
@@ -265,9 +260,9 @@ private static bool SkipGeneratedBranchForExceptionRethrown(List<Instruction> in
265260
instructions[branchIndex + 3].OpCode == OpCodes.Throw;
266261
}
267262

268-
private static bool SkipGeneratedBranchesForExceptionHandlers(MethodDefinition methodDefinition, Instruction instruction, List<Instruction> bodyInstructions)
263+
private bool SkipGeneratedBranchesForExceptionHandlers(MethodDefinition methodDefinition, Instruction instruction, List<Instruction> bodyInstructions)
269264
{
270-
if (!CompilerGeneratedBranchesToExclude.ContainsKey(methodDefinition.FullName))
265+
if (!_compilerGeneratedBranchesToExclude.ContainsKey(methodDefinition.FullName))
271266
{
272267
/*
273268
This method is used to parse compiler generated code inside async state machine and find branches generated for exception catch blocks
@@ -393,13 +388,13 @@ private static bool SkipGeneratedBranchesForExceptionHandlers(MethodDefinition m
393388
}
394389
}
395390

396-
CompilerGeneratedBranchesToExclude.TryAdd(methodDefinition.FullName, detectedBranches.ToArray());
391+
_compilerGeneratedBranchesToExclude.TryAdd(methodDefinition.FullName, detectedBranches.ToArray());
397392
}
398393

399-
return CompilerGeneratedBranchesToExclude[methodDefinition.FullName].Contains(instruction.Offset);
394+
return _compilerGeneratedBranchesToExclude[methodDefinition.FullName].Contains(instruction.Offset);
400395
}
401396

402-
public static List<BranchPoint> GetBranchPoints(MethodDefinition methodDefinition)
397+
public IReadOnlyList<BranchPoint> GetBranchPoints(MethodDefinition methodDefinition)
403398
{
404399
var list = new List<BranchPoint>();
405400
if (methodDefinition is null)
@@ -664,7 +659,7 @@ await ...
664659
IL_00eb: br.s IL_00ed
665660
...
666661
*/
667-
internal static bool SkipNotCoverableInstruction(MethodDefinition methodDefinition, Instruction instruction)
662+
public bool SkipNotCoverableInstruction(MethodDefinition methodDefinition, Instruction instruction)
668663
{
669664
if (!IsMoveNextInsideAsyncStateMachine(methodDefinition))
670665
{

src/coverlet.msbuild.tasks/InstrumentationTask.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using Coverlet.Core;
66
using Coverlet.Core.Abstractions;
77
using Coverlet.Core.Helpers;
8+
using Coverlet.Core.Symbols;
89
using Microsoft.Build.Framework;
910
using Microsoft.Build.Utilities;
1011
using Microsoft.Extensions.DependencyInjection;
@@ -131,6 +132,7 @@ public override bool Execute()
131132
serviceCollection.AddSingleton<ISourceRootTranslator, SourceRootTranslator>(serviceProvider => new SourceRootTranslator(_path, serviceProvider.GetRequiredService<ILogger>(), serviceProvider.GetRequiredService<IFileSystem>()));
132133
// We need to keep singleton/static semantics
133134
serviceCollection.AddSingleton<IInstrumentationHelper, InstrumentationHelper>();
135+
serviceCollection.AddSingleton<ICecilSymbolHelper, CecilSymbolHelper>();
134136

135137
ServiceProvider = serviceCollection.BuildServiceProvider();
136138

@@ -156,7 +158,8 @@ public override bool Execute()
156158
_logger,
157159
ServiceProvider.GetService<IInstrumentationHelper>(),
158160
fileSystem,
159-
ServiceProvider.GetService<ISourceRootTranslator>());
161+
ServiceProvider.GetService<ISourceRootTranslator>(),
162+
ServiceProvider.GetService<ICecilSymbolHelper>());
160163

161164
CoveragePrepareResult prepareResult = coverage.PrepareModules();
162165
InstrumenterState = new TaskItem(System.IO.Path.GetTempFileName());

0 commit comments

Comments
 (0)