< Summary

Information
Class: NexusLabs.Needlr.Generators.CodeGen.RecordConstructorOverloadCodeGenerator
Assembly: NexusLabs.Needlr.Generators
File(s): /home/runner/work/needlr/needlr/src/NexusLabs.Needlr.Generators/CodeGen/RecordConstructorOverloadCodeGenerator.cs
Line coverage
100%
Covered lines: 70
Uncovered lines: 0
Coverable lines: 70
Total lines: 132
Line coverage: 100%
Branch coverage
94%
Covered branches: 17
Total branches: 18
Branch coverage: 94.4%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
BuildHintName(...)50%22100%
GenerateSource(...)100%1414100%
ToCrefTypeParameterList(...)100%22100%

File(s)

/home/runner/work/needlr/needlr/src/NexusLabs.Needlr.Generators/CodeGen/RecordConstructorOverloadCodeGenerator.cs

#LineLine coverage
 1using System.Linq;
 2using System.Text;
 3
 4using NexusLabs.Needlr.Generators.Models;
 5
 6namespace NexusLabs.Needlr.Generators.CodeGen;
 7
 8/// <summary>
 9/// Emits one public forwarding constructor overload for a positional record model.
 10/// </summary>
 11internal static class RecordConstructorOverloadCodeGenerator
 12{
 13    private const string GeneratedFileSuffix =
 14        ".RecordConstructorOverload.g.cs";
 15
 16    /// <summary>
 17    /// Builds the deterministic generated-source hint name.
 18    /// </summary>
 19    internal static string BuildHintName(RecordConstructorOverloadModel model)
 20    {
 5221        var baseName = model.ContainingNamespace.Length > 0
 5222            ? $"{model.ContainingNamespace}.{model.ContainingTypeName}"
 5223            : model.ContainingTypeName;
 5224        return $"{GeneratorHelpers.SanitizeIdentifier(baseName)}_T{GeneratorHelpers.Literal(model.Arity)}{GeneratedFileS
 25    }
 26
 27    /// <summary>
 28    /// Emits the complete partial record declaration and forwarding constructor.
 29    /// </summary>
 30    internal static string GenerateSource(
 31        RecordConstructorOverloadModel model,
 32        string assemblyName,
 33        BreadcrumbWriter breadcrumbs)
 34    {
 5235        var builder = new StringBuilder();
 36
 5237        breadcrumbs.WriteFileHeader(
 5238            builder,
 5239            assemblyName,
 5240            $"Generated record constructor overload for {model.ContainingTypeName}{model.TypeParameterList}");
 5241        builder.AppendLine("#nullable enable");
 5242        builder.AppendLine();
 43
 5244        if (model.ContainingNamespace.Length > 0)
 45        {
 5246            builder.AppendLine($"namespace {model.ContainingNamespace};");
 5247            builder.AppendLine();
 48        }
 49
 5250        breadcrumbs.WriteInlineComment(
 5251            builder,
 5252            string.Empty,
 5253            $"Constructor overload generated from {GeneratorHelpers.Literal(model.PropertyParameters.Length)} marked pro
 5254        builder.AppendLine(
 5255            $"partial record class {model.EscapedContainingTypeName}{model.TypeParameterList}");
 5256        builder.AppendLine("{");
 5257        builder.AppendLine("    /// <summary>");
 5258        builder.AppendLine(
 5259            $"    /// Initializes a new instance of the <see cref=\"{model.EscapedContainingTypeName}{ToCrefTypeParamete
 5260        builder.AppendLine("    /// </summary>");
 61
 23262        foreach (var parameter in model.PrimaryParameters)
 63        {
 6464            builder.AppendLine(
 6465                $"    /// <param name=\"{parameter.Name}\">{parameter.Documentation}</param>");
 66        }
 67
 22868        foreach (var parameter in model.PropertyParameters)
 69        {
 6270            builder.AppendLine(
 6271                $"    /// <param name=\"{parameter.PropertyName}\">{parameter.Documentation}</param>");
 72        }
 73
 5274        ConstructorGuardCodeGenerator.WriteExceptionDocumentation(
 5275            builder,
 5276            model.PropertyParameters
 6277                .Select(parameter => parameter.PropertyName)
 5278                .ToArray(),
 5279            model.PropertyParameters
 6280                .Select(parameter => parameter.EffectiveGuards)
 5281                .ToArray(),
 5282            "    ");
 83
 5284        var parameters = model.PrimaryParameters
 5285            .Select(parameter =>
 6486                $"{parameter.TypeName} {parameter.EscapedName}")
 5287            .Concat(model.PropertyParameters.Select(parameter =>
 11488                $"{parameter.TypeName} {parameter.EscapedPropertyName}"));
 5289        builder.AppendLine(
 5290            $"    public {model.EscapedContainingTypeName}({string.Join(", ", parameters)})");
 91
 5292        var forwardedArguments = string.Join(
 5293            ", ",
 5294            model.PrimaryParameters.Select(parameter =>
 11695                parameter.EscapedName));
 5296        builder.AppendLine($"        : this({forwardedArguments})");
 5297        builder.AppendLine("    {");
 98
 5299        var emittedGuard = false;
 228100        foreach (var parameter in model.PropertyParameters)
 101        {
 150102            foreach (var guard in parameter.EffectiveGuards)
 103            {
 13104                builder.AppendLine(
 13105                    $"        {ConstructorGuardCodeGenerator.BuildGuardCall(guard, parameter.EscapedPropertyName)}");
 13106                emittedGuard = true;
 107            }
 108        }
 109
 52110        if (emittedGuard)
 11111            builder.AppendLine();
 112
 228113        foreach (var parameter in model.PropertyParameters)
 114        {
 62115            builder.AppendLine(
 62116                $"        this.{parameter.EscapedPropertyName} = {parameter.EscapedPropertyName};");
 117        }
 118
 52119        builder.AppendLine("    }");
 52120        builder.AppendLine("}");
 121
 52122        return builder.ToString();
 123    }
 124
 125    private static string ToCrefTypeParameterList(string typeParameterList)
 126    {
 52127        if (typeParameterList.Length == 0)
 48128            return string.Empty;
 129
 4130        return typeParameterList.Replace('<', '{').Replace('>', '}');
 131    }
 132}