< 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: 46
Uncovered lines: 0
Coverable lines: 46
Total lines: 98
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    {
 931        var builder = new StringBuilder();
 932        var safeAssemblyName = GeneratorHelpers.SanitizeIdentifier(assemblyName);
 33
 934        breadcrumbs.WriteFileHeader(builder, assemblyName, "Needlr Type Registry (empty)");
 935        builder.AppendLine("#nullable enable");
 936        builder.AppendLine();
 937        builder.AppendLine($"namespace {safeAssemblyName}.Generated;");
 938        builder.AppendLine();
 939        builder.AppendLine("/// <summary>");
 940        builder.AppendLine("/// Compile-time generated registry for an assembly that declares [GenerateTypeRegistry]");
 941        builder.AppendLine("/// but contains no registerable types. Exposes empty providers so that consumers which");
 942        builder.AppendLine("/// force-load this type compile, without depending on the Needlr injection packages.");
 943        builder.AppendLine("/// </summary>");
 944        builder.AppendLine("[global::System.CodeDom.Compiler.GeneratedCodeAttribute(\"NexusLabs.Needlr.Generators\", \"1
 945        builder.AppendLine("public static class TypeRegistry");
 946        builder.AppendLine("{");
 947        builder.AppendLine("    private static readonly global::NexusLabs.Needlr.Generators.InjectableTypeInfo[] _types 
 948        builder.AppendLine("    private static readonly global::NexusLabs.Needlr.Generators.PluginTypeInfo[] _plugins = 
 949        builder.AppendLine();
 950        builder.AppendLine("    /// <summary>Gets all injectable types discovered at compile time (none).</summary>");
 951        builder.AppendLine("    /// <returns>An empty read-only list.</returns>");
 952        builder.AppendLine("    public static global::System.Collections.Generic.IReadOnlyList<global::NexusLabs.Needlr.
 953        builder.AppendLine();
 954        builder.AppendLine("    /// <summary>Gets all plugin types discovered at compile time (none).</summary>");
 955        builder.AppendLine("    /// <returns>An empty read-only list.</returns>");
 956        builder.AppendLine("    public static global::System.Collections.Generic.IReadOnlyList<global::NexusLabs.Needlr.
 957        builder.AppendLine("}");
 58
 959        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 registry-identity <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    {
 976        var builder = new StringBuilder();
 977        var safeAssemblyName = GeneratorHelpers.SanitizeIdentifier(assemblyName);
 78
 979        breadcrumbs.WriteFileHeader(builder, assemblyName, "Needlr Source-Gen Bootstrap (empty)");
 980        builder.AppendLine("#nullable enable");
 981        builder.AppendLine();
 982        builder.AppendLine($"namespace {safeAssemblyName}.Generated;");
 983        builder.AppendLine();
 984        builder.AppendLine("internal static class NeedlrSourceGenModuleInitializer");
 985        builder.AppendLine("{");
 986        builder.AppendLine("    [global::System.Runtime.CompilerServices.ModuleInitializer]");
 987        builder.AppendLine("    internal static void Initialize()");
 988        builder.AppendLine("    {");
 989        builder.AppendLine("        global::NexusLabs.Needlr.Generators.NeedlrSourceGenBootstrap.Register(");
 990        builder.AppendLine($"            typeof(global::{safeAssemblyName}.Generated.TypeRegistry),");
 991        builder.AppendLine($"            global::{safeAssemblyName}.Generated.TypeRegistry.GetInjectableTypes,");
 992        builder.AppendLine($"            global::{safeAssemblyName}.Generated.TypeRegistry.GetPluginTypes);");
 993        builder.AppendLine("    }");
 994        builder.AppendLine("}");
 95
 996        return builder.ToString();
 97    }
 98}