From b230b17ec9c703ae7506b5cf312f2899f8e2b2a4 Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Wed, 26 Nov 2025 21:51:37 -0500 Subject: [PATCH] Adjust analyzer diagnostic severities and improve MCP001 reporting (#1038) Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com> --- .../Diagnostics.cs | 2 +- .../XmlToDescriptionGenerator.cs | 17 ++++++++++------- .../XmlToDescriptionGeneratorTests.cs | 12 ++++++------ 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/src/ModelContextProtocol.Analyzers/Diagnostics.cs b/src/ModelContextProtocol.Analyzers/Diagnostics.cs index e2c7041..99f868f 100644 --- a/src/ModelContextProtocol.Analyzers/Diagnostics.cs +++ b/src/ModelContextProtocol.Analyzers/Diagnostics.cs @@ -25,7 +25,7 @@ internal static class Diagnostics title: "MCP method must be partial to generate [Description] attributes", messageFormat: "Method '{0}' has XML documentation that could be used to generate [Description] attributes, but the method is not declared as partial.", category: "mcp", - defaultSeverity: DiagnosticSeverity.Warning, + defaultSeverity: DiagnosticSeverity.Info, isEnabledByDefault: true, description: "Methods with MCP attributes should be declared as partial to allow the source generator to emit Description attributes from XML documentation comments."); } diff --git a/src/ModelContextProtocol.Analyzers/XmlToDescriptionGenerator.cs b/src/ModelContextProtocol.Analyzers/XmlToDescriptionGenerator.cs index a5dff0c..0110ac0 100644 --- a/src/ModelContextProtocol.Analyzers/XmlToDescriptionGenerator.cs +++ b/src/ModelContextProtocol.Analyzers/XmlToDescriptionGenerator.cs @@ -72,7 +72,7 @@ public sealed class XmlToDescriptionGenerator : IIncrementalGenerator List<(IMethodSymbol MethodSymbol, MethodDeclarationSyntax MethodDeclaration, XmlDocumentation? XmlDocs)> methodsToGenerate = new(methods.Length); foreach (var methodModel in methods) { - var xmlDocs = ExtractXmlDocumentation(methodModel.MethodSymbol, context); + var xmlDocs = ExtractXmlDocumentation(methodModel.MethodSymbol, methodModel.MethodDeclaration, context); // Generate implementation for partial methods. if (methodModel.MethodDeclaration.Modifiers.Any(SyntaxKind.PartialKeyword)) @@ -97,7 +97,7 @@ public sealed class XmlToDescriptionGenerator : IIncrementalGenerator } } - private static XmlDocumentation? ExtractXmlDocumentation(IMethodSymbol methodSymbol, SourceProductionContext context) + private static XmlDocumentation? ExtractXmlDocumentation(IMethodSymbol methodSymbol, MethodDeclarationSyntax methodDeclaration, SourceProductionContext context) { string? xmlDoc = methodSymbol.GetDocumentationCommentXml(); if (string.IsNullOrWhiteSpace(xmlDoc)) @@ -138,11 +138,14 @@ public sealed class XmlToDescriptionGenerator : IIncrementalGenerator } catch (System.Xml.XmlException) { - // Emit warning for invalid XML - context.ReportDiagnostic(Diagnostic.Create( - Diagnostics.InvalidXmlDocumentation, - methodSymbol.Locations.FirstOrDefault(), - methodSymbol.Name)); + // Emit warning for invalid XML only if the method is partial (as that's when it would affect generated code) + if (methodDeclaration.Modifiers.Any(SyntaxKind.PartialKeyword)) + { + context.ReportDiagnostic(Diagnostic.Create( + Diagnostics.InvalidXmlDocumentation, + methodSymbol.Locations.FirstOrDefault(), + methodSymbol.Name)); + } return null; } } diff --git a/tests/ModelContextProtocol.Analyzers.Tests/XmlToDescriptionGeneratorTests.cs b/tests/ModelContextProtocol.Analyzers.Tests/XmlToDescriptionGeneratorTests.cs index 2439f89..f9b13bf 100644 --- a/tests/ModelContextProtocol.Analyzers.Tests/XmlToDescriptionGeneratorTests.cs +++ b/tests/ModelContextProtocol.Analyzers.Tests/XmlToDescriptionGeneratorTests.cs @@ -381,7 +381,7 @@ public partial class XmlToDescriptionGeneratorTests // Should report MCP002 diagnostic var diagnostic = Assert.Single(result.Diagnostics, d => d.Id == "MCP002"); - Assert.Equal(DiagnosticSeverity.Warning, diagnostic.Severity); + Assert.Equal(DiagnosticSeverity.Info, diagnostic.Severity); Assert.Contains("TestMethod", diagnostic.GetMessage()); Assert.Contains("partial", diagnostic.GetMessage()); } @@ -412,7 +412,7 @@ public partial class XmlToDescriptionGeneratorTests // Should report MCP002 diagnostic because parameter has documentation var diagnostic = Assert.Single(result.Diagnostics, d => d.Id == "MCP002"); - Assert.Equal(DiagnosticSeverity.Warning, diagnostic.Severity); + Assert.Equal(DiagnosticSeverity.Info, diagnostic.Severity); } [Fact] @@ -441,7 +441,7 @@ public partial class XmlToDescriptionGeneratorTests // Should report MCP002 diagnostic because return has documentation var diagnostic = Assert.Single(result.Diagnostics, d => d.Id == "MCP002"); - Assert.Equal(DiagnosticSeverity.Warning, diagnostic.Severity); + Assert.Equal(DiagnosticSeverity.Info, diagnostic.Severity); } [Fact] @@ -559,7 +559,7 @@ public partial class XmlToDescriptionGeneratorTests // Should report MCP002 diagnostic because parameter description would be generated var diagnostic = Assert.Single(result.Diagnostics, d => d.Id == "MCP002"); - Assert.Equal(DiagnosticSeverity.Warning, diagnostic.Severity); + Assert.Equal(DiagnosticSeverity.Info, diagnostic.Severity); } [Fact] @@ -590,7 +590,7 @@ public partial class XmlToDescriptionGeneratorTests // Should report MCP002 diagnostic for prompts too var diagnostic = Assert.Single(result.Diagnostics, d => d.Id == "MCP002"); - Assert.Equal(DiagnosticSeverity.Warning, diagnostic.Severity); + Assert.Equal(DiagnosticSeverity.Info, diagnostic.Severity); } [Fact] @@ -621,7 +621,7 @@ public partial class XmlToDescriptionGeneratorTests // Should report MCP002 diagnostic for resources too var diagnostic = Assert.Single(result.Diagnostics, d => d.Id == "MCP002"); - Assert.Equal(DiagnosticSeverity.Warning, diagnostic.Severity); + Assert.Equal(DiagnosticSeverity.Info, diagnostic.Severity); } [Fact]