< Summary

Information
Class: NexusLabs.Needlr.Generators.Models.GeneratedConstructorModel
Assembly: NexusLabs.Needlr.Generators
File(s): /_work/nick-alienware-needlr-1-1784953859-3e8997/needlr/needlr/src/NexusLabs.Needlr.Generators/Models/Constructors/GeneratedConstructorModel.cs
Line coverage
66%
Covered lines: 26
Uncovered lines: 13
Coverable lines: 39
Total lines: 129
Line coverage: 66.6%
Branch coverage
40%
Covered branches: 9
Total branches: 22
Branch coverage: 40.9%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
get_ContainingNamespace()100%11100%
get_ContainingTypeName()100%11100%
get_TypeParameterList()100%11100%
get_Arity()100%11100%
get_NullGuardMode()100%11100%
get_Fields()100%11100%
get_SourceFilePath()100%11100%
Equals(...)50%1212100%
Equals(...)0%620%
GetHashCode()0%2040%
op_Equality(...)100%210%
op_Inequality(...)100%210%
FieldsEqual(...)75%4480%

File(s)

/_work/nick-alienware-needlr-1-1784953859-3e8997/needlr/needlr/src/NexusLabs.Needlr.Generators/Models/Constructors/GeneratedConstructorModel.cs

#LineLine coverage
 1using System;
 2using System.Linq;
 3
 4namespace NexusLabs.Needlr.Generators.Models;
 5
 6/// <summary>
 7/// The complete shared model describing a generated constructor for a single partial
 8/// class. Consumed by both source emission and Needlr's type-registry constructor
 9/// discovery so both agree on the effective constructor shape.
 10/// </summary>
 11/// <remarks>
 12/// Implements value equality (rather than the default struct member-by-member
 13/// reflection-based comparison) â€” in particular <see cref="Fields"/> is compared
 14/// element-by-element rather than by array reference â€” so that the incremental
 15/// generator pipeline can cache this model across unrelated edits: an edit to one
 16/// type's fields must not force every other eligible type's model to be considered
 17/// "changed" just because a new (but equal) model instance was rebuilt for it.
 18/// </remarks>
 19internal readonly struct GeneratedConstructorModel : IEquatable<GeneratedConstructorModel>
 20{
 21    public GeneratedConstructorModel(
 22        string containingNamespace,
 23        string containingTypeName,
 24        string typeParameterList,
 25        int arity,
 26        GeneratedConstructorNullGuardMode nullGuardMode,
 27        EligibleConstructorField[] fields,
 28        string? sourceFilePath)
 29    {
 11330        ContainingNamespace = containingNamespace;
 11331        ContainingTypeName = containingTypeName;
 11332        TypeParameterList = typeParameterList;
 11333        Arity = arity;
 11334        NullGuardMode = nullGuardMode;
 11335        Fields = fields;
 11336        SourceFilePath = sourceFilePath;
 11337    }
 38
 39    /// <summary>
 40    /// The containing namespace, or an empty string for the global namespace.
 41    /// </summary>
 29842    public string ContainingNamespace { get; }
 43
 44    /// <summary>
 45    /// The simple containing type name, without namespace or type parameters.
 46    /// </summary>
 36447    public string ContainingTypeName { get; }
 48
 49    /// <summary>
 50    /// The type parameter list syntax (e.g. <c>&lt;T&gt;</c>), or an empty string for
 51    /// non-generic types.
 52    /// </summary>
 23253    public string TypeParameterList { get; }
 54
 55    /// <summary>
 56    /// The type's generic arity (number of type parameters). Used, alongside
 57    /// <see cref="ContainingNamespace"/> and <see cref="ContainingTypeName"/>, as a
 58    /// deterministic hint-name discriminator so that two distinct types sharing the
 59    /// same namespace and name but different arity (e.g. <c>Foo</c> and
 60    /// <c>Foo&lt;T&gt;</c>) never collide on the same generated file name â€” the same
 61    /// discriminator the CLR itself uses to distinguish same-named generic arities
 62    /// within a namespace.
 63    /// </summary>
 10064    public int Arity { get; }
 65
 66    /// <summary>
 67    /// The class-level null-guard mode in effect for this constructor.
 68    /// </summary>
 10969    public GeneratedConstructorNullGuardMode NullGuardMode { get; }
 70
 71    /// <summary>
 72    /// Eligible fields, in deterministic declaration order, that become constructor
 73    /// parameters.
 74    /// </summary>
 69775    public EligibleConstructorField[] Fields { get; }
 76
 77    /// <summary>
 78    /// The source file path of the containing type declaration, used for breadcrumbs.
 79    /// </summary>
 3480    public string? SourceFilePath { get; }
 81
 82    public bool Equals(GeneratedConstructorModel other)
 83    {
 1784        return string.Equals(ContainingNamespace, other.ContainingNamespace, StringComparison.Ordinal) &&
 1785            string.Equals(ContainingTypeName, other.ContainingTypeName, StringComparison.Ordinal) &&
 1786            string.Equals(TypeParameterList, other.TypeParameterList, StringComparison.Ordinal) &&
 1787            Arity == other.Arity &&
 1788            NullGuardMode == other.NullGuardMode &&
 1789            string.Equals(SourceFilePath, other.SourceFilePath, StringComparison.Ordinal) &&
 1790            FieldsEqual(Fields, other.Fields);
 91    }
 92
 093    public override bool Equals(object? obj) => obj is GeneratedConstructorModel other && Equals(other);
 94
 95    public override int GetHashCode()
 96    {
 97        unchecked
 98        {
 099            var hash = ContainingNamespace.GetHashCode();
 0100            hash = (hash * 397) ^ ContainingTypeName.GetHashCode();
 0101            hash = (hash * 397) ^ TypeParameterList.GetHashCode();
 0102            hash = (hash * 397) ^ Arity;
 0103            hash = (hash * 397) ^ (int)NullGuardMode;
 0104            hash = (hash * 397) ^ (SourceFilePath?.GetHashCode() ?? 0);
 105
 0106            foreach (var field in Fields)
 107            {
 0108                hash = (hash * 397) ^ field.GetHashCode();
 109            }
 110
 0111            return hash;
 112        }
 113    }
 114
 0115    public static bool operator ==(GeneratedConstructorModel left, GeneratedConstructorModel right) => left.Equals(right
 116
 0117    public static bool operator !=(GeneratedConstructorModel left, GeneratedConstructorModel right) => !left.Equals(righ
 118
 119    private static bool FieldsEqual(EligibleConstructorField[] left, EligibleConstructorField[] right)
 120    {
 17121        if (ReferenceEquals(left, right))
 8122            return true;
 123
 9124        if (left.Length != right.Length)
 0125            return false;
 126
 9127        return left.SequenceEqual(right);
 128    }
 129}