Skip to content

Commit

Permalink
Merge branch 'master' into release/Ezoguma
Browse files Browse the repository at this point in the history
  • Loading branch information
SteveGilham committed May 7, 2019
2 parents c85d90e + 2a81001 commit bcb985c
Show file tree
Hide file tree
Showing 75 changed files with 1,909 additions and 931 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
language: csharp
mono: latest
dist: xenial
dotnet: 2.1.503
sudo: false
addons:
apt:
sources:
Expand Down
58 changes: 31 additions & 27 deletions AltCover.CSApi/Definitions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ public interface IPrepareArgs
bool BranchCover { get; }
bool ExposeReturnCode { get; }
bool SourceLink { get; }
bool Defer { get; }

string[] CommandLine { get; }

Expand Down Expand Up @@ -162,38 +163,40 @@ public class PrepareArgs : IPrepareArgs
public bool BranchCover { get; set; }
public bool ExposeReturnCode { get; set; }
public bool SourceLink { get; set; }
public bool Defer { get; set; }

public string[] CommandLine { get; set; }

public FSApi.PrepareParams ToParameters()
{
var primitive = new AltCover.Primitive.PrepareParams(
InputDirectory,
OutputDirectory,
SymbolDirectories,
Dependencies,
Keys,
StrongNameKey,
XmlReport,
FileFilter,
AssemblyFilter,
AssemblyExcludeFilter,
TypeFilter,
MethodFilter,
AttributeFilter,
PathFilter,
CallContext,

OpenCover,
InPlace,
Save,
Single,
LineCover,
BranchCover,
CommandLine,
ExposeReturnCode,
SourceLink
);
InputDirectory,
OutputDirectory,
SymbolDirectories,
Dependencies,
Keys,
StrongNameKey,
XmlReport,
FileFilter,
AssemblyFilter,
AssemblyExcludeFilter,
TypeFilter,
MethodFilter,
AttributeFilter,
PathFilter,
CallContext,

OpenCover,
InPlace,
Save,
Single,
LineCover,
BranchCover,
CommandLine,
ExposeReturnCode,
SourceLink,
Defer
);
return FSApi.PrepareParams.NewPrimitive(primitive);
}

Expand Down Expand Up @@ -226,7 +229,8 @@ public static PrepareArgs Create()
CommandLine = { },

ExposeReturnCode = true,
SourceLink = false
SourceLink = false,
Defer = false
};
}

Expand Down
2 changes: 1 addition & 1 deletion AltCover.FSApi/AltCover.FSApi.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
</PropertyGroup>
</Otherwise>
</Choose>
<Import Project="$(FSharpTargetsPath)" />
<Import Project="$(FSharpTargetsPath)" Condition=" '$(FSharpTargetsPath)' != '' "/>
<ItemGroup>
<Compile Include="..\_Generated\AssemblyVersion.fs">
<Link>AssemblyVersion.fs</Link>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
<PropertyGroup Condition=" '$(FSharpTargetsPath)' == '' AND Exists('$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets') ">
<FSharpTargetsPath>$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets</FSharpTargetsPath>
</PropertyGroup>
<Import Project="$(FSharpTargetsPath)" />
<Import Project="$(FSharpTargetsPath)" Condition=" '$(FSharpTargetsPath)' != '' "/>
<ItemGroup>
<Compile Include="..\_Generated\AssemblyVersion.fs">
<Link>AssemblyVersion.fs</Link>
Expand Down
2 changes: 1 addition & 1 deletion AltCover.Fake/AltCover.Fake.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
</PropertyGroup>
</Otherwise>
</Choose>
<Import Project="$(FSharpTargetsPath)" />
<Import Project="$(FSharpTargetsPath)" Condition=" '$(FSharpTargetsPath)' != '' "/>
<ItemGroup>
<Compile Include="..\_Generated\AssemblyVersion.fs">
<Link>AssemblyVersion.fs</Link>
Expand Down
5 changes: 5 additions & 0 deletions AltCover.GlobalTool/runtimeconfig.template.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
// Rollforward across major versions of ASP.NET Core
// The default setting only will only rollforward across minor versions
"rollForwardOnNoCandidateFx": 2
}
2 changes: 1 addition & 1 deletion AltCover.PowerShell/AltCover.PowerShell.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@
</Reference>
<Reference Include="mscorlib" />
<Reference Include="Newtonsoft.Json">
<HintPath>..\packages\Newtonsoft.Json.12.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
<HintPath>..\packages\Newtonsoft.Json.12.0.2\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Condition="'$(OS)' != 'Windows_NT'" Include="System.Management.Automation">
Expand Down
10 changes: 8 additions & 2 deletions AltCover.PowerShell/Command.fs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ type Summary =
| BPlus = 4

