< Summary

Information
Class: NexusLabs.Needlr.Generators.CodeGen.PluginsCodeGenerator
Assembly: NexusLabs.Needlr.Generators
File(s): /home/runner/work/needlr/needlr/src/NexusLabs.Needlr.Generators/CodeGen/PluginsCodeGenerator.cs
Line coverage
95%
Covered lines: 38
Uncovered lines: 2
Coverable lines: 40
Total lines: 98
Line coverage: 95%
Branch coverage
80%
Covered branches: 16
Total branches: 20
Branch coverage: 80%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
GeneratePluginTypesArray(...)80%202095%

File(s)

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

#LineLine coverage
 1// Copyright (c) NexusLabs. All rights reserved.
 2// Licensed under the MIT License.
 3
 4using System.Collections.Generic;
 5using System.Linq;
 6using System.Text;
 7
 8using NexusLabs.Needlr.Generators.Models;
 9
 10namespace NexusLabs.Needlr.Generators.CodeGen;
 11
 12/// <summary>
 13/// Generates the static <c>_plugins</c> array of <see cref="DiscoveredPlugin"/>
 14/// entries for the compile-time type registry.
 15/// </summary>
 16internal static class PluginsCodeGenerator
 17{
 18    internal static void GeneratePluginTypesArray(StringBuilder builder, IReadOnlyList<DiscoveredPlugin> plugins, Breadc
 19    {
 45520        builder.AppendLine("    private static readonly PluginTypeInfo[] _plugins =");
 45521        builder.AppendLine("    [");
 22
 23        // Sort plugins by Order first, then by TypeName for determinism
 45524        var sortedPlugins = plugins
 138225            .OrderBy(p => p.Order)
 138226            .ThenBy(p => p.TypeName, StringComparer.Ordinal)
 45527            .ToList();
 28
 29        // Group for breadcrumb display, but maintain the sorted order
 242330        var pluginsByAssembly = sortedPlugins.GroupBy(p => p.AssemblyName).OrderBy(g => g.Key);
 31
 203432        foreach (var group in pluginsByAssembly)
 33        {
 56234            breadcrumbs.WriteInlineComment(builder, "        ", $"From {group.Key}");
 35
 36            // Maintain order within assembly group
 674837            foreach (var plugin in group.OrderBy(p => p.Order).ThenBy(p => p.TypeName, StringComparer.Ordinal))
 38            {
 39                // Write verbose breadcrumb for this plugin
 140640                if (breadcrumbs.Level == BreadcrumbLevel.Verbose)
 41                {
 9142                    var sourcePath = plugin.SourceFilePath != null
 9143                        ? BreadcrumbWriter.GetRelativeSourcePath(plugin.SourceFilePath, projectDirectory)
 9144                        : $"[{plugin.AssemblyName}]";
 9145                    var interfaces = plugin.InterfaceNames.Length > 0
 9146                        ? string.Join(", ", plugin.InterfaceNames.Select(i => i.Split('.').Last()))
 9147                        : "none";
 9148                    var orderInfo = plugin.Order != 0 ? $"Order: {plugin.Order}" : "Order: 0 (default)";
 49
 9150                    breadcrumbs.WriteVerboseBox(builder, "        ",
 9151                        $"Plugin: {plugin.TypeName.Split('.').Last()}",
 9152                        $"Source: {sourcePath}",
 9153                        $"Implements: {interfaces}",
 9154                        orderInfo);
 55                }
 131556                else if (breadcrumbs.Level == BreadcrumbLevel.Minimal && plugin.Order != 0)
 57                {
 58                    // Show order in minimal mode only if non-default
 059                    breadcrumbs.WriteInlineComment(builder, "        ", $"{plugin.TypeName.Split('.').Last()} (Order: {p
 60                }
 61
 140662                builder.Append($"        new(typeof({plugin.TypeName}), ");
 63
 64                // Interfaces
 140665                if (plugin.InterfaceNames.Length == 0)
 66                {
 067                    builder.Append("Array.Empty<Type>(), ");
 68                }
 69                else
 70                {
 140671                    builder.Append("[");
 281772                    builder.Append(string.Join(", ", plugin.InterfaceNames.Select(i => $"typeof({i})")));
 140673                    builder.Append("], ");
 74                }
 75
 76                // Factory lambda - no Activator.CreateInstance needed
 140677                builder.Append($"() => new {plugin.TypeName}(), ");
 78
 79                // Attributes
 140680                if (plugin.AttributeNames.Length == 0)
 81                {
 135982                    builder.Append("Array.Empty<Type>(), ");
 83                }
 84                else
 85                {
 4786                    builder.Append("[");
 10887                    builder.Append(string.Join(", ", plugin.AttributeNames.Select(a => $"typeof({a})")));
 4788                    builder.Append("], ");
 89                }
 90
 91                // Order
 140692                builder.AppendLine($"{plugin.Order}),");
 93            }
 94        }
 95
 45596        builder.AppendLine("    ];");
 45597    }
 98}