< Summary

Information
Class: DirectSight.Parser.Analysis.Class
Assembly DirectSight
File(s): /home/runner/work/DirectSight/DirectSight/DirectSight/Parser/Analysis/Class.cs
Line coverage
89%
Covered lines: 79
Uncovered lines: 9
Coverable lines: 88
Total lines: 277
Line coverage: 89.7%
Branch coverage
86%
Covered branches: 33
Total branches: 38
Branch coverage: 86.8%
Method coverage

Metrics

MethodBranch coverage Cyclomatic complexity NPath complexity Sequence coverage
.cctor()100%11100%
.ctor(...)83.33%1818100%
.ctor(...)100%11100%
ToString()100%110%
Equals(...)100%66100%
GetHashCode()100%110%
AddFile(...)100%11100%
Merge(...)66.66%6668.75%

File(s)

/home/runner/work/DirectSight/DirectSight/DirectSight/Parser/Analysis/Class.cs

#LineLine coverage
 1using System;
 2using System.Collections.Generic;
 3using System.Linq;
 4using System.Text.RegularExpressions;
 5using DirectSight.Common;
 6
 7namespace DirectSight.Parser.Analysis;
 8
 9/// <summary>
 10/// Represents a class.
 11/// </summary>
 12public class Class
 13{
 14    /// <summary>
 15    /// Regex to analyze if a class is generic.
 16    /// </summary>
 117    private static readonly Regex GenericClassRegex = new Regex("^(?<Name>.+)`(?<Number>\\d+)$", RegexOptions.Compiled);
 18
 19    /// <summary>
 20    /// List of files that define this class.
 21    /// </summary>
 147922    private readonly List<CodeFile> files = [];
 23
 24    /// <summary>
 25    /// Initializes a new instance of the <see cref="Class"/> class.
 26    /// </summary>
 27    /// <param name="name">The name of the class.</param>
 28    /// <param name="assembly">The assembly.</param>
 29    internal Class(string name, Assembly assembly)
 147930        : this(name, name, assembly)
 147931    {
 147932    }
 33
 34    /// <summary>
 35    /// Initializes a new instance of the <see cref="Class"/> class.
 36    /// </summary>
 37    /// <param name="name">The name of the class.</param>
 38    /// <param name="rawName">The raw name of the class.</param>
 39    /// <param name="assembly">The assembly.</param>
 147940    internal Class(string name, string rawName, Assembly assembly)
 147941    {
 147942        this.Name = name ?? throw new ArgumentNullException(nameof(name));
 147943        this.RawName = rawName ?? throw new ArgumentNullException(nameof(rawName));
 147944        this.Assembly = assembly ?? throw new ArgumentNullException(nameof(assembly));
 45
 147946        this.DisplayName = name;
 47
 48        /*
 49         * Convert class name of generic classes:
 50         * See: https://github.com/coverlet-coverage/coverlet/issues/1077
 51         *
 52         * SomeClass`1 -> SomeClass<T>
 53         * SomeClass`2 -> SomeClass<T1, T2>
 54         * SomeClass`3 -> SomeClass<T1, T2, T3>
 55         */
 147956        if (name.Contains("`"))
 17957        {
 17958            Match match = GenericClassRegex.Match(name);
 59
 17960            if (match.Success)
 17961            {
 17962                this.DisplayName = match.Groups["Name"].Value;
 63
 17964                int number = int.Parse(match.Groups["Number"].Value);
 65
 17966                if (number == 1)
 167                {
 168                    this.DisplayName += "<T>";
 169                }
 17870                else if (number > 1)
 17871                {
 17872                    this.DisplayName += "<";
 73
 107074                    for (int i = 1; i <= number; i++)
 35775                    {
 35776                        if (i > 1)
 17977                        {
 17978                            this.DisplayName += ", ";
 17979                        }
 80
 35781                        this.DisplayName += "T" + i;
 35782                    }
 83
 17884                    this.DisplayName += ">";
 17885                }
 17986            }
 17987        }
 147988    }
 89
 90    /// <summary>
 91    /// Gets the name of the class.
 92    /// </summary>
 188793    public string Name { get; }
 94
 95    /// <summary>
 96    /// Gets the display name of the class.
 97    /// </summary>
 104198    public string DisplayName { get; }
 99
 100    /// <summary>
 101    /// Gets the raw name of the class.
 102    /// </summary>
 6454103    public string RawName { get; }
 104
 105    /// <summary>
 106    /// Gets the assembly.
 107    /// </summary>
 108    /// <value>The assembly.</value>
 2407109    public Assembly Assembly { get; internal set; }
 110
 111    /// <summary>
 112    /// Gets the files.
 113    /// </summary>
 114    /// <value>The files.</value>
 1148115    public IEnumerable<CodeFile> Files => this.files.OrderBy(f => f.Path);
 116
 117    /// <summary>
 118    /// Gets the number of covered lines.
 119    /// </summary>
 120    /// <value>The covered lines.</value>
 3115121    public int CoveredLines => this.files.SafeSum(f => f.CoveredLines);
 122
 123    /// <summary>
 124    /// Gets the number of coverable lines.
 125    /// </summary>
 126    /// <value>The coverable lines.</value>
 4976127    public int CoverableLines => this.files.SafeSum(f => f.CoverableLines);
 128
 129    /// <summary>
 130    /// Gets the number of total lines.
 131    /// </summary>
 132    /// <value>The total lines.</value>
 576133    public int? TotalLines => this.files.SafeSum(f => f.TotalLines);
 134
 135    /// <summary>
 136    /// Gets the coverage quota of the class.
 137    /// </summary>
 138    /// <value>The coverage quota.</value>
 139    public decimal? CoverageQuota
 140    {
 141        get
 417142        {
 417143            return (this.CoverableLines == 0) ? (decimal?)null : MathExtensions.CalculatePercentage(this.CoveredLines, t
 417144        }
 145    }
 146
 147    /// <summary>
 148    /// Gets the number of covered branches.
 149    /// </summary>
 150    /// <value>
 151    /// The number of covered branches.
 152    /// </value>
 2340153    public int? CoveredBranches => this.files.SafeSum(f => f.CoveredBranches);
 154
 155    /// <summary>
 156    /// Gets the number of total branches.
 157    /// </summary>
 158    /// <value>
 159    /// The number of total branches.
 160    /// </value>
 3996161    public int? TotalBranches => this.files.SafeSum(f => f.TotalBranches);
 162
 163    /// <summary>
 164    /// Gets the branch coverage quota of the class.
 165    /// </summary>
 166    /// <value>The branch coverage quota.</value>
 320167    public decimal? BranchCoverageQuota => (this.TotalBranches == 0) ? (decimal?)null : MathExtensions.CalculatePercenta
 168
 169    /// <summary>
 170    /// Gets the number of covered code elements.
 171    /// </summary>
 172    /// <value>
 173    /// The number of covered code elements.
 174    /// </value>
 640175    public int CoveredCodeElements => this.files.SafeSum(f => f.CoveredCodeElements);
 176
 177    /// <summary>
 178    /// Gets the number of fully covered code elements.
 179    /// </summary>
 180    /// <value>
 181    /// The number of fully covered code elements.
 182    /// </value>
 640183    public int FullCoveredCodeElements => this.files.SafeSum(f => f.FullCoveredCodeElements);
 184
 185    /// <summary>
 186    /// Gets the number of total code elements.
 187    /// </summary>
 188    /// <value>
 189    /// The number of total code elements.
 190    /// </value>
 1920191    public int TotalCodeElements => this.files.SafeSum(f => f.TotalCodeElements);
 192
 193    /// <summary>
 194    /// Gets the code elements coverage quota.
 195    /// </summary>
 196    /// <value>The code elements coverage quota.</value>
 68197    public decimal? CodeElementCoverageQuota => (this.TotalCodeElements == 0) ? (decimal?)null : MathExtensions.Calculat
 198
 199    /// <summary>
 200    /// Gets the full code elements coverage quota.
 201    /// </summary>
 202    /// <value>The full code elements coverage quota.</value>
 68203    public decimal? FullCodeElementCoverageQuota => (this.TotalCodeElements == 0) ? (decimal?)null : MathExtensions.Calc
 204
 205    /// <summary>
 206    /// Returns a <see cref="string" /> that represents this instance.
 207    /// </summary>
 208    /// <returns>
 209    /// A <see cref="string" /> that represents this instance.
 210    /// </returns>
 211    public override string ToString()
 0212    {
 0213        return this.Name;
 0214    }
 215
 216    /// <summary>
 217    /// Determines whether the specified <see cref="object"/> is equal to this instance.
 218    /// </summary>
 219    /// <param name="obj">The <see cref="object"/> to compare with this instance.</param>
 220    /// <returns>
 221    ///   <c>true</c> if the specified <see cref="object"/> is equal to this instance; otherwise, <c>false</c>.
 222    /// </returns>
 223    public override bool Equals(object obj)
 3229224    {
 3229225        if (obj == null || !obj.GetType().Equals(typeof(Class)))
 2226        {
 2227            return false;
 228        }
 229        else
 3227230        {
 3227231            var @class = (Class)obj;
 3227232            return @class.RawName.Equals(this.RawName) && @class.Assembly.Equals(this.Assembly);
 233        }
 3229234    }
 235
 236    /// <summary>
 237    /// Returns a hash code for this instance.
 238    /// </summary>
 239    /// <returns>
 240    /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.
 241    /// </returns>
 0242    public override int GetHashCode() => this.Name.GetHashCode();
 243
 244    /// <summary>
 245    /// Adds the given file.
 246    /// </summary>
 247    /// <param name="codeFile">The code file.</param>
 248    internal void AddFile(CodeFile codeFile)
 1525249    {
 1525250        this.files.Add(codeFile);
 1525251    }
 252
 253    /// <summary>
 254    /// Merges the given class with the current instance.
 255    /// </summary>
 256    /// <param name="class">The class to merge.</param>
 257    internal void Merge(Class @class)
 370258    {
 370259        if (@class == null)
 0260        {
 0261            throw new ArgumentNullException(nameof(@class));
 262        }
 263
 1878264        foreach (var file in @class.files)
 384265        {
 811266            var existingFile = this.files.FirstOrDefault(f => f.Equals(file));
 384267            if (existingFile != null)
 384268            {
 384269                existingFile.Merge(file);
 384270            }
 271            else
 0272            {
 0273                this.AddFile(file);
 0274            }
 384275        }
 370276    }
 277}