[<Cmdlet(VerbsLifecycle.Invoke, "AltCover")>]
[<OutputType("System.Void")>]
[<OutputType([|"System.Void";"System.String"|])>]
[<System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.PowerShell",
"PS1101:AllCmdletsShouldAcceptPipelineInput",
Justification = "No valid input")>]
Expand Down Expand Up @@ -161,6 +161,10 @@ type InvokeAltCoverCommand(runner : bool) =
ValueFromPipeline = false, ValueFromPipelineByPropertyName = false)>]
member val SourceLink : SwitchParameter = SwitchParameter(false) with get, set

[<Parameter(ParameterSetName = "Instrument", Mandatory = false,
ValueFromPipeline = false, ValueFromPipelineByPropertyName = false)>]
member val Defer : SwitchParameter = SwitchParameter(false) with get, set

[<Parameter(ParameterSetName = "Runner", Mandatory = false, ValueFromPipeline = false,
ValueFromPipelineByPropertyName = false)>]
member val SummaryFormat : Summary = Summary.Default with get, set
Expand Down Expand Up @@ -210,7 +214,8 @@ type InvokeAltCoverCommand(runner : bool) =
BranchCover = self.BranchCover.IsPresent
CommandLine = self.CommandLine
ExposeReturnCode = not self.DropReturnCode.IsPresent
SourceLink = self.SourceLink.IsPresent }
SourceLink = self.SourceLink.IsPresent
Defer = self.Defer.IsPresent }

member private self.Log() =
FSApi.Logging.Primitive { Primitive.Logging.Create() with Error = (fun s -> self.Fail <- s :: self.Fail)
Expand Down Expand Up @@ -240,6 +245,7 @@ type InvokeAltCoverCommand(runner : bool) =
let task = self.Prepare()
Api.Prepare task) log
if status <> 0 then status.ToString() |> self.Log().Error
else if self.Runner.IsPresent then Api.Summary () |> self.WriteObject
match self.Fail with
| [] -> ()
| things -> String.Join(Environment.NewLine, things |> List.rev) |> makeError
Expand Down
2 changes: 1 addition & 1 deletion AltCover.PowerShell/packages.config
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@
<package id="FSharp.Core" version="4.5.2" targetFramework="net47" />
<package id="Mono.Cecil" version="0.10.3" targetFramework="net47" />
<package id="Mono.Options.Signed" version="0.2.3" targetFramework="net47" />
<package id="Newtonsoft.Json" version="12.0.1" targetFramework="net47" />
<package id="Newtonsoft.Json" version="12.0.2" targetFramework="net47" />
<package id="PowerShellStandard.Library" version="5.1.0" targetFramework="net47" />
</packages>
4 changes: 2 additions & 2 deletions AltCover.Recorder/AltCover.Recorder.fsproj
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\packages\ILMerge.3.0.21\build\ILMerge.props" Condition="Exists('..\packages\ILMerge.3.0.21\build\ILMerge.props')" />
<Import Project="..\packages\ILMerge.3.0.29\build\ILMerge.props" Condition="Exists('..\packages\ILMerge.3.0.29\build\ILMerge.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
Expand Down Expand Up @@ -99,7 +99,7 @@
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\ILMerge.3.0.21\build\ILMerge.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\ILMerge.3.0.21\build\ILMerge.props'))" />
<Error Condition="!Exists('..\packages\ILMerge.3.0.29\build\ILMerge.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\ILMerge.3.0.29\build\ILMerge.props'))" />
</Target>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
Expand Down
10 changes: 10 additions & 0 deletions AltCover.Recorder/AltCover.Shadow.fsproj
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\packages\ILMerge.3.0.29\build\ILMerge.props" Condition="Exists('..\packages\ILMerge.3.0.29\build\ILMerge.props')" />
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
Expand All @@ -18,6 +19,8 @@
<ResolveNuGetPackages>false</ResolveNuGetPackages>
<UseStandardResourceNames>True</UseStandardResourceNames>
<Win32Resource>$(ProjectDir)../AltCover/Resource.res</Win32Resource>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
Expand Down Expand Up @@ -58,6 +61,12 @@
</Otherwise>
</Choose>
<Import Project="$(FSharpTargetsPath)" Condition="Exists('$(FSharpTargetsPath)')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\ILMerge.3.0.29\build\ILMerge.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\ILMerge.3.0.29\build\ILMerge.props'))" />
</Target>
<ItemGroup>
<Compile Include="AssemblyInfo.fs" />
<Compile Include="..\_Generated\VisibleToTest.fs">
Expand All @@ -70,6 +79,7 @@
<Compile Include="Tracer.fs" />
<Compile Include="Recorder.fs" />
<EmbeddedResource Include="Strings.resx" />
<Content Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Reference Include="mscorlib" />
Expand Down
95 changes: 80 additions & 15 deletions AltCover.Recorder/Base.fs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ type
| Time = 1
| Call = 2
| Both = 3
| Table = 4

