< Summary

Information
Class: NexusLabs.Needlr.Generators.CodeGen.EmptyTypeRegistryCodeGenerator
Assembly: NexusLabs.Needlr.Generators
File(s): /home/runner/work/needlr/needlr/src/NexusLabs.Needlr.Generators/CodeGen/EmptyTypeRegistryCodeGenerator.cs
Line coverage
100%
Covered lines: 45
Uncovered lines: 0
Coverable lines: 45
Total lines: 97
Line coverage: 100%
Branch coverage
N/A
Covered branches: 0
Total branches: 0
Branch coverage: N/A
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
GenerateTypeRegistrySource(...)100%11100%
GenerateBootstrapSource(...)100%11100%

File(s)

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

#LineLine coverage
 1// Copyright (c) NexusLabs. All rights reserved.
 2// Licensed under the MIT License.
 3
 4using System.Text;
 5
 6namespace NexusLabs.Needlr.Generators.CodeGen;
 7
 8/// <summary>
 9/// Emits a minimal <c>TypeRegistry</c> and module-initializer bootstrap for an assembly that
 10/// declares <c>[GenerateTypeRegistry]</c> but has nothing to register.
 11/// </summary>
 12/// <remarks>
 13/// The emitted code depends only on the attributes package (<c>InjectableTypeInfo</c>,
 14/// <c>PluginTypeInfo</c>, and <c>NeedlrSourceGenBootstrap</c>) — never on the injection packages.
 15/// A project must reference the attributes package to use <c>[GenerateTypeRegistry]</c> at all, so
 16/// this registry always compiles, even for a project that references no Needlr injection packages
 17/// (a documentation, contracts, or abstractions library). Emitting it keeps a type-less participant
 18/// force-loadable by consumers (<c>typeof(&lt;Assembly&gt;.Generated.TypeRegistry)</c>) without the
 19/// <c>CS0234</c> failure that omitting it would cause.
 20/// </remarks>
 21internal static class EmptyTypeRegistryCodeGenerator
 22{
 23    /// <summary>
 24    /// Emits the empty <c>TypeRegistry</c> exposing empty injectable and plugin providers.
 25    /// </summary>
 26    /// <param name="assemblyName">The assembly the registry is generated for.</param>
 27    /// <param name="breadcrumbs">The breadcrumb writer supplied by the orchestration method.</param>
 28    /// <returns>The generated C# source for the empty <c>TypeRegistry</c>.</returns>
 29    internal static string GenerateTypeRegistrySource(string assemblyName, BreadcrumbWriter breadcrumbs)
 30    {
 731        var builder = new StringBuilder();
 732        var safeAssemblyName = GeneratorHelpers.SanitizeIdentifier(assemblyName);
 33
 734        breadcrumbs.WriteFileHeader(builder, assemblyName, "Needlr Type Registry (empty)");
 735        builder.AppendLine("#nullable enable");
 736        builder.AppendLine();
 737        builder.AppendLine($"namespace {safeAssemblyName}.Generated;");
 738        builder.AppendLine();
 739        builder.AppendLine("/// <summary>");
 740        builder.AppendLine("/// Compile-time generated registry for an assembly that declares [GenerateTypeRegistry]");
 741        builder.AppendLine("/// but contains no registerable types. Exposes empty providers so that consumers which");
 742        builder.AppendLine("/// force-load this type compile, without depending on the Needlr injection packages.");
 743        builder.AppendLine("/// </summary>");
 744        builder.AppendLine("[global::System.CodeDom.Compiler.GeneratedCodeAttribute(\"NexusLabs.Needlr.Generators\", \"1
 745        builder.AppendLine("public static class TypeRegistry");
 746        builder.AppendLine("{");
 747        builder.AppendLine("    private static readonly global::NexusLabs.Needlr.Generators.InjectableTypeInfo[] _types 
 748        builder.AppendLine("    private static readonly global::NexusLabs.Needlr.Generators.PluginTypeInfo[] _plugins = 
 749        builder.AppendLine();
 750        builder.AppendLine("    /// <summary>Gets all injectable types discovered at compile time (none).</summary>");
 751        builder.AppendLine("    /// <returns>An empty read-only list.</returns>");
 752        builder.AppendLine("    public static global::System.Collections.Generic.IReadOnlyList<global::NexusLabs.Needlr.
 753        builder.AppendLine();
 754        builder.AppendLine("    /// <summary>Gets all plugin types discovered at compile time (none).</summary>");
 755        builder.AppendLine("    /// <returns>An empty read-only list.</returns>");
 756        builder.AppendLine("    public static global::System.Collections.Generic.IReadOnlyList<global::NexusLabs.Needlr.
 757        builder.AppendLine("}");
 58
 759        return builder.ToString();
 60    }
 61
 62    /// <summary>
 63    /// Emits the module-initializer bootstrap that registers the empty providers with
 64    /// <c>NeedlrSourceGenBootstrap</c>.
 65    /// </summary>
 66    /// <param name="assemblyName">The assembly the bootstrap is generated for.</param>
 67    /// <param name="breadcrumbs">The breadcrumb writer supplied by the orchestration method.</param>
 68    /// <returns>The generated C# source for the module-initializer bootstrap.</returns>
 69    /// <remarks>
 70    /// Uses the two-argument <c>Register</c> overload (no decorator applier, no options registrar),
 71    /// which takes no <c>IServiceCollection</c>/<c>IConfiguration</c> parameters and therefore keeps
 72    /// the emitted code free of any Microsoft.Extensions.DependencyInjection dependency.
 73    /// </remarks>
 74    internal static string GenerateBootstrapSource(string assemblyName, BreadcrumbWriter breadcrumbs)
 75    {
 776        var builder = new StringBuilder();
 777        var safeAssemblyName = GeneratorHelpers.SanitizeIdentifier(assemblyName);
 78
 779        breadcrumbs.WriteFileHeader(builder, assemblyName, "Needlr Source-Gen Bootstrap (empty)");
 780        builder.AppendLine("#nullable enable");
 781        builder.AppendLine();
 782        builder.AppendLine($"namespace {safeAssemblyName}.Generated;");
 783        builder.AppendLine();
 784        builder.AppendLine("internal static class NeedlrSourceGenModuleInitializer");
 785        builder.AppendLine("{");
 786        builder.AppendLine("    [global::System.Runtime.CompilerServices.ModuleInitializer]");
 787        builder.AppendLine("    internal static void Initialize()");
 788        builder.AppendLine("    {");
 789        builder.AppendLine("        global::NexusLabs.Needlr.Generators.NeedlrSourceGenBootstrap.Register(");
 790        builder.AppendLine($"            global::{safeAssemblyName}.Generated.TypeRegistry.GetInjectableTypes,");
 791        builder.AppendLine($"            global::{safeAssemblyName}.Generated.TypeRegistry.GetPluginTypes);");
 792        builder.AppendLine("    }");
 793        builder.AppendLine("}");
 94
 795        return builder.ToString();
 96    }
 97}