Skip to content

Commit c4a06d5

Browse files
Copilotstephentoub
andcommitted
Address review feedback: rename field to s_camelCase and add test for unqualified types
- Rename FullyQualifiedFormatWithNullability to s_fullyQualifiedFormatWithNullability - Add test for unqualified parameter type in source (using directive) to ensure the generator still produces fully qualified output Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com>
1 parent 2a2409e commit c4a06d5

2 files changed

Lines changed: 65 additions & 3 deletions

File tree

src/ModelContextProtocol.Analyzers/XmlToDescriptionGenerator.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public sealed class XmlToDescriptionGenerator : IIncrementalGenerator
2323
/// A display format that produces fully-qualified type names with "global::" prefix
2424
/// and includes nullability annotations.
2525
/// </summary>
26-
private static readonly SymbolDisplayFormat FullyQualifiedFormatWithNullability =
26+
private static readonly SymbolDisplayFormat s_fullyQualifiedFormatWithNullability =
2727
SymbolDisplayFormat.FullyQualifiedFormat.AddMiscellaneousOptions(
2828
SymbolDisplayMiscellaneousOptions.IncludeNullableReferenceTypeModifier);
2929

@@ -133,7 +133,7 @@ private static MethodToGenerate ExtractMethodInfo(
133133
.Where(m => !m.IsKind(SyntaxKind.AsyncKeyword))
134134
.Select(m => m.Text);
135135
string modifiersStr = string.Join(" ", modifiers);
136-
string returnType = methodSymbol.ReturnType.ToDisplayString(FullyQualifiedFormatWithNullability);
136+
string returnType = methodSymbol.ReturnType.ToDisplayString(s_fullyQualifiedFormatWithNullability);
137137
string methodName = methodSymbol.Name;
138138

139139
// Extract parameters
@@ -145,7 +145,7 @@ private static MethodToGenerate ExtractMethodInfo(
145145
var paramSyntax = i < parameterSyntaxList.Count ? parameterSyntaxList[i] : null;
146146

147147
parameters[i] = new ParameterInfo(
148-
ParameterType: param.Type.ToDisplayString(FullyQualifiedFormatWithNullability),
148+
ParameterType: param.Type.ToDisplayString(s_fullyQualifiedFormatWithNullability),
149149
Name: param.Name,
150150
HasDescriptionAttribute: descriptionAttribute is not null && HasAttribute(param, descriptionAttribute),
151151
XmlDescription: xmlDocs?.Parameters.TryGetValue(param.Name, out var pd) == true && !string.IsNullOrWhiteSpace(pd) ? pd : null,

tests/ModelContextProtocol.Analyzers.Tests/XmlToDescriptionGeneratorTests.cs

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1777,6 +1777,68 @@ partial class Tools
17771777
AssertGeneratedSourceEquals(expected, result.GeneratedSources[0].SourceText.ToString());
17781778
}
17791779

1780+
[Fact]
1781+
public void Generator_WithUnqualifiedTypeInSource_GeneratesFullyQualifiedTypeName()
1782+
{
1783+
// This test validates that even when the source code uses an unqualified type name
1784+
// (via a using directive), the generator still emits fully qualified type names.
1785+
// This is the exact scenario from the original issue.
1786+
var result = RunGenerator("""
1787+
using ModelContextProtocol.Server;
1788+
using System.ComponentModel;
1789+
using System.Threading.Tasks;
1790+
using MyApp.Actions;
1791+
1792+
namespace MyApp.Actions
1793+
{
1794+
public enum MyAction
1795+
{
1796+
One,
1797+
Two
1798+
}
1799+
}
1800+
1801+
namespace MyApp
1802+
{
1803+
[McpServerToolType]
1804+
public sealed partial class Tools
1805+
{
1806+
/// <summary>Do a thing based on an action.</summary>
1807+
/// <param name="action">The action to perform.</param>
1808+
[McpServerTool]
1809+
public async partial Task<string> DoThing(MyAction action)
1810+
=> await Task.FromResult("ok");
1811+
}
1812+
}
1813+
""");
1814+
1815+
Assert.True(result.Success);
1816+
Assert.Single(result.GeneratedSources);
1817+
1818+
// Even though the source uses unqualified "MyAction", the generated code should use
1819+
// the fully qualified "global::MyApp.Actions.MyAction"
1820+
var expected = $$"""
1821+
// <auto-generated/>
1822+
// ModelContextProtocol.Analyzers {{typeof(XmlToDescriptionGenerator).Assembly.GetName().Version}}
1823+
1824+
#pragma warning disable
1825+
1826+
using System.ComponentModel;
1827+
using ModelContextProtocol.Server;
1828+
1829+
namespace MyApp
1830+
{
1831+
partial class Tools
1832+
{
1833+
[Description("Do a thing based on an action.")]
1834+
public partial global::System.Threading.Tasks.Task<string> DoThing([Description("The action to perform.")] global::MyApp.Actions.MyAction action);
1835+
}
1836+
}
1837+
""";
1838+
1839+
AssertGeneratedSourceEquals(expected, result.GeneratedSources[0].SourceText.ToString());
1840+
}
1841+
17801842
private GeneratorRunResult RunGenerator([StringSyntax("C#-test")] string source, params string[] expectedDiagnosticIds)
17811843
{
17821844
var syntaxTree = CSharpSyntaxTree.ParseText(source);

0 commit comments

Comments
 (0)