< Summary

Information
Class: NexusLabs.Needlr.Generators.Models.EligibleConstructorField
Assembly: NexusLabs.Needlr.Generators
File(s): /home/runner/work/needlr/needlr/src/NexusLabs.Needlr.Generators/Models/Constructors/EligibleConstructorField.cs
Line coverage
100%
Covered lines: 31
Uncovered lines: 0
Coverable lines: 31
Total lines: 103
Line coverage: 100%
Branch coverage
93%
Covered branches: 15
Total branches: 16
Branch coverage: 93.7%
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_FieldName()100%11100%
get_ParameterName()100%11100%
get_ParameterTypeName()100%11100%
get_IsNonNullableReferenceType()100%11100%
get_ExplicitGuards()100%11100%
Equals(...)100%88100%
Equals(...)50%22100%
GetHashCode()100%22100%
op_Equality(...)100%11100%
op_Inequality(...)100%11100%
GuardsEqual(...)100%44100%

File(s)

/home/runner/work/needlr/needlr/src/NexusLabs.Needlr.Generators/Models/Constructors/EligibleConstructorField.cs

#LineLine coverage
 1using System;
 2using System.Linq;
 3
 4namespace NexusLabs.Needlr.Generators.Models;
 5
 6/// <summary>
 7/// A single field eligible to become a generated constructor parameter.
 8/// </summary>
 9/// <remarks>
 10/// Implements value equality (rather than the default struct member-by-member
 11/// reflection-based comparison) — in particular <see cref="ExplicitGuards"/> is
 12/// compared element-by-element rather than by array reference — so that
 13/// <see cref="GeneratedConstructorModel"/> stays cacheable across incremental
 14/// generator runs: two separately-built field lists with the same effective content
 15/// must compare equal even though they are different array instances.
 16/// </remarks>
 17internal readonly struct EligibleConstructorField : IEquatable<EligibleConstructorField>
 18{
 19    public EligibleConstructorField(
 20        string fieldName,
 21        string parameterName,
 22        string parameterTypeName,
 23        bool isNonNullableReferenceType,
 24        ConstructorGuardModel[] explicitGuards)
 25    {
 20326        FieldName = fieldName;
 20327        ParameterName = parameterName;
 20328        ParameterTypeName = parameterTypeName;
 20329        IsNonNullableReferenceType = isNonNullableReferenceType;
 20330        ExplicitGuards = explicitGuards;
 20331    }
 32
 33    /// <summary>
 34    /// The original field name, e.g. <c>_repository</c>.
 35    /// </summary>
 31636    public string FieldName { get; }
 37
 38    /// <summary>
 39    /// The normalized constructor parameter name, e.g. <c>repository</c>.
 40    /// </summary>
 57441    public string ParameterName { get; }
 42
 43    /// <summary>
 44    /// The fully qualified parameter type name, preserving nullable-reference and
 45    /// generic type syntax.
 46    /// </summary>
 24147    public string ParameterTypeName { get; }
 48
 49    /// <summary>
 50    /// True when the field's type is a reference type with no nullable annotation,
 51    /// making it eligible for the class-level automatic null-guard default.
 52    /// </summary>
 10153    public bool IsNonNullableReferenceType { get; }
 54
 55    /// <summary>
 56    /// Explicit guards requested for this field, in source declaration order.
 57    /// </summary>
 17758    public ConstructorGuardModel[] ExplicitGuards { get; }
 59
 60    public bool Equals(EligibleConstructorField other)
 61    {
 5562        return string.Equals(FieldName, other.FieldName, StringComparison.Ordinal) &&
 5563            string.Equals(ParameterName, other.ParameterName, StringComparison.Ordinal) &&
 5564            string.Equals(ParameterTypeName, other.ParameterTypeName, StringComparison.Ordinal) &&
 5565            IsNonNullableReferenceType == other.IsNonNullableReferenceType &&
 5566            GuardsEqual(ExplicitGuards, other.ExplicitGuards);
 67    }
 68
 269    public override bool Equals(object? obj) => obj is EligibleConstructorField other && Equals(other);
 70
 71    public override int GetHashCode()
 72    {
 73        unchecked
 74        {
 875            var hash = FieldName.GetHashCode();
 876            hash = (hash * 397) ^ ParameterName.GetHashCode();
 877            hash = (hash * 397) ^ ParameterTypeName.GetHashCode();
 878            hash = (hash * 397) ^ IsNonNullableReferenceType.GetHashCode();
 79
 3280            foreach (var guard in ExplicitGuards)
 81            {
 882                hash = (hash * 397) ^ guard.GetHashCode();
 83            }
 84
 885            return hash;
 86        }
 87    }
 88
 189    public static bool operator ==(EligibleConstructorField left, EligibleConstructorField right) => left.Equals(right);
 90
 191    public static bool operator !=(EligibleConstructorField left, EligibleConstructorField right) => !left.Equals(right)
 92
 93    private static bool GuardsEqual(ConstructorGuardModel[] left, ConstructorGuardModel[] right)
 94    {
 3595        if (ReferenceEquals(left, right))
 1096            return true;
 97
 2598        if (left.Length != right.Length)
 399            return false;
 100
 22101        return left.SequenceEqual(right);
 102    }
 103}