Skip to content

Commit

Permalink
Merge branch 'master' into release/Genbu
Browse files Browse the repository at this point in the history
  • Loading branch information
SteveGilham committed Jan 1, 2021
2 parents ca37205 + bfd234c commit e338179
Show file tree
Hide file tree
Showing 114 changed files with 2,014 additions and 958 deletions.
2 changes: 1 addition & 1 deletion .config/dotnet-tools.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"isRoot": true,
"tools": {
"dotnet-reportgenerator-globaltool": {
"version": "4.8.1",
"version": "4.8.3",
"commands": [
"reportgenerator"
]
Expand Down
2 changes: 1 addition & 1 deletion AltCover.Api.Tests/AltCover.Api.Tests.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.8.3" />
<PackageReference Include="NUnit" Version="3.12.0" />
<PackageReference Include="YoloDev.Expecto.TestSdk" Version="0.9.2" Condition="'$(TargetFramework)' != 'net472'" />
<PackageReference Include="YoloDev.Expecto.TestSdk" Version="0.11.1" Condition="'$(TargetFramework)' != 'net472'" />
<PackageReference Include="Mono.Cecil" Version="0.11.2" />
</ItemGroup>

Expand Down
14 changes: 7 additions & 7 deletions AltCover.Api.Tests/FSApiTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ module FSApiTests =
|> not
then setAttribute el "crapScore" "0")
OpenCover.PostProcess after BranchOrdinal.Offset
//#if ! NET5_0
//#if !NET472
// NUnit.Framework.Assert.That(after.ToString(),
// NUnit.Framework.Is.EqualTo(before.ToString()))
//#endif
Expand Down Expand Up @@ -177,7 +177,7 @@ module FSApiTests =
let sample = typeof<M.Thing>.Assembly.Location
let reporter, doc = AltCover.Report.reportGenerator()
let visitors = [ reporter ]
Visitor.visit visitors [(sample, [])]
Visitor.visit visitors [ { AssemblyPath = sample; Destinations = [] } ]
use mstream = new MemoryStream()
let rewrite = CoverageFormats.ConvertFromNCover doc [ sample ]
test <@ rewrite |> isNull |> not @>
Expand Down Expand Up @@ -338,13 +338,13 @@ module FSApiTests =
|> List.collect (fun f -> f prep)
|> List.sort

// not input and output directories
//#if ! NET5_0
// not input and output directories or inplace
//#if !NET472
// NUnit.Framework.Assert.That(prepareFragments |> List.length, NUnit.Framework.Is.EqualTo ((prepareNames |> List.length) - 2),
// "expected " + String.Join("; ", prepareNames) + Environment.NewLine +
// "but got " + String.Join("; ", prepareFragments))
//#endif
test <@ (prepareFragments) |> List.length = ((prepareNames |> List.length) - 2) @>
test <@ (prepareFragments) |> List.length = ((prepareNames |> List.length) - 3) @>

let collect = doc.Descendants()
|> Seq.filter (fun d -> d.Name.LocalName = "AltCover.Collect")
Expand All @@ -363,7 +363,7 @@ module FSApiTests =
|> List.sort

// not recorder directory
//#if ! NET5_0
//#if !NET472
// NUnit.Framework.Assert.That(collectFragments |> List.length, NUnit.Framework.Is.EqualTo ((collectNames |> List.length) - 1),
// "expected " + String.Join("; ", collectNames) + Environment.NewLine +
// "but got " + String.Join("; ", collectFragments))
Expand All @@ -386,7 +386,7 @@ module FSApiTests =
|> List.sort

// ignore Is<CaseName> and Tag
//#if ! NET5_0
//#if !NET472
// NUnit.Framework.Assert.That(optionsFragments |> List.length, NUnit.Framework.Is.EqualTo ((optionNames |> List.length) - (1 + optionCases)),
// "expected " + String.Join("; ", optionNames) + Environment.NewLine +
// "but got " + String.Join("; ", optionsFragments))
Expand Down
2 changes: 1 addition & 1 deletion AltCover.Api.Tests/Program.fs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
namespace Tests

#if NET5_0
#if !NET472

open Expecto

Expand Down
1 change: 1 addition & 0 deletions AltCover.Avalonia.FuncUI/AltCover.Avalonia.FuncUI.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
<IntermediateOutputPath>$(ProjectDir)..\_Intermediate/$(AssemblyName).FuncUI/$(Configuration)+$(Platform)/</IntermediateOutputPath>
<OtherFlags>--keyfile:$(ProjectDir)..\Build\Infrastructure.snk</OtherFlags>
<RollForward>Major</RollForward>
<CheckEolTargetFramework>false</CheckEolTargetFramework>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)'=='Debug'">
Expand Down
1 change: 1 addition & 0 deletions AltCover.Avalonia/AltCover.Avalonia.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
<UseStandardResourceNames>True</UseStandardResourceNames>
<Win32Resource>$(ProjectDir)../AltCover.Visualizer/Resource.res</Win32Resource>
<RollForward>Major</RollForward>
<CheckEolTargetFramework>false</CheckEolTargetFramework>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)'=='Debug'">
Expand Down
2 changes: 1 addition & 1 deletion AltCover.DotNet/DotNet.fs
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ module DotNet =
Justification="Internal implementation detail")>]
let internal toCLIOptionsArgArgumentList (options : ICLIOptions) =
[
arg, "Force", "true", options.ForceDelete //=true|false` to force delete any left-over `__Saved` folders from previous runs
arg, "Force", "true", options.ForceDelete //=true|false` to force delete any left-over `__Instrumented` folders from previous runs
arg, "FailFast", "true", options.FailFast //=true|false` to skip coverage collection if the unit tests fail
]

