From 42f50545c9122c08b878ef48d9db18a88b9d81b0 Mon Sep 17 00:00:00 2001 From: nightcityblade Date: Sun, 30 Aug 2026 23:30:38 +0800 Subject: [PATCH] [http-client-csharp] Preserve cref tags in parameter docs --- .../src/Providers/NamedTypeSymbolProvider.cs | 4 +-- .../NamedTypeSymbolProviders/XmlDocsTests.cs | 28 ++++++++++++++++++- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/NamedTypeSymbolProvider.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/NamedTypeSymbolProvider.cs index 1a822a16db8..613c9e34108 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/NamedTypeSymbolProvider.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/NamedTypeSymbolProvider.cs @@ -73,7 +73,7 @@ private static string GetMetadataName(INamedTypeSymbol symbol) protected override string BuildNamespace() => _namedTypeSymbol.ContainingNamespace.GetFullyQualifiedNameFromDisplayString(); protected override IReadOnlyList BuildAttributes() - => [.._namedTypeSymbol.GetAttributes().Select(a => new AttributeStatement(a))]; + => [.. _namedTypeSymbol.GetAttributes().Select(a => new AttributeStatement(a))]; protected internal override CSharpType[] BuildImplements() => [.. _namedTypeSymbol.AllInterfaces.Select(i => i.GetCSharpType())]; @@ -961,7 +961,7 @@ private static XDocument ParseXml(ISymbol docsSymbol, string xmlDocumentation) var paramElement = xmlDoc.Descendants("param") .FirstOrDefault(e => e.Attribute("name")?.Value == parameterSymbol.Name); - return paramElement?.Value.Trim(); + return paramElement is null ? null : ProcessXmlContent(paramElement); } private static MethodSignatureModifiers GetAccessModifier(Accessibility accessibility) => accessibility switch diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/NamedTypeSymbolProviders/XmlDocsTests.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/NamedTypeSymbolProviders/XmlDocsTests.cs index c9ab80631a5..3de07122f56 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/NamedTypeSymbolProviders/XmlDocsTests.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/NamedTypeSymbolProviders/XmlDocsTests.cs @@ -126,6 +126,19 @@ public void MixedContentWithSeeTagsProcessedCorrectly() Assert.That(description, Contains.Substring("This property represents and returns a value.")); } + [Test] + public void ParameterSeeTagsProcessedCorrectly() + { + var model = new ParameterSeeTagsModel(); + var compilation = CompilationHelper.LoadCompilation(new[] { model }); + var symbol = CompilationHelper.GetSymbol(compilation.Assembly.Modules.First().GlobalNamespace, nameof(ParameterSeeTagsModel)); + + var provider = new NamedTypeSymbolProvider(symbol!, compilation); + var description = provider.Methods.Single().Signature.Parameters.Single().Description.ToString(); + + Assert.AreEqual("Works with and types.", description); + } + [Test] public void InvalidParameterDocsThrows() { @@ -167,11 +180,24 @@ private class InvalidParameterDocsModel : TypeProvider protected internal override MethodProvider[] BuildMethods() { - var sig = new MethodSignature("Write", $"", MethodSignatureModifiers.Public, null, $"", [ new ParameterProvider("value", $"This is an invalid description because it is missing closing slash ", typeof(int)), new ParameterProvider("options", $"", typeof(string)) ]); + var sig = new MethodSignature("Write", $"", MethodSignatureModifiers.Public, null, $"", [new ParameterProvider("value", $"This is an invalid description because it is missing closing slash ", typeof(int)), new ParameterProvider("options", $"", typeof(string))]); return [new MethodProvider(sig, Snippet.ThrowExpression(Snippet.Null), this, null)]; } } + private class ParameterSeeTagsModel : TypeProvider + { + protected override string BuildRelativeFilePath() => "."; + + protected override string BuildName() => nameof(ParameterSeeTagsModel); + + protected internal override MethodProvider[] BuildMethods() + { + var signature = new MethodSignature("Write", $"", MethodSignatureModifiers.Public, null, $"", [new ParameterProvider("value", $"Works with and types", typeof(string))]); + return [new MethodProvider(signature, Snippet.ThrowExpression(Snippet.Null), this, null)]; + } + } + private class ValidDocsModel : TypeProvider { protected override string BuildRelativeFilePath() => ".";