diff --git a/src/MiniCover.Core/Instrumentation/AssemblyInstrumenter.cs b/src/MiniCover.Core/Instrumentation/AssemblyInstrumenter.cs index 108689b..e7ac78d 100644 --- a/src/MiniCover.Core/Instrumentation/AssemblyInstrumenter.cs +++ b/src/MiniCover.Core/Instrumentation/AssemblyInstrumenter.cs @@ -35,7 +35,7 @@ public AssemblyInstrumenter( } public InstrumentedAssembly InstrumentAssemblyFile( - InstrumentationContext context, + IInstrumentationContext context, IFileInfo assemblyFile) { var assemblyDirectory = assemblyFile.Directory; @@ -59,7 +59,7 @@ public InstrumentedAssembly InstrumentAssemblyFile( } private InstrumentedAssembly InstrumentAssemblyDefinition( - InstrumentationContext context, + IInstrumentationContext context, AssemblyDefinition assemblyDefinition) { if (assemblyDefinition.CustomAttributes.Any(a => a.AttributeType.Name == "InstrumentedAttribute")) @@ -70,12 +70,6 @@ private InstrumentedAssembly InstrumentAssemblyDefinition( var assemblyDocuments = assemblyDefinition.GetAllDocuments(); - if (!assemblyDocuments.Any(d => context.IsSource(d.Url) || context.IsTest(d.Url))) - { - _logger.LogInformation("No link to source files or test files"); - return null; - } - var changedDocuments = assemblyDocuments.Where(d => d.FileHasChanged()).ToArray(); if (changedDocuments.Any()) { @@ -91,8 +85,6 @@ private InstrumentedAssembly InstrumentAssemblyDefinition( return null; } - _logger.LogInformation("Instrumenting"); - var instrumentedAssembly = new InstrumentedAssembly(assemblyDefinition.Name.Name); var instrumentedAttributeReference = assemblyDefinition.MainModule.ImportReference(instrumentedAttributeConstructor); assemblyDefinition.CustomAttributes.Add(new CustomAttribute(instrumentedAttributeReference)); @@ -110,6 +102,13 @@ private InstrumentedAssembly InstrumentAssemblyDefinition( instrumentedAssembly); } + if (!instrumentedAssembly.Methods.Any()) { + _logger.LogInformation("Nothing to instrument"); + return null; + } + + _logger.LogInformation("Assembly instrumented"); + var miniCoverTempPath = GetMiniCoverTempPath(); var instrumentedAssemblyFile = _fileSystem.FileInfo.FromFileName(Path.Combine(miniCoverTempPath, $"{Guid.NewGuid()}.dll")); diff --git a/src/MiniCover.Core/Instrumentation/FileBasedInstrumentationContext.cs b/src/MiniCover.Core/Instrumentation/FileBasedInstrumentationContext.cs new file mode 100644 index 0000000..d95183a --- /dev/null +++ b/src/MiniCover.Core/Instrumentation/FileBasedInstrumentationContext.cs @@ -0,0 +1,36 @@ +using System.Collections.Generic; +using System.IO.Abstractions; +using System.Linq; +using MiniCover.Core.Extensions; +using Mono.Cecil; + +namespace MiniCover.Core.Instrumentation +{ + public class FileBasedInstrumentationContext : IInstrumentationContext + { + private int _uniqueId; + + public virtual IList Assemblies { get; set; } + public virtual IList Sources { get; set; } + public virtual IList Tests { get; set; } + public virtual string HitsPath { get; set; } + public virtual IDirectoryInfo Workdir { get; set; } + + public virtual int NewInstructionId() + { + return ++_uniqueId; + } + + public virtual bool IsSource(MethodDefinition methodDefinition) + { + return methodDefinition.GetAllDocuments() + .Any(d => Sources.Any(s => s.FullName == d.Url)); + } + + public virtual bool IsTest(MethodDefinition methodDefinition) + { + return methodDefinition.GetAllDocuments() + .Any(d => Tests.Any(s => s.FullName == d.Url)); + } + } +} diff --git a/src/MiniCover.Core/Instrumentation/IAssemblyInstrumenter.cs b/src/MiniCover.Core/Instrumentation/IAssemblyInstrumenter.cs index 64bbe1b..c71b5c0 100644 --- a/src/MiniCover.Core/Instrumentation/IAssemblyInstrumenter.cs +++ b/src/MiniCover.Core/Instrumentation/IAssemblyInstrumenter.cs @@ -5,6 +5,6 @@ namespace MiniCover.Core.Instrumentation { public interface IAssemblyInstrumenter { - InstrumentedAssembly InstrumentAssemblyFile(InstrumentationContext context, IFileInfo assemblyFile); + InstrumentedAssembly InstrumentAssemblyFile(IInstrumentationContext context, IFileInfo assemblyFile); } } \ No newline at end of file diff --git a/src/MiniCover.Core/Instrumentation/IInstrumentationContext.cs b/src/MiniCover.Core/Instrumentation/IInstrumentationContext.cs new file mode 100644 index 0000000..a10b0c8 --- /dev/null +++ b/src/MiniCover.Core/Instrumentation/IInstrumentationContext.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; +using System.IO.Abstractions; +using Mono.Cecil; + +namespace MiniCover.Core.Instrumentation +{ + public interface IInstrumentationContext + { + IList Assemblies { get; } + string HitsPath { get; } + IDirectoryInfo Workdir { get; } + int NewInstructionId(); + bool IsSource(MethodDefinition methodDefinition); + bool IsTest(MethodDefinition methodDefinition); + } +} diff --git a/src/MiniCover.Core/Instrumentation/IInstrumenter.cs b/src/MiniCover.Core/Instrumentation/IInstrumenter.cs index 6364acb..6d882bf 100644 --- a/src/MiniCover.Core/Instrumentation/IInstrumenter.cs +++ b/src/MiniCover.Core/Instrumentation/IInstrumenter.cs @@ -4,6 +4,6 @@ namespace MiniCover.Core.Instrumentation { public interface IInstrumenter { - InstrumentationResult Instrument(InstrumentationContext context); + InstrumentationResult Instrument(IInstrumentationContext context); } } \ No newline at end of file diff --git a/src/MiniCover.Core/Instrumentation/IMethodInstrumenter.cs b/src/MiniCover.Core/Instrumentation/IMethodInstrumenter.cs index 42d3c07..4d2a5ef 100644 --- a/src/MiniCover.Core/Instrumentation/IMethodInstrumenter.cs +++ b/src/MiniCover.Core/Instrumentation/IMethodInstrumenter.cs @@ -5,6 +5,6 @@ namespace MiniCover.Core.Instrumentation { public interface IMethodInstrumenter { - void InstrumentMethod(InstrumentationContext context, bool instrumentInstructions, MethodDefinition methodDefinition, InstrumentedAssembly instrumentedAssembly); + void InstrumentMethod(IInstrumentationContext context, bool instrumentInstructions, MethodDefinition methodDefinition, InstrumentedAssembly instrumentedAssembly); } } \ No newline at end of file diff --git a/src/MiniCover.Core/Instrumentation/ITypeInstrumenter.cs b/src/MiniCover.Core/Instrumentation/ITypeInstrumenter.cs index ccf141b..b937722 100644 --- a/src/MiniCover.Core/Instrumentation/ITypeInstrumenter.cs +++ b/src/MiniCover.Core/Instrumentation/ITypeInstrumenter.cs @@ -5,6 +5,6 @@ namespace MiniCover.Core.Instrumentation { public interface ITypeInstrumenter { - void InstrumentType(InstrumentationContext context, TypeDefinition typeDefinition, InstrumentedAssembly instrumentedAssembly); + void InstrumentType(IInstrumentationContext context, TypeDefinition typeDefinition, InstrumentedAssembly instrumentedAssembly); } } \ No newline at end of file diff --git a/src/MiniCover.Core/Instrumentation/InstrumentationContext.cs b/src/MiniCover.Core/Instrumentation/InstrumentationContext.cs deleted file mode 100644 index 1c447db..0000000 --- a/src/MiniCover.Core/Instrumentation/InstrumentationContext.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System.Collections.Generic; -using System.IO; -using System.IO.Abstractions; -using System.Linq; - -namespace MiniCover.Core.Instrumentation -{ - public class InstrumentationContext - { - public virtual IList Assemblies { get; set; } - public virtual IList Sources { get; set; } - public virtual IList Tests { get; set; } - public virtual string HitsPath { get; set; } - public virtual IDirectoryInfo Workdir { get; set; } - public virtual int UniqueId { get; set; } - - public virtual bool IsSource(string file) - { - return Sources.Any(s => s.FullName == file); - } - - public virtual bool IsTest(string file) - { - return Tests.Any(s => s.FullName == file); - } - } -} diff --git a/src/MiniCover.Core/Instrumentation/Instrumenter.cs b/src/MiniCover.Core/Instrumentation/Instrumenter.cs index df41fac..e503efa 100644 --- a/src/MiniCover.Core/Instrumentation/Instrumenter.cs +++ b/src/MiniCover.Core/Instrumentation/Instrumenter.cs @@ -38,10 +38,8 @@ public Instrumenter( _logger = logger; } - public InstrumentationResult Instrument(InstrumentationContext context) + public InstrumentationResult Instrument(IInstrumentationContext context) { - context.Workdir = context.Workdir; - var result = new InstrumentationResult { SourcePath = context.Workdir.FullName, @@ -79,7 +77,7 @@ private bool ShouldInstrumentAssemblyFile(IFileInfo assemblyFile) } private void VisitAssemblyGroup( - InstrumentationContext context, + IInstrumentationContext context, InstrumentationResult result, IEnumerable assemblyFiles) { diff --git a/src/MiniCover.Core/Instrumentation/MethodInstrumenter.cs b/src/MiniCover.Core/Instrumentation/MethodInstrumenter.cs index 079fc0a..1996246 100644 --- a/src/MiniCover.Core/Instrumentation/MethodInstrumenter.cs +++ b/src/MiniCover.Core/Instrumentation/MethodInstrumenter.cs @@ -36,7 +36,7 @@ public MethodInstrumenter( } public void InstrumentMethod( - InstrumentationContext context, + IInstrumentationContext context, bool instrumentInstructions, MethodDefinition methodDefinition, InstrumentedAssembly instrumentedAssembly) @@ -96,10 +96,11 @@ public void InstrumentMethod( } private void InstrumentInstructions( - InstrumentationContext context, + IInstrumentationContext context, MethodDefinition methodDefinition, InstrumentedAssembly instrumentedAssembly, - IList<(SequencePoint sequencePoint, Instruction instruction)> sequencePointsInstructions, + IList<(SequencePoint sequencePoint, + Instruction instruction)> sequencePointsInstructions, ILProcessor ilProcessor, VariableDefinition methodContextVariable, InstrumentedMethod instrumentedMethod) @@ -219,11 +220,11 @@ private static int InstrumentInstruction( ILProcessor ilProcessor, VariableDefinition methodContextVariable, MethodReference hitMethodReference, - InstrumentationContext context) + IInstrumentationContext context) { return instruction.GetOrAddExtension("Id", () => { - var id = ++context.UniqueId; + var id = context.NewInstructionId(); ilProcessor.InsertBefore(instruction, new[] { ilProcessor.Create(OpCodes.Ldloc, methodContextVariable), @@ -239,7 +240,7 @@ private IEnumerable GetExclusions(IList instructions) return LambdaInitPattern.FindInstructions(instructions); } - private static string GetSourceRelativePath(InstrumentationContext context, string path) + private static string GetSourceRelativePath(IInstrumentationContext context, string path) { return PathUtils.GetRelativePath(context.Workdir.FullName, path); } diff --git a/src/MiniCover.Core/Instrumentation/TypeInstrumenter.cs b/src/MiniCover.Core/Instrumentation/TypeInstrumenter.cs index 16d671a..a5f1ca9 100644 --- a/src/MiniCover.Core/Instrumentation/TypeInstrumenter.cs +++ b/src/MiniCover.Core/Instrumentation/TypeInstrumenter.cs @@ -1,6 +1,4 @@ -using System.Linq; -using MiniCover.Core.Extensions; -using MiniCover.Core.Model; +using MiniCover.Core.Model; using Mono.Cecil; namespace MiniCover.Core.Instrumentation @@ -15,7 +13,7 @@ public TypeInstrumenter(IMethodInstrumenter methodInstrumenter) } public void InstrumentType( - InstrumentationContext context, + IInstrumentationContext context, TypeDefinition typeDefinition, InstrumentedAssembly instrumentedAssembly) { @@ -24,11 +22,8 @@ public void InstrumentType( if (!methodDefinition.HasBody || !methodDefinition.DebugInformation.HasSequencePoints) continue; - var methodDocuments = methodDefinition.GetAllDocuments(); - - var isSource = methodDocuments.Any(d => context.IsSource(d.Url)); - var isTest = methodDocuments.Any(d => context.IsTest(d.Url)); - + var isTest = context.IsTest(methodDefinition); + var isSource = context.IsSource(methodDefinition); if (!isSource && !isTest) continue; diff --git a/src/MiniCover/CommandLine/Commands/InstrumentCommand.cs b/src/MiniCover/CommandLine/Commands/InstrumentCommand.cs index d18cc48..8b247a6 100644 --- a/src/MiniCover/CommandLine/Commands/InstrumentCommand.cs +++ b/src/MiniCover/CommandLine/Commands/InstrumentCommand.cs @@ -88,7 +88,7 @@ public Task Execute() var testFiles = GetFiles(_includeTestsOption.Value, _excludeTestsOption.Value, _parentDirOption.DirectoryInfo); - var instrumentationContext = new InstrumentationContext + var instrumentationContext = new FileBasedInstrumentationContext { Assemblies = assemblies, HitsPath = _hitsDirectoryOption.DirectoryInfo.FullName, diff --git a/tests/MiniCover.Core.UnitTests/TestHelpers/InstrumentationExtensions.cs b/tests/MiniCover.Core.UnitTests/TestHelpers/InstrumentationExtensions.cs index 1a57668..725007f 100644 --- a/tests/MiniCover.Core.UnitTests/TestHelpers/InstrumentationExtensions.cs +++ b/tests/MiniCover.Core.UnitTests/TestHelpers/InstrumentationExtensions.cs @@ -86,9 +86,9 @@ public static MethodBase Load(this MethodDefinition methodDefinition) return type.GetMembers().OfType().First(m => m.Name == methodDefinition.Name); } - private static InstrumentationContext CreateInstrumentationContext(IEnumerable documents) + private static FileBasedInstrumentationContext CreateInstrumentationContext(IEnumerable documents) { - return new InstrumentationContext + return new FileBasedInstrumentationContext { HitsPath = "/tmp", Workdir = _fileSystem.DirectoryInfo.FromDirectoryName("/tmp"),