Skip to content

Commit 8c1ca3f

Browse files
committed
Merge branch 'master' into cleaner-build
2 parents 546c274 + 8e618c3 commit 8c1ca3f

File tree

9 files changed

+328
-12
lines changed

9 files changed

+328
-12
lines changed

THIRD-PARTY-NOTICES.txt

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
coverlet uses third-party libraries or other resources that may be
2+
distributed under licenses different than the coverlet software.
3+
4+
In the event that we accidentally failed to list a required notice, please
5+
bring it to our attention by posting an issue.
6+
7+
The attached notices are provided for information only.
8+
9+
10+
License notice for ConsoleTables
11+
--------------------------------
12+
13+
The MIT License (MIT)
14+
15+
Copyright (c) 2012 Khalid Abuhakmeh
16+
17+
Permission is hereby granted, free of charge, to any person obtaining a copy
18+
of this software and associated documentation files (the "Software"), to deal
19+
in the Software without restriction, including without limitation the rights
20+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
21+
copies of the Software, and to permit persons to whom the Software is
22+
furnished to do so, subject to the following conditions:
23+
24+
The above copyright notice and this permission notice shall be included in all
25+
copies or substantial portions of the Software.
26+
27+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
28+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
30+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
31+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
32+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
33+
SOFTWARE.
Lines changed: 271 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,271 @@
1+
// The MIT License (MIT)
2+
//
3+
// Copyright (c) 2012 Khalid Abuhakmeh
4+
//
5+
// Permission is hereby granted, free of charge, to any person obtaining a copy
6+
// of this software and associated documentation files (the "Software"), to deal
7+
// in the Software without restriction, including without limitation the rights
8+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
// copies of the Software, and to permit persons to whom the Software is
10+
// furnished to do so, subject to the following conditions:
11+
//
12+
// The above copyright notice and this permission notice shall be included in all
13+
// copies or substantial portions of the Software.
14+
//
15+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
// SOFTWARE.
22+
23+
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
24+
// ⚠ Do not modify this file. It will be replaced by a package reference once ConsoleTables has a strong name.
25+
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
26+
27+
using System;
28+
using System.Collections.Generic;
29+
using System.Linq;
30+
using System.Reflection;
31+
using System.Text;
32+
using System.Text.RegularExpressions;
33+
34+
namespace ConsoleTables
35+
{
36+
public class ConsoleTable
37+
{
38+
public IList<object> Columns { get; set; }
39+
public IList<object[]> Rows { get; protected set; }
40+
41+
public ConsoleTableOptions Options { get; protected set; }
42+
43+
public ConsoleTable(params string[] columns)
44+
:this(new ConsoleTableOptions { Columns = new List<string>(columns) })
45+
{
46+
}
47+
48+
public ConsoleTable(ConsoleTableOptions options)
49+
{
50+
Options = options ?? throw new ArgumentNullException("options");
51+
Rows = new List<object[]>();
52+
Columns = new List<object>(options.Columns);
53+
}
54+
55+
public ConsoleTable AddColumn(IEnumerable<string> names)
56+
{
57+
foreach (var name in names)
58+
Columns.Add(name);
59+
return this;
60+
}
61+
62+
public ConsoleTable AddRow(params object[] values)
63+
{
64+
if (values == null)
65+
throw new ArgumentNullException(nameof(values));
66+
67+
if (!Columns.Any())
68+
throw new Exception("Please set the columns first");
69+
70+
if (Columns.Count != values.Length)
71+
throw new Exception(
72+
$"The number columns in the row ({Columns.Count}) does not match the values ({values.Length}");
73+
74+
Rows.Add(values);
75+
return this;
76+
}
77+
78+
public static ConsoleTable From<T>(IEnumerable<T> values)
79+
{
80+
var table = new ConsoleTable();
81+
82+
var columns = GetColumns<T>();
83+
84+
table.AddColumn(columns);
85+
86+
foreach (var propertyValues in values.Select(value => columns.Select(column => GetColumnValue<T>(value, column) )))
87+
table.AddRow(propertyValues.ToArray());
88+
89+
return table;
90+
}
91+
92+
public override string ToString()
93+
{
94+
var builder = new StringBuilder();
95+
96+
// find the longest column by searching each row
97+
var columnLengths = ColumnLengths();
98+
99+
// create the string format with padding
100+
var format = Enumerable.Range(0, Columns.Count)
101+
.Select(i => " | {" + i + ",-" + columnLengths[i] + "}")
102+
.Aggregate((s, a) => s + a) + " |";
103+
104+
// find the longest formatted line
105+
var maxRowLength = Math.Max(0, Rows.Any() ? Rows.Max(row => string.Format(format, row).Length) : 0);
106+
var columnHeaders = string.Format(format, Columns.ToArray());
107+
108+
// longest line is greater of formatted columnHeader and longest row
109+
var longestLine = Math.Max(maxRowLength, columnHeaders.Length);
110+
111+
// add each row
112+
var results = Rows.Select(row => string.Format(format, row)).ToList();
113+
114+
// create the divider
115+
var divider = " " + string.Join("", Enumerable.Repeat("-", longestLine - 1)) + " ";
116+
117+
builder.AppendLine(divider);
118+
builder.AppendLine(columnHeaders);
119+
120+
foreach (var row in results)
121+
{
122+
builder.AppendLine(divider);
123+
builder.AppendLine(row);
124+
}
125+
126+
builder.AppendLine(divider);
127+
128+
if (Options.EnableCount)
129+
{
130+
builder.AppendLine("");
131+
builder.AppendFormat(" Count: {0}", Rows.Count);
132+
}
133+
134+
return builder.ToString();
135+
}
136+
137+
public string ToMarkDownString()
138+
{
139+
return ToMarkDownString('|');
140+
}
141+
142+
private string ToMarkDownString(char delimiter)
143+
{
144+
var builder = new StringBuilder();
145+
146+
// find the longest column by searching each row
147+
var columnLengths = ColumnLengths();
148+
149+
// create the string format with padding
150+
var format = Format(columnLengths, delimiter);
151+
152+
// find the longest formatted line
153+
var columnHeaders = string.Format(format, Columns.ToArray());
154+
155+
// add each row
156+
var results = Rows.Select(row => string.Format(format, row)).ToList();
157+
158+
// create the divider
159+
var divider = Regex.Replace(columnHeaders, @"[^|]", "-");
160+
161+
builder.AppendLine(columnHeaders);
162+
builder.AppendLine(divider);
163+
results.ForEach(row => builder.AppendLine(row));
164+
165+
return builder.ToString();
166+
}
167+
168+
public string ToMinimalString()
169+
{
170+
return ToMarkDownString(char.MinValue);
171+
}
172+
173+
public string ToStringAlternative()
174+
{
175+
var builder = new StringBuilder();
176+
177+
// find the longest column by searching each row
178+
var columnLengths = ColumnLengths();
179+
180+
// create the string format with padding
181+
var format = Format(columnLengths);
182+
183+
// find the longest formatted line
184+
var columnHeaders = string.Format(format, Columns.ToArray());
185+
186+
// add each row
187+
var results = Rows.Select(row => string.Format(format, row)).ToList();
188+
189+
// create the divider
190+
var divider = Regex.Replace(columnHeaders, @"[^|]", "-");
191+
var dividerPlus = divider.Replace("|", "+");
192+
193+
builder.AppendLine(dividerPlus);
194+
builder.AppendLine(columnHeaders);
195+
196+
foreach (var row in results)
197+
{
198+
builder.AppendLine(dividerPlus);
199+
builder.AppendLine(row);
200+
}
201+
builder.AppendLine(dividerPlus);
202+
203+
return builder.ToString();
204+
}
205+
206+
private string Format(List<int> columnLengths, char delimiter = '|')
207+
{
208+
var delimiterStr = delimiter == char.MinValue ? string.Empty : delimiter.ToString();
209+
var format = (Enumerable.Range(0, Columns.Count)
210+
.Select(i => " "+ delimiterStr + " {" + i + ",-" + columnLengths[i] + "}")
211+
.Aggregate((s, a) => s + a) + " " + delimiterStr).Trim();
212+
return format;
213+
}
214+
215+
private List<int> ColumnLengths()
216+
{
217+
var columnLengths = Columns
218+
.Select((t, i) => Rows.Select(x => x[i])
219+
.Union(new[] { Columns[i] })
220+
.Where(x => x != null)
221+
.Select(x => x.ToString().Length).Max())
222+
.ToList();
223+
return columnLengths;
224+
}
225+
226+
public void Write(Format format = ConsoleTables.Format.Default)
227+
{
228+
switch (format)
229+
{
230+
case ConsoleTables.Format.Default:
231+
Console.WriteLine(ToString());
232+
break;
233+
case ConsoleTables.Format.MarkDown:
234+
Console.WriteLine(ToMarkDownString());
235+
break;
236+
case ConsoleTables.Format.Alternative:
237+
Console.WriteLine(ToStringAlternative());
238+
break;
239+
case ConsoleTables.Format.Minimal:
240+
Console.WriteLine(ToMinimalString());
241+
break;
242+
default:
243+
throw new ArgumentOutOfRangeException(nameof(format), format, null);
244+
}
245+
}
246+
247+
private static IEnumerable<string> GetColumns<T>()
248+
{
249+
return typeof(T).GetProperties().Select(x => x.Name).ToArray();
250+
}
251+
252+
private static object GetColumnValue<T>(object target, string column)
253+
{
254+
return typeof(T).GetProperty(column).GetValue(target, null);
255+
}
256+
}
257+
258+
public class ConsoleTableOptions
259+
{
260+
public IEnumerable<string> Columns { get; set; } = new List<string>();
261+
public bool EnableCount { get; set; } = true;
262+
}
263+
264+
public enum Format
265+
{
266+
Default = 0,
267+
MarkDown = 1,
268+
Alternative = 2,
269+
Minimal = 3
270+
}
271+
}

