You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
NamedTypeSymbolProvider.GetParameterXmlDocumentation extracts <param> documentation with XElement.Value, which concatenates text nodes only. <see cref="..."/> is an empty element with no text content, so every cross-reference in a parameter doc is silently deleted when a type is read back from a LastContractView.
The sibling method GetSymbolXmlDoc (used for <summary> and <returns>) does not have this problem, because it routes through ProcessXmlContent, which special-cases see and rebuilds the tag:
So summaries keep their crefs and parameters lose them.
Reproduction
varxml=""" <doc><param name="p">Please note <see cref="T:Azure.Foo"/> is the base class. The available derived classes include <see cref="T:Azure.A"/> and <see cref="T:Azure.B"/>.</param></doc> """;varp=XDocument.Parse(xml).Descendants("param").First();Console.WriteLine(p.Value.Trim());
Actual:
Please note is the base class.
The available derived classes include and .
Expected: the <see cref="..."/> references preserved, as ProcessXmlContent already does for summaries.
Real-world impact
This is observable in shipped Azure SDK output. sdk/network/Azure.ResourceManager.Network/src/Generated/ArmNetworkModelFactory.cs on Azure/azure-sdk-for-net@30d826a5d9b contains, inside <param name="ruleCollections">:
/// Please note is the base class. According to the scenario, a derived class of the base class might need to be assigned here, ...
/// The available derived classes include and .
Two separate defects compound here:
Lost crefs (this issue) — the type references are gone and cannot be recovered, because the doc is reconstituted from text rather than from structured data. Note that even the summary path is lossy in a weaker sense: FormattableStringHelpers.FromString yields a zero-argument FormattableString, so a cref survives only as literal text, never as a CSharpType reference.
Fixing (1) would be a matter of calling ProcessXmlContent(paramElement) rather than paramElement.Value, which would also make the two extraction paths consistent.
Describe the bug
NamedTypeSymbolProvider.GetParameterXmlDocumentationextracts<param>documentation withXElement.Value, which concatenates text nodes only.<see cref="..."/>is an empty element with no text content, so every cross-reference in a parameter doc is silently deleted when a type is read back from aLastContractView.https://github.com/microsoft/typespec/blob/main/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/NamedTypeSymbolProvider.cs
The sibling method
GetSymbolXmlDoc(used for<summary>and<returns>) does not have this problem, because it routes throughProcessXmlContent, which special-casesseeand rebuilds the tag:So summaries keep their crefs and parameters lose them.
Reproduction
Actual:
Expected: the
<see cref="..."/>references preserved, asProcessXmlContentalready does for summaries.Real-world impact
This is observable in shipped Azure SDK output.
sdk/network/Azure.ResourceManager.Network/src/Generated/ArmNetworkModelFactory.csonAzure/azure-sdk-for-net@30d826a5d9bcontains, inside<param name="ruleCollections">:Two separate defects compound here:
FormattableStringHelpers.FromStringyields a zero-argumentFormattableString, so a cref survives only as literal text, never as aCSharpTypereference..Trim()only trims the ends, so the writer's continuation indentation is preserved inside the string and re-indented on the next regeneration, growing by 12 spaces per round-trip. Tracked for the management emitter in [Mgmt generator] Model factory regeneration cumulatively adds whitespace to multiline XML docs Azure/azure-sdk-for-net#62444 and fixed there ([mgmt] Regenerate model factory back-compat docs instead of reusing last contract docs Azure/azure-sdk-for-net#62446) by regenerating parameter docs from the current model instead of reusing last-contract text.Fixing (1) would be a matter of calling
ProcessXmlContent(paramElement)rather thanparamElement.Value, which would also make the two extraction paths consistent.Checklist