Expand Down
2 changes: 0 additions & 2 deletions AltCover.Engine/AltCover.Engine.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@
<ContinuousIntegrationBuild Condition="'$(APPVEYOR)'=='True'">true</ContinuousIntegrationBuild>
<DeterministicSourcePaths Condition="'$(APPVEYOR)'=='True'">true</DeterministicSourcePaths>
<SolutionDir Condition="'$(SolutionDir)' == '$(ProjectDir)'">$(ProjectDir)../</SolutionDir>
<!-- https://github.com/dotnet/sdk/issues/987 -->
<AssemblySearchPaths Condition="'$(TargetFramework)' == 'net472'">$(AssemblySearchPaths);{GAC}</AssemblySearchPaths>
<OutputPath>$(SolutionDir)_Binaries/$(AssemblyName)/$(Configuration)+$(Platform)/</OutputPath>
<IntermediateOutputPath>$(SolutionDir)_Intermediate/$(AssemblyName)/$(Configuration)+$(Platform)/</IntermediateOutputPath>
<DocumentationFile>$(OutputPath)\$(TargetFramework)\$(AssemblyName).xml</DocumentationFile>
Expand Down
6 changes: 3 additions & 3 deletions AltCover.Engine/Augment.fs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ open System.Diagnostics.CodeAnalysis
[<SuppressMessage("Gendarme.Rules.Smells", "AvoidSpeculativeGeneralityRule",
Justification = "AvoidCodeDuplicatedInSameClassRule")>]
[<AutoOpen>]
#if !GUI
module internal Augment =
#else
#if GUI
module Augment =
#else
module internal Augment =
#endif

#if !ValidateGendarmeEmulation
Expand Down
84 changes: 36 additions & 48 deletions AltCover.Engine/Instrument.fs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ open System.Collections.Generic
open System.Diagnostics.CodeAnalysis
open System.IO
open System.Reflection
open System.Resources

open Manatee.Json
open Mono.Cecil
Expand Down Expand Up @@ -86,8 +85,6 @@ module internal Instrument =
let version = typeof<AltCover.Recorder.Tracer>.Assembly.GetName().Version.ToString()
let internal resolutionTable = Dictionary<string, AssemblyDefinition>()

[<SuppressMessage("Microsoft.Maintainability", "CA1506",
Justification = "partitioned into closures")>]
module internal I =

// Locate the method that must be called to register a code point for coverage visit.
Expand Down Expand Up @@ -472,16 +469,16 @@ module internal Instrument =

o.GetIndentedString().Replace("\t\t", " ").Replace("\t", " ").Replace(" :", ":")

let private visitModule (state : InstrumentContext) (m : ModuleDefinition) included =
let private visitModule (state : InstrumentContext) (m : ModuleEntry) =
let restate =
match included <> Inspections.Ignore with
match m.Inspection <> Inspections.Ignore with
| true ->
let recordingMethod =
match state.RecordingMethod with
| [] -> recordingMethod state.RecordingAssembly
| _ -> state.RecordingMethod