src/coverlet.console/coverlet.console.csproj

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
</PropertyGroup>
2222

2323
<ItemGroup>
24-
<PackageReference Include="ConsoleTables" Version="2.1.0" />
2524
<PackageReference Include="Microsoft.Extensions.CommandLineUtils" Version="1.1.1" />
2625
</ItemGroup>
2726

src/coverlet.core/Instrumentation/Instrumenter.cs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ internal class Instrumenter
2323
private readonly string[] _includeFilters;
2424
private readonly string[] _excludedFiles;
2525
private readonly string[] _excludedAttributes;
26+
private readonly bool _isCoreLibrary;
2627
private InstrumenterResult _result;
2728
private FieldDefinition _customTrackerHitsFilePath;
2829
private FieldDefinition _customTrackerHitsArray;
@@ -41,6 +42,8 @@ public Instrumenter(string module, string identifier, string[] excludeFilters, s
4142
_includeFilters = includeFilters;
4243
_excludedFiles = excludedFiles ?? Array.Empty<string>();
4344
_excludedAttributes = excludedAttributes;
45+
46+
_isCoreLibrary = Path.GetFileNameWithoutExtension(_module) == "System.Private.CoreLib";
4447
}
4548

4649
public bool CanInstrument() => InstrumentationHelper.HasPdb(_module);
@@ -74,8 +77,7 @@ private void InstrumentModule()
7477
{
7578
resolver.AddSearchDirectory(Path.GetDirectoryName(_module));
7679
var parameters = new ReaderParameters { ReadSymbols = true, AssemblyResolver = resolver };
77-
bool isCoreLib = Path.GetFileNameWithoutExtension(_module) == "System.Private.CoreLib";
78-
if (isCoreLib)
80+
if (_isCoreLibrary)
7981
{
8082
parameters.MetadataImporterProvider = new CoreLibMetadataImporterProvider();
8183
}
@@ -97,7 +99,7 @@ private void InstrumentModule()
9799
var actualType = type.DeclaringType ?? type;
98100
if (!actualType.CustomAttributes.Any(IsExcludeAttribute)
99101
// Instrumenting Interlocked which is used for recording hits would cause an infinite loop.
100-
&& (!isCoreLib || actualType.FullName != "System.Threading.Interlocked")
102+
&& (!_isCoreLibrary || actualType.FullName != "System.Threading.Interlocked")
101103
&& !InstrumentationHelper.IsTypeExcluded(_module, actualType.FullName, _excludeFilters)
102104
&& InstrumentationHelper.IsTypeIncluded(_module, actualType.FullName, _includeFilters))
103105
InstrumentType(type);
@@ -430,9 +432,12 @@ private Instruction AddInstrumentationInstructions(MethodDefinition method, ILPr
430432
{
431433
if (_customTrackerRecordHitMethod == null)
432434
{
435+
var recordHitMethodName = _isCoreLibrary
436+
? nameof(ModuleTrackerTemplate.RecordHitInCoreLibrary)
437+
: nameof(ModuleTrackerTemplate.RecordHit);
433438
_customTrackerRecordHitMethod = new MethodReference(
434-
"RecordHit", method.Module.TypeSystem.Void, _customTrackerTypeDef);
435-
_customTrackerRecordHitMethod.Parameters.Add(new ParameterDefinition(method.Module.TypeSystem.Int32));
439+
recordHitMethodName, method.Module.TypeSystem.Void, _customTrackerTypeDef);
440+
_customTrackerRecordHitMethod.Parameters.Add(new ParameterDefinition("hitLocationIndex", ParameterAttributes.None, method.Module.TypeSystem.Int32));
436441
}
437442

438443
var indxInstr = Instruction.Create(OpCodes.Ldc_I4, hitEntryIndex);

src/coverlet.core/Reporters/OpenCoverReporter.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ public string Report(CoverageResult result)
9090

9191
XElement methodPoint = new XElement("MethodPoint");
9292
methodPoint.Add(new XAttribute("vc", methLineCoverage.Covered.ToString()));
93-
methodPoint.Add(new XAttribute("upsid", "0"));
93+
methodPoint.Add(new XAttribute("uspid", "0"));
9494
methodPoint.Add(new XAttribute(XName.Get("type", "xsi"), "SequencePoint"));
9595
methodPoint.Add(new XAttribute("ordinal", j.ToString()));
9696
methodPoint.Add(new XAttribute("offset", j.ToString()));
@@ -114,7 +114,7 @@ public string Report(CoverageResult result)
114114
{
115115
XElement sequencePoint = new XElement("SequencePoint");
116116
sequencePoint.Add(new XAttribute("vc", lines.Value.ToString()));
117-
sequencePoint.Add(new XAttribute("upsid", lines.Key.ToString()));
117+
sequencePoint.Add(new XAttribute("uspid", lines.Key.ToString()));
118118
sequencePoint.Add(new XAttribute("ordinal", k.ToString()));
119119
sequencePoint.Add(new XAttribute("sl", lines.Key.ToString()));
120120
sequencePoint.Add(new XAttribute("sc", "1"));
@@ -138,7 +138,7 @@ public string Report(CoverageResult result)
138138
{
139139
XElement branchPoint = new XElement("BranchPoint");
140140
branchPoint.Add(new XAttribute("vc", branche.Hits.ToString()));
141-
branchPoint.Add(new XAttribute("upsid", branche.Line.ToString()));
141+
branchPoint.Add(new XAttribute("uspid", branche.Line.ToString()));
142142
branchPoint.Add(new XAttribute("ordinal", branche.Ordinal.ToString()));
143143
branchPoint.Add(new XAttribute("path", branche.Path.ToString()));
144144
branchPoint.Add(new XAttribute("offset", branche.Offset.ToString()));

0 commit comments

Comments
 (0)