< Summary

Information
Class: NexusLabs.Needlr.AgentFramework.Analyzers.AgentFunctionDescriptionAnalyzer
Assembly: NexusLabs.Needlr.AgentFramework.Analyzers
File(s): /home/runner/work/needlr/needlr/src/NexusLabs.Needlr.AgentFramework.Analyzers/AgentFunctionDescriptionAnalyzer.cs
Line coverage
100%
Covered lines: 34
Uncovered lines: 0
Coverable lines: 34
Total lines: 81
Line coverage: 100%
Branch coverage
72%
Covered branches: 16
Total branches: 22
Branch coverage: 72.7%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
get_SupportedDiagnostics()100%11100%
Initialize(...)100%11100%
AnalyzeMethod(...)72.72%2222100%

File(s)

/home/runner/work/needlr/needlr/src/NexusLabs.Needlr.AgentFramework.Analyzers/AgentFunctionDescriptionAnalyzer.cs

#LineLine coverage
 1using System.Collections.Immutable;
 2
 3using Microsoft.CodeAnalysis;
 4using Microsoft.CodeAnalysis.Diagnostics;
 5
 6namespace NexusLabs.Needlr.AgentFramework.Analyzers;
 7
 8/// <summary>
 9/// Analyzer that detects <c>[AgentFunction]</c> methods and their parameters that are
 10/// missing <c>[System.ComponentModel.Description]</c> attributes.
 11/// </summary>
 12/// <remarks>
 13/// <b>NDLRMAF012</b> (Warning): An <c>[AgentFunction]</c> method has no <c>[Description]</c>.<br/>
 14/// <b>NDLRMAF013</b> (Warning): A non-<c>CancellationToken</c> parameter of an <c>[AgentFunction]</c>
 15/// method has no <c>[Description]</c>.
 16/// </remarks>
 17[DiagnosticAnalyzer(LanguageNames.CSharp)]
 18public sealed class AgentFunctionDescriptionAnalyzer : DiagnosticAnalyzer
 19{
 20    private const string AgentFunctionAttributeName = "NexusLabs.Needlr.AgentFramework.AgentFunctionAttribute";
 21    private const string DescriptionAttributeName = "System.ComponentModel.DescriptionAttribute";
 22    private const string CancellationTokenTypeName = "System.Threading.CancellationToken";
 23
 24    public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics =>
 31225        ImmutableArray.Create(
 31226            MafDiagnosticDescriptors.AgentFunctionMissingDescription,
 31227            MafDiagnosticDescriptors.AgentFunctionParameterMissingDescription);
 28
 29    public override void Initialize(AnalysisContext context)
 30    {
 2331        context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
 2332        context.EnableConcurrentExecution();
 2333        context.RegisterSymbolAction(AnalyzeMethod, SymbolKind.Method);
 2334    }
 35
 36    private static void AnalyzeMethod(SymbolAnalysisContext context)
 37    {
 36638        var method = (IMethodSymbol)context.Symbol;
 39
 36640        var agentFunctionAttr = method.GetAttributes()
 38141            .FirstOrDefault(a => a.AttributeClass?.ToDisplayString() == AgentFunctionAttributeName);
 42
 36643        if (agentFunctionAttr is null)
 35144            return;
 45
 1546        var attrLocation = agentFunctionAttr.ApplicationSyntaxReference?.SyntaxTree is { } tree
 1547            ? Location.Create(tree, agentFunctionAttr.ApplicationSyntaxReference.Span)
 1548            : method.Locations[0];
 49
 1550        var hasDescription = method.GetAttributes()
 3751            .Any(a => a.AttributeClass?.ToDisplayString() == DescriptionAttributeName);
 52
 1553        if (!hasDescription)
 54        {
 855            context.ReportDiagnostic(Diagnostic.Create(
 856                MafDiagnosticDescriptors.AgentFunctionMissingDescription,
 857                attrLocation,
 858                method.Name));
 59        }
 60
 6061        foreach (var parameter in method.Parameters)
 62        {
 1563            if (parameter.Type.ToDisplayString() == CancellationTokenTypeName)
 64                continue;
 65
 1466            var paramHasDescription = parameter.GetAttributes()
 1867                .Any(a => a.AttributeClass?.ToDisplayString() == DescriptionAttributeName);
 68
 1469            if (!paramHasDescription)
 70            {
 1071                var paramLocation = parameter.Locations.FirstOrDefault() ?? method.Locations[0];
 72
 1073                context.ReportDiagnostic(Diagnostic.Create(
 1074                    MafDiagnosticDescriptors.AgentFunctionParameterMissingDescription,
 1075                    paramLocation,
 1076                    parameter.Name,
 1077                    method.Name));
 78            }
 79        }
 1580    }
 81}