#if NETSTANDARD2_0
[<System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage>]
Expand All @@ -50,11 +51,36 @@ type
[<System.Runtime.InteropServices.ProgIdAttribute("ExcludeFromCodeCoverage hack for OpenCover issue 615")>]
#endif
#endif
[<NoComparison>]
type internal Track =
| Null
| Time of int64
| Call of int
| Both of (int64 * int)
| Table of Dictionary<string, Dictionary<int, PointVisit>>
and [<NoComparison>]
#if NETSTANDARD2_0
[<System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage>]
#else
#if NETCOREAPP2_0
[<System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage>]
#else
[<System.Runtime.InteropServices.ProgIdAttribute("ExcludeFromCodeCoverage hack for OpenCover issue 615")>]
#endif
#endif
internal PointVisit =
{
mutable Count : int64
Tracks : List<Track>
}
with
static member Create () = { Count = 0L; Tracks = List<Track>() }
static member Init n l = let tmp = { PointVisit.Create() with Count = n }
tmp.Tracks.AddRange l
tmp
member self.Step() = System.Threading.Interlocked.Increment(&self.Count) |> ignore
member self.Track something = lock self.Tracks (fun () -> self.Tracks.Add something)
member self.Total() = self.Count + int64 self.Tracks.Count

module internal Assist =
let internal SafeDispose x =
Expand Down Expand Up @@ -130,8 +156,8 @@ module internal Counter =
/// <param name="hitCounts">The coverage results to incorporate</param>
/// <param name="coverageFile">The coverage file to update as a stream</param>
let internal UpdateReport (postProcess : XmlDocument -> unit)
(pointProcess : XmlElement -> Track list -> unit) own
(counts : Dictionary<string, Dictionary<int, int * Track list>>) format coverageFile
(pointProcess : XmlElement -> List<Track> -> unit) own
(counts : Dictionary<string, Dictionary<int, PointVisit>>) format coverageFile
(outputFile : Stream) =
let flushStart = DateTime.UtcNow
let coverageDocument = ReadXDocument coverageFile
Expand Down Expand Up @@ -193,14 +219,14 @@ module internal Counter =
let pt = snd x
let counter = fst x
let vc =
Int32.TryParse
Int64.TryParse
(pt.GetAttribute(v), System.Globalization.NumberStyles.Integer,
System.Globalization.CultureInfo.InvariantCulture) |> snd
// Treat -ve visit counts (an exemption added in analysis) as zero
let (count, l) = moduleHits.[counter]
let visits = (max 0 vc) + count + l.Length
let count = moduleHits.[counter]
let visits = (max 0L vc) + count.Total()
pt.SetAttribute(v, visits.ToString(CultureInfo.InvariantCulture))
pointProcess pt l))
pointProcess pt count.Tracks))
postProcess coverageDocument

// Save modified xml to a file
Expand Down Expand Up @@ -232,13 +258,52 @@ module internal Counter =
UpdateReport postProcess pointProcess own counts format coverageFile outputFile
TimeSpan(DateTime.UtcNow.Ticks - flushStart.Ticks)

let internal AddVisit (counts : Dictionary<string, Dictionary<int, int * Track list>>)
moduleId hitPointId context =
let private EnsureModule (counts : Dictionary<string, Dictionary<int, PointVisit>>) moduleId =
if not (counts.ContainsKey moduleId) then
counts.[moduleId] <- Dictionary<int, int * Track list>()
if not (counts.[moduleId].ContainsKey hitPointId) then
counts.[moduleId].Add(hitPointId, (0, []))
let n, l = counts.[moduleId].[hitPointId]
counts.[moduleId].[hitPointId] <- match context with
| Null -> (1 + n, l)
| something -> (n, something :: l)
lock counts (fun () ->
if not (counts.ContainsKey moduleId)
then counts.Add(moduleId, Dictionary<int, PointVisit>())
)

let private EnsurePoint (counts : Dictionary<int, PointVisit>) hitPointId =
if not (counts.ContainsKey hitPointId) then
lock counts (fun () ->
if not (counts.ContainsKey hitPointId)
then counts.Add(hitPointId, PointVisit.Create()))

let internal AddTable (counts : Dictionary<string, Dictionary<int, PointVisit>>)
(t : Dictionary<string, Dictionary<int, PointVisit>>) =
let mutable hitcount = 0L
t.Keys
|> Seq.iter (fun m -> EnsureModule counts m
let next = counts.[m]
let here = t.[m]
here.Keys |>
Seq.iter (fun p -> EnsurePoint next p
let v = next.[p]
let add = here.[p]
hitcount <- hitcount + add.Total()
lock v (fun () -> v.Count <- v.Count + add.Count
v.Tracks.AddRange(add.Tracks)
)))
hitcount

let internal AddSingleVisit (counts : Dictionary<string, Dictionary<int, PointVisit>>)
moduleId hitPointId context =
EnsureModule counts moduleId
let next = counts.[moduleId]
EnsurePoint next hitPointId

let v = next.[hitPointId]
match context with
| Null -> v.Step()
| something -> v.Track something

#if RUNNER
let internal AddVisit (counts : Dictionary<string, Dictionary<int, PointVisit>>)
moduleId hitPointId context =
match context with
| Table t -> AddTable counts t
| _ -> AddSingleVisit counts moduleId hitPointId context
1L
#endif
Loading

0 comments on commit bcb985c

Please sign in to comment.