< 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: 62
Uncovered lines: 0
Coverable lines: 62
Total lines: 122
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    /// callbacks and force-loads referenced assemblies.
 17    /// </summary>
 18    internal static string GenerateModuleInitializerBootstrapSource(string assemblyName, IReadOnlyList<string> reference
 19    {
 45520        var builder = new StringBuilder();
 45521        var safeAssemblyName = GeneratorHelpers.SanitizeIdentifier(assemblyName);
 22
 45523        breadcrumbs.WriteFileHeader(builder, assemblyName, "Needlr Source-Gen Bootstrap");
 45524        builder.AppendLine("#nullable enable");
 45525        builder.AppendLine();
 45526        builder.AppendLine("using System.Runtime.CompilerServices;");
 45527        builder.AppendLine();
 45528        builder.AppendLine("using Microsoft.Extensions.Configuration;");
 45529        builder.AppendLine("using Microsoft.Extensions.DependencyInjection;");
 45530        builder.AppendLine();
 45531        builder.AppendLine($"namespace {safeAssemblyName}.Generated;");
 45532        builder.AppendLine();
 45533        builder.AppendLine("internal static class NeedlrSourceGenModuleInitializer");
 45534        builder.AppendLine("{");
 45535        builder.AppendLine("    [global::System.Runtime.CompilerServices.ModuleInitializer]");
 45536        builder.AppendLine("    internal static void Initialize()");
 45537        builder.AppendLine("    {");
 38
 39        // Generate ForceLoadAssemblies call if there are referenced assemblies with [GenerateTypeRegistry]
 45540        if (referencedAssemblies.Count > 0)
 41        {
 1742            builder.AppendLine("        // Force-load referenced assemblies to ensure their module initializers run");
 1743            builder.AppendLine("        ForceLoadReferencedAssemblies();");
 1744            builder.AppendLine();
 45        }
 46
 45547        builder.AppendLine("        global::NexusLabs.Needlr.Generators.NeedlrSourceGenBootstrap.Register(");
 45548        builder.AppendLine($"            global::{safeAssemblyName}.Generated.TypeRegistry.GetInjectableTypes,");
 45549        builder.AppendLine($"            global::{safeAssemblyName}.Generated.TypeRegistry.GetPluginTypes,");
 50
 51        // Generate the decorator/factory/provider applier lambda
 45552        if (hasFactories || hasProviders)
 53        {
 4154            builder.AppendLine("            services =>");
 4155            builder.AppendLine("            {");
 4156            builder.AppendLine($"                global::{safeAssemblyName}.Generated.TypeRegistry.ApplyDecorators((ISer
 4157            if (hasFactories)
 58            {
 2459                builder.AppendLine($"                global::{safeAssemblyName}.Generated.FactoryRegistrations.RegisterF
 60            }
 4161            if (hasProviders)
 62            {
 1763                builder.AppendLine($"                global::{safeAssemblyName}.Generated.TypeRegistry.RegisterProviders
 64            }
 4165            builder.AppendLine("            },");
 66        }
 67        else
 68        {
 41469            builder.AppendLine($"            services => global::{safeAssemblyName}.Generated.TypeRegistry.ApplyDecorato
 70        }
 71
 72        // Generate the options registrar lambda for NeedlrSourceGenBootstrap (for backward compat)
 45573        if (hasOptions)
 74        {
 14675            builder.AppendLine($"            (services, config) => global::{safeAssemblyName}.Generated.TypeRegistry.Reg
 76        }
 77        else
 78        {
 30979            builder.AppendLine("            null);");
 80        }
 81
 82        // Also register with SourceGenRegistry (for ConfiguredSyringe without Generators.Attributes dependency)
 45583        if (hasOptions)
 84        {
 14685            builder.AppendLine();
 14686            builder.AppendLine("        // Register options with core SourceGenRegistry for ConfiguredSyringe");
 14687            builder.AppendLine($"        global::NexusLabs.Needlr.SourceGenRegistry.RegisterOptionsRegistrar(");
 14688            builder.AppendLine($"            (services, config) => global::{safeAssemblyName}.Generated.TypeRegistry.Reg
 89        }
 90
 45591        builder.AppendLine("    }");
 92
 93        // Generate ForceLoadReferencedAssemblies method if needed
 45594        if (referencedAssemblies.Count > 0)
 95        {
 1796            builder.AppendLine();
 1797            builder.AppendLine("    /// <summary>");
 1798            builder.AppendLine("    /// Forces referenced assemblies with [GenerateTypeRegistry] to load,");
 1799            builder.AppendLine("    /// ensuring their module initializers execute and register their types.");
 17100            builder.AppendLine("    /// </summary>");
 17101            builder.AppendLine("    /// <remarks>");
 17102            builder.AppendLine("    /// Without this, transitive dependencies that are never directly referenced");
 17103            builder.AppendLine("    /// in code would not be loaded by the CLR, and their plugins would not be discovere
 17104            builder.AppendLine("    /// </remarks>");
 17105            builder.AppendLine("    [MethodImpl(MethodImplOptions.NoInlining)]");
 17106            builder.AppendLine("    private static void ForceLoadReferencedAssemblies()");
 17107            builder.AppendLine("    {");
 108
 70109            foreach (var referencedAssembly in referencedAssemblies)
 110            {
 18111                var safeRefAssemblyName = GeneratorHelpers.SanitizeIdentifier(referencedAssembly);
 18112                builder.AppendLine($"        _ = typeof(global::{safeRefAssemblyName}.Generated.TypeRegistry).Assembly;"
 113            }
 114
 17115            builder.AppendLine("    }");
 116        }
 117
 455118        builder.AppendLine("}");
 119
 455120        return builder.ToString();
 121    }
 122}