< Summary

Information
Class: NexusLabs.Needlr.Generators.CodeGen.BootstrapCodeGenerator
Assembly: NexusLabs.Needlr.Generators
File(s): /home/runner/work/needlr/needlr/src/NexusLabs.Needlr.Generators/CodeGen/BootstrapCodeGenerator.cs
Line coverage
100%
Covered lines: 61
Uncovered lines: 0
Coverable lines: 61
Total lines: 121
Line coverage: 100%
Branch coverage
100%
Covered branches: 16
Total branches: 16
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
GenerateModuleInitializerBootstrapSource(...)100%1616100%

File(s)

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

#LineLine coverage
 1// Copyright (c) NexusLabs. All rights reserved.
 2// Licensed under the MIT License.
 3
 4using System.Collections.Generic;
 5using System.Text;
 6
 7namespace NexusLabs.Needlr.Generators.CodeGen;
 8
 9/// <summary>
 10/// Generates the <c>NeedlrSourceGenBootstrap.g.cs</c> module initializer file.
 11/// </summary>
 12internal static class BootstrapCodeGenerator
 13{
 14    /// <summary>
 15    /// Emits the module-initializer bootstrap source that registers TypeRegistry
 16    /// identity and callbacks and runs referenced TypeRegistry module constructors.
 17    /// </summary>
 18    internal static string GenerateModuleInitializerBootstrapSource(string assemblyName, IReadOnlyList<string> reference
 19    {
 59120        var builder = new StringBuilder();
 59121        var safeAssemblyName = GeneratorHelpers.SanitizeIdentifier(assemblyName);
 22
 59123        breadcrumbs.WriteFileHeader(builder, assemblyName, "Needlr Source-Gen Bootstrap");
 59124        builder.AppendLine("#nullable enable");
 59125        builder.AppendLine();
 59126        builder.AppendLine("using Microsoft.Extensions.Configuration;");
 59127        builder.AppendLine("using Microsoft.Extensions.DependencyInjection;");
 59128        builder.AppendLine();
 59129        builder.AppendLine($"namespace {safeAssemblyName}.Generated;");
 59130        builder.AppendLine();
 59131        builder.AppendLine("internal static class NeedlrSourceGenModuleInitializer");
 59132        builder.AppendLine("{");
 59133        builder.AppendLine("    [global::System.Runtime.CompilerServices.ModuleInitializer]");
 59134        builder.AppendLine("    internal static void Initialize()");
 59135        builder.AppendLine("    {");
 36
 37        // Generate the referenced-module initialization call when dependencies have registries.
 59138        if (referencedAssemblies.Count > 0)
 39        {
 1940            builder.AppendLine("        // Run referenced module constructors so their registries register");
 1941            builder.AppendLine("        ForceLoadReferencedAssemblies();");
 1942            builder.AppendLine();
 43        }
 44
 59145        builder.AppendLine("        global::NexusLabs.Needlr.Generators.NeedlrSourceGenBootstrap.Register(");
 59146        builder.AppendLine($"            typeof(global::{safeAssemblyName}.Generated.TypeRegistry),");
 59147        builder.AppendLine($"            global::{safeAssemblyName}.Generated.TypeRegistry.GetInjectableTypes,");
 59148        builder.AppendLine($"            global::{safeAssemblyName}.Generated.TypeRegistry.GetPluginTypes,");
 49
 50        // Generate the decorator/factory/provider applier lambda
 59151        if (hasFactories || hasProviders)
 52        {
 5753            builder.AppendLine("            services =>");
 5754            builder.AppendLine("            {");
 5755            builder.AppendLine($"                global::{safeAssemblyName}.Generated.TypeRegistry.ApplyDecorators((ISer
 5756            if (hasFactories)
 57            {
 3958                builder.AppendLine($"                global::{safeAssemblyName}.Generated.FactoryRegistrations.RegisterF
 59            }
 5760            if (hasProviders)
 61            {
 1862                builder.AppendLine($"                global::{safeAssemblyName}.Generated.TypeRegistry.RegisterProviders
 63            }
 5764            builder.AppendLine("            },");
 65        }
 66        else
 67        {
 53468            builder.AppendLine($"            services => global::{safeAssemblyName}.Generated.TypeRegistry.ApplyDecorato
 69        }
 70
 71        // Generate the options registrar lambda for NeedlrSourceGenBootstrap (for backward compat)
 59172        if (hasOptions)
 73        {
 16274            builder.AppendLine($"            (services, config) => global::{safeAssemblyName}.Generated.TypeRegistry.Reg
 75        }
 76        else
 77        {
 42978            builder.AppendLine("            null);");
 79        }
 80
 81        // Also register with SourceGenRegistry (for ConfiguredSyringe without Generators.Attributes dependency)
 59182        if (hasOptions)
 83        {
 16284            builder.AppendLine();
 16285            builder.AppendLine("        // Register options with core SourceGenRegistry for ConfiguredSyringe");
 16286            builder.AppendLine($"        global::NexusLabs.Needlr.SourceGenRegistry.RegisterOptionsRegistrar(");
 16287            builder.AppendLine($"            (services, config) => global::{safeAssemblyName}.Generated.TypeRegistry.Reg
 88        }
 89
 59190        builder.AppendLine("    }");
 91
 92        // Generate ForceLoadReferencedAssemblies method if needed
 59193        if (referencedAssemblies.Count > 0)
 94        {
 1995            builder.AppendLine();
 1996            builder.AppendLine("    /// <summary>");
 1997            builder.AppendLine("    /// Runs module constructors for referenced assemblies with");
 1998            builder.AppendLine("    /// [GenerateTypeRegistry], ensuring their registries register.");
 1999            builder.AppendLine("    /// </summary>");
 19100            builder.AppendLine("    /// <remarks>");
 19101            builder.AppendLine("    /// A typeof expression alone does not guarantee module initialization.");
 19102            builder.AppendLine("    /// RunModuleConstructor is idempotent when a dependency was already initialized.");
 19103            builder.AppendLine("    /// </remarks>");
 19104            builder.AppendLine("    private static void ForceLoadReferencedAssemblies()");
 19105            builder.AppendLine("    {");
 106
 78107            foreach (var referencedAssembly in referencedAssemblies)
 108            {
 20109                var safeRefAssemblyName = GeneratorHelpers.SanitizeIdentifier(referencedAssembly);
 20110                builder.AppendLine("        global::System.Runtime.CompilerServices.RuntimeHelpers.RunModuleConstructor(
 20111                builder.AppendLine($"            typeof(global::{safeRefAssemblyName}.Generated.TypeRegistry).Module.Mod
 112            }
 113
 19114            builder.AppendLine("    }");
 115        }
 116
 591117        builder.AppendLine("}");
 118
 591119        return builder.ToString();
 120    }
 121}