let refs = recordingMethod |> List.map m.ImportReference
let refs = recordingMethod |> List.map m.Module.ImportReference
{ state with
RecordingMethodRef =
{ Visit = refs.[0]
Expand All @@ -490,20 +487,19 @@ module internal Instrument =
RecordingMethod = recordingMethod
AsyncSupport = state.AsyncSupport
|> Option.map (fun a -> { a with LocalWait =
a.Wait |> m.ImportReference })
a.Wait |> m.Module.ImportReference })
}
| _ -> state
{ restate with
ModuleId =
match CoverageParameters.reportKind() with
| ReportFormat.OpenCover -> KeyStore.hashFile m.FileName
| _ -> m.Mvid.ToString() }
| ReportFormat.OpenCover -> KeyStore.hashFile m.Module.FileName
| _ -> m.Module.Mvid.ToString() }

let private visitMethod (state : InstrumentContext) (m : MethodDefinition)
(included : Inspections) =
match included.IsInstrumented with
let private visitMethod (state : InstrumentContext) m =
match m.Inspection.IsInstrumented with
| true ->
let body = m.Body
let body = m.Method.Body
{ state with
MethodBody = body
MethodWorker = body.GetILProcessor() }
Expand All @@ -514,12 +510,12 @@ module internal Instrument =
body.Instructions |> Seq.iter (substituteInstructionOperand instruction injected)
body.ExceptionHandlers |> Seq.iter (substituteExceptionBoundary instruction injected)

let private visitMethodPoint (state : InstrumentContext) instruction point included =
if included then
let private visitMethodPoint (state : InstrumentContext) e =
if e.Interesting then
let instrLoadModuleId =
insertVisit instruction state.MethodWorker state.RecordingMethodRef.Visit
state.ModuleId point
updateBranchReferences state.MethodBody instruction instrLoadModuleId
insertVisit e.Instruction state.MethodWorker state.RecordingMethodRef.Visit
state.ModuleId e.Uid
updateBranchReferences state.MethodBody e.Instruction instrLoadModuleId
state

let internal visitBranchPoint (state : InstrumentContext) branch =
Expand Down Expand Up @@ -611,12 +607,11 @@ module internal Instrument =
let private invokePredicate (f:unit -> bool) =
f()

