< 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: 48
Uncovered lines: 0
Coverable lines: 48
Total lines: 106
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
 6using NexusLabs.Needlr.Generators.Models;
 7
 8namespace NexusLabs.Needlr.Generators.CodeGen;
 9
 10/// <summary>
 11/// Emits a minimal <c>TypeRegistry</c> and module-initializer bootstrap for an assembly that
 12/// declares <c>[GenerateTypeRegistry]</c> but has nothing to register.
 13/// </summary>
 14/// <remarks>
 15/// The emitted code depends only on the attributes package (<c>InjectableTypeInfo</c>,
 16/// <c>PluginTypeInfo</c>, and <c>NeedlrSourceGenBootstrap</c>) — never on the injection packages.
 17/// A project must reference the attributes package to use <c>[GenerateTypeRegistry]</c> at all, so
 18/// this registry always compiles, even for a project that references no Needlr injection packages
 19/// (a documentation, contracts, or abstractions library). Emitting it keeps a type-less participant
 20/// force-loadable by consumers (<c>typeof(&lt;Assembly&gt;.Generated.TypeRegistry)</c>) without the
 21/// <c>CS0234</c> failure that omitting it would cause.
 22/// </remarks>
 23internal static class EmptyTypeRegistryCodeGenerator
 24{
 25    /// <summary>
 26    /// Emits the empty <c>TypeRegistry</c> exposing empty injectable and plugin providers.
 27    /// </summary>
 28    /// <param name="registrationPlan">The normalized registration plan for the assembly.</param>
 29    /// <param name="breadcrumbs">The breadcrumb writer supplied by the orchestration method.</param>
 30    /// <returns>The generated C# source for the empty <c>TypeRegistry</c>.</returns>
 31    internal static string GenerateTypeRegistrySource(
 32        GeneratedRegistrationPlan registrationPlan,
 33        BreadcrumbWriter breadcrumbs)
 34    {
 1035        var builder = new StringBuilder();
 1036        var assemblyName = registrationPlan.AssemblyName;
 1037        var safeAssemblyName = GeneratorHelpers.SanitizeIdentifier(assemblyName);
 38
 1039        breadcrumbs.WriteFileHeader(builder, assemblyName, "Needlr Type Registry (empty)");
 1040        builder.AppendLine("#nullable enable");
 1041        builder.AppendLine();
 1042        builder.AppendLine($"namespace {safeAssemblyName}.Generated;");
 1043        builder.AppendLine();
 1044        builder.AppendLine("/// <summary>");
 1045        builder.AppendLine("/// Compile-time generated registry for an assembly that declares [GenerateTypeRegistry]");
 1046        builder.AppendLine("/// but contains no registerable types. Exposes empty providers so that consumers which");
 1047        builder.AppendLine("/// force-load this type compile, without depending on the Needlr injection packages.");
 1048        builder.AppendLine("/// </summary>");
 1049        builder.AppendLine("[global::System.CodeDom.Compiler.GeneratedCodeAttribute(\"NexusLabs.Needlr.Generators\", \"1
 1050        builder.AppendLine("public static class TypeRegistry");
 1051        builder.AppendLine("{");
 1052        builder.AppendLine("    private static readonly global::NexusLabs.Needlr.Generators.InjectableTypeInfo[] _types 
 1053        builder.AppendLine("    private static readonly global::NexusLabs.Needlr.Generators.PluginTypeInfo[] _plugins = 
 1054        builder.AppendLine();
 1055        builder.AppendLine("    /// <summary>Gets all injectable types discovered at compile time (none).</summary>");
 1056        builder.AppendLine("    /// <returns>An empty read-only list.</returns>");
 1057        builder.AppendLine("    public static global::System.Collections.Generic.IReadOnlyList<global::NexusLabs.Needlr.
 1058        builder.AppendLine();
 1059        builder.AppendLine("    /// <summary>Gets all plugin types discovered at compile time (none).</summary>");
 1060        builder.AppendLine("    /// <returns>An empty read-only list.</returns>");
 1061        builder.AppendLine("    public static global::System.Collections.Generic.IReadOnlyList<global::NexusLabs.Needlr.
 1062        builder.AppendLine("}");
 63
 1064        return builder.ToString();
 65    }
 66
 67    /// <summary>
 68    /// Emits the module-initializer bootstrap that registers the empty providers with
 69    /// <c>NeedlrSourceGenBootstrap</c>.
 70    /// </summary>
 71    /// <param name="registrationPlan">The normalized registration plan for the assembly.</param>
 72    /// <param name="breadcrumbs">The breadcrumb writer supplied by the orchestration method.</param>
 73    /// <returns>The generated C# source for the module-initializer bootstrap.</returns>
 74    /// <remarks>
 75    /// Uses the registry-identity <c>Register</c> overload (no decorator applier, no options registrar),
 76    /// which takes no <c>IServiceCollection</c>/<c>IConfiguration</c> parameters and therefore keeps
 77    /// the emitted code free of any Microsoft.Extensions.DependencyInjection dependency.
 78    /// </remarks>
 79    internal static string GenerateBootstrapSource(
 80        GeneratedRegistrationPlan registrationPlan,
 81        BreadcrumbWriter breadcrumbs)
 82    {
 1083        var builder = new StringBuilder();
 1084        var assemblyName = registrationPlan.AssemblyName;
 1085        var safeAssemblyName = GeneratorHelpers.SanitizeIdentifier(assemblyName);
 86
 1087        breadcrumbs.WriteFileHeader(builder, assemblyName, "Needlr Source-Gen Bootstrap (empty)");
 1088        builder.AppendLine("#nullable enable");
 1089        builder.AppendLine();
 1090        builder.AppendLine($"namespace {safeAssemblyName}.Generated;");
 1091        builder.AppendLine();
 1092        builder.AppendLine("internal static class NeedlrSourceGenModuleInitializer");
 1093        builder.AppendLine("{");
 1094        builder.AppendLine("    [global::System.Runtime.CompilerServices.ModuleInitializer]");
 1095        builder.AppendLine("    internal static void Initialize()");
 1096        builder.AppendLine("    {");
 1097        builder.AppendLine("        global::NexusLabs.Needlr.Generators.NeedlrSourceGenBootstrap.Register(");
 1098        builder.AppendLine($"            typeof(global::{safeAssemblyName}.Generated.TypeRegistry),");
 1099        builder.AppendLine($"            global::{safeAssemblyName}.Generated.TypeRegistry.GetInjectableTypes,");
 10100        builder.AppendLine($"            global::{safeAssemblyName}.Generated.TypeRegistry.GetPluginTypes);");
 10101        builder.AppendLine("    }");
 10102        builder.AppendLine("}");
 103
 10104        return builder.ToString();
 105    }
 106}