let internal doTrack state (m : MethodDefinition) (included:Inspections)
(track : (int * string) option) =
track
|> Option.fold (fun (s:InstrumentContext) (n, _) -> // this line for FxCop
let internal doTrack state (m : MethodEntry) =
m.Track
|> Option.fold (fun (s:InstrumentContext) (n, _) ->
let body =
[ m.Body; state.MethodBody ].[(included.IsInstrumented).ToInt32]
[ m.Method.Body; state.MethodBody ].[(m.Inspection.IsInstrumented).ToInt32]
let methodWorker = body.GetILProcessor()
removeTailInstructions methodWorker
let (endFinally, rtype, leave) = encapsulateWithTryFinally methodWorker
Expand All @@ -643,7 +638,7 @@ module internal Instrument =
"System.Threading.Tasks.Task"
"System.Threading.Tasks.Task`1"
] |> Seq.exists (fun n -> n = e)
let isStateMachine () = m.CustomAttributes // could improve this
let isStateMachine () = m.Method.CustomAttributes // could improve this
|> Seq.exists (fun a -> a.AttributeType.FullName =
"System.Runtime.CompilerServices.AsyncStateMachineAttribute")
let asyncChecks =
Expand Down Expand Up @@ -671,7 +666,7 @@ module internal Instrument =
// ahead of the leave opcode

let newstate = { state with AsyncSupport = Some
(Option.defaultWith (fun () -> AsyncSupport.Update m)
(Option.defaultWith (fun () -> AsyncSupport.Update m.Method)
state.AsyncSupport) }

let injectWait ilp (i:Instruction) =
Expand All @@ -692,22 +687,21 @@ module internal Instrument =
newstate
else state) state

let private visitAfterMethod state m (included : Inspections) track =
if included.IsInstrumented then
let private visitAfterMethod state (m:MethodEntry) =
if m.Inspection.IsInstrumented then
let body = state.MethodBody
// changes conditional (br.s, brtrue.s ...) operators to corresponding "long" ones (br, brtrue)
body.SimplifyMacros()
// changes "long" conditional operators to their short representation where possible
body.OptimizeMacros()
doTrack state m included track
doTrack state m

[<System.Diagnostics.CodeAnalysis.SuppressMessage(
"Gendarme.Rules.Maintainability", "AvoidUnnecessarySpecializationRule",
Justification = "AvoidSpeculativeGenerality too")>]
let private visitAfterAssembly state (assembly : AssemblyDefinition)
(paths : string list) =
let originalFileName = Path.GetFileName assembly.MainModule.FileName
writeAssemblies assembly originalFileName paths Output.info
let private visitAfterAssembly (state:InstrumentContext) (assembly : AssemblyEntry) =
let originalFileName = Path.GetFileName assembly.Assembly.MainModule.FileName
writeAssemblies assembly.Assembly originalFileName assembly.Destinations Output.info
state

[<System.Diagnostics.CodeAnalysis.SuppressMessage("Gendarme.Rules.Correctness",
Expand Down Expand Up @@ -760,21 +754,20 @@ module internal Instrument =
let internal instrumentationVisitorCore (state : InstrumentContext) (node : Node) =
match node with
| Start _ -> visitStart state
| Assembly(assembly, included, _) ->
updateStrongReferences assembly state.InstrumentedAssemblies |> ignore
if included <> Inspections.Ignore then
assembly.MainModule.AssemblyReferences.Add(state.RecordingAssembly.Name)
| Assembly assembly ->
updateStrongReferences assembly.Assembly state.InstrumentedAssemblies |> ignore
if assembly.Inspection <> Inspections.Ignore then
assembly.Assembly.MainModule.AssemblyReferences.Add(state.RecordingAssembly.Name)
state
| Module(m, included) -> visitModule state m included
| Module m -> visitModule state m
| Type _ -> state
| Method(m, included, _, _) -> visitMethod state m included
| MethodPoint(instruction, _, point, included, _) ->
visitMethodPoint state instruction point included
| Method m -> visitMethod state m
| MethodPoint m -> visitMethodPoint state m
| BranchPoint branch -> visitBranchPoint state branch
| AfterMethod(m, included, track) -> visitAfterMethod state m included track
| AfterMethod m -> visitAfterMethod state m
| AfterType -> state
| AfterModule -> state
| AfterAssembly(assembly, paths) -> visitAfterAssembly state assembly paths
| AfterAssembly assembly -> visitAfterAssembly state assembly
| Finish -> finishVisit state

let internal instrumentationVisitorWrapper (core : InstrumentContext -> Node -> InstrumentContext)
Expand All @@ -800,9 +793,4 @@ module internal Instrument =
// param name="assemblies">List of assembly paths to visit</param>
// returns>Stateful visitor function</returns>
let internal instrumentGenerator(assemblies : string list) =
Visitor.encloseState I.instrumentationVisitor (InstrumentContext.Build assemblies)

[<assembly: SuppressMessage("Microsoft.Maintainability", "CA1506:AvoidExcessiveClassCoupling",
Scope="member", Target="AltCover.Instrument+I+doTrack@617.#Invoke(AltCover.InstrumentContext,System.Tuple`2<System.Int32,System.String>)",
Justification="Nice idea if you can manage it")>]
()
Visitor.encloseState I.instrumentationVisitor (InstrumentContext.Build assemblies)
6 changes: 1 addition & 5 deletions AltCover.Engine/Main.fs
Original file line number Diff line number Diff line change
Expand Up @@ -94,11 +94,7 @@ module internal Main =
"--callContext", x) :: CommandLine.error
(false, Left None)

[<SuppressMessage("Microsoft.Maintainability", "CA1506:AvoidExcessiveClassCoupling",
Justification="It's perfectly maintainable.")>]
module internal I =
[<SuppressMessage("Microsoft.Maintainability", "CA1506:AvoidExcessiveClassCoupling",
Justification="It's perfectly maintainable.")>]
let internal declareOptions() =
let makeRegex (x : String) =
x.Replace(char 0, '\\').Replace(char 1, '|')
Expand Down Expand Up @@ -447,7 +443,7 @@ module internal Main =
let proto = a.Path.Head
let targets =
a.Path |> List.map (Path.GetDirectoryName >> (fun d -> mapping.[d]))
((proto, targets), a.Name))
({ AssemblyPath = proto; Destinations = targets}, a.Name))

List.unzip sorted

Expand Down
Loading

0 comments on commit e338179

Please sign in to comment.