Skip to content

Commit 1c13851

Browse files
Handle langword for see elements
Handle `<see langword="" />` references in XML documentation as inline code. Contributes to #61042.
1 parent 3a1fc4f commit 1c13851

File tree

3 files changed

+80
-10
lines changed

3 files changed

+80
-10
lines changed

src/OpenApi/gen/XmlComments/XmlComment.cs

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,11 @@ private XmlComment(Compilation compilation, string xml)
3535
// Transform triple slash comment
3636
var doc = XDocument.Parse(xml, LoadOptions.PreserveWhitespace | LoadOptions.SetLineInfo);
3737

38-
ResolveCrefLink(compilation, doc, $"//{DocumentationCommentXmlNames.SeeAlsoElementName}[@cref]");
39-
ResolveCrefLink(compilation, doc, $"//{DocumentationCommentXmlNames.SeeElementName}[@cref]");
38+
ResolveCrefLink(compilation, doc, DocumentationCommentXmlNames.SeeAlsoElementName);
39+
ResolveCrefLink(compilation, doc, DocumentationCommentXmlNames.SeeElementName);
40+
41+
ResolveLangKeyword(doc, DocumentationCommentXmlNames.SeeElementName);
42+
4043
// Resolve <list> and <item> tags into bullets
4144
ResolveListTags(doc);
4245
// Resolve <code> tags into code blocks
@@ -171,18 +174,20 @@ private static void ResolveParaTags(XDocument document)
171174
/// </summary>
172175
/// <param name="compilation">The compilation to resolve type symbol declarations from.</param>
173176
/// <param name="node">The target node to process crefs in.</param>
174-
/// <param name="nodeSelector">The node type to process crefs for, can be `see` or `seealso`.</param>
175-
private static void ResolveCrefLink(Compilation compilation, XNode node, string nodeSelector)
177+
/// <param name="elementName">The node type to process crefs for, can be `see` or `seealso`.</param>
178+
private static void ResolveCrefLink(Compilation compilation, XNode node, string elementName)
176179
{
177-
if (node == null || string.IsNullOrEmpty(nodeSelector))
180+
if (node == null || string.IsNullOrEmpty(elementName))
178181
{
179182
return;
180183
}
181184

182-
var nodes = node.XPathSelectElements(nodeSelector + "[@cref]").ToArray();
185+
var attributeName = DocumentationCommentXmlNames.CrefAttributeName;
186+
187+
var nodes = node.XPathSelectElements($"//{elementName}[@{attributeName}]").ToArray();
183188
foreach (var item in nodes)
184189
{
185-
var cref = item.Attribute(DocumentationCommentXmlNames.CrefAttributeName).Value;
190+
var cref = item.Attribute(attributeName).Value;
186191
if (string.IsNullOrEmpty(cref))
187192
{
188193
continue;
@@ -197,6 +202,35 @@ private static void ResolveCrefLink(Compilation compilation, XNode node, string
197202
}
198203
}
199204

205+
/// <summary>
206+
/// Resolves the links in the XML documentation into type names.
207+
/// </summary>
208+
/// <param name="node">The target node to process crefs in.</param>
209+
/// <param name="elementName">The node type to process crefs for, can be `see` or `seealso`.</param>
210+
private static void ResolveLangKeyword(XNode node, string elementName)
211+
{
212+
if (node == null || string.IsNullOrEmpty(elementName))
213+
{
214+
return;
215+
}
216+
217+
var attributeName = DocumentationCommentXmlNames.LangwordAttributeName;
218+
219+
var nodes = node.XPathSelectElements($"//{elementName}[@{attributeName}]").ToArray();
220+
foreach (var item in nodes)
221+
{
222+
var langword = item.Attribute(attributeName).Value;
223+
if (string.IsNullOrEmpty(langword))
224+
{
225+
continue;
226+
}
227+
228+
// TODO Is this the right thing to do? For example C# would get `true`, `false`, `null`
229+
// but VB would get `True`, `False`, `Nothing`. They should emit in neutral OpenAPI terms?
230+
item.ReplaceWith(new XText($"`{langword}`"));
231+
}
232+
}
233+
200234
private static IEnumerable<string?> GetMultipleExampleNodes(XPathNavigator navigator, string selector)
201235
{
202236
var iterator = navigator.Select(selector);

src/OpenApi/test/Microsoft.AspNetCore.OpenApi.SourceGenerators.Tests/CompletenessTests.cs

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

4-
using System.Globalization;
5-
using System.Text.Json.Nodes;
64
using Microsoft.OpenApi.Models;
75

86
namespace Microsoft.AspNetCore.OpenApi.SourceGenerators.Tests;
@@ -354,6 +352,39 @@ public static T GetGenericValue<T>(T para)
354352
return para;
355353
}
356354
}
355+
356+
/// <summary>
357+
/// A class that implements the <see cref="IDisposable"/> interface.
358+
/// </summary>
359+
public class DisposableType : IDisposable
360+
{
361+
/// <summary>
362+
/// Finalizes an instance of the <see cref="DisposableType"/> class.
363+
/// </summary>
364+
~DisposableType()
365+
{
366+
Dispose(false);
367+
}
368+
369+
/// <inheritdoc />
370+
public void Dispose()
371+
{
372+
Dispose(true);
373+
GC.SuppressFinalize(this);
374+
}
375+
376+
/// <summary>
377+
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
378+
/// </summary>
379+
/// <param name="disposing">
380+
/// <see langword="true" /> to release both managed and unmanaged resources;
381+
/// <see langword="false" /> to release only unmanaged resources.
382+
/// </param>
383+
protected virtual void Dispose(bool disposing)
384+
{
385+
// No-op
386+
}
387+
}
357388
""";
358389
var generator = new XmlCommentGenerator();
359390
await SnapshotTestHelper.Verify(source, generator, out var compilation);

src/OpenApi/test/Microsoft.AspNetCore.OpenApi.SourceGenerators.Tests/snapshots/CompletenessTests.SupportsAllXmlTagsOnSchemas#OpenApiXmlCommentSupport.generated.verified.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,8 @@ type as a cref attribute.
259259
In generic classes and methods, you'll often want to reference the
260260
generic type, or the type parameter.", null, null, false, null, null, null));
261261
_cache.Add(new MemberKey(typeof(global::ParamsAndParamRefs), MemberType.Type, null, null, []), new XmlComment(@"This shows examples of typeparamref and typeparam tags", null, null, null, null, false, null, null, null));
262-
_cache.Add(new MemberKey(typeof(global::ExampleClass), MemberType.Property, "Label", null, []), new XmlComment(null, null, @" The string? ExampleClass.Label is a <see langword=""string"" />
262+
_cache.Add(new MemberKey(typeof(global::DisposableType), MemberType.Type, null, null, []), new XmlComment(@"A class that implements the IDisposable interface.", null, null, null, null, false, null, null, null));
263+
_cache.Add(new MemberKey(typeof(global::ExampleClass), MemberType.Property, "Label", null, []), new XmlComment(null, null, @" The string? ExampleClass.Label is a `string`
263264
that you use for a label.
264265
Note that there isn't a way to provide a ""cref"" to
265266
each accessor, only to the property itself.", null, @"The `Label` property represents a label
@@ -289,6 +290,10 @@ that implement this interface when the
289290
method as a cref attribute.
290291
The parameter and return value are both of an arbitrary type,
291292
T", null, null, false, null, null, null));
293+
_cache.Add(new MemberKey(typeof(global::DisposableType), MemberType.Method, "Finalize", typeof(void), []), new XmlComment(@"Finalizes an instance of the DisposableType class.", null, null, null, null, false, null, null, null));
294+
_cache.Add(new MemberKey(typeof(global::DisposableType), MemberType.Method, "Dispose", typeof(void), []), new XmlComment(null, null, null, null, null, false, null, null, null));
295+
_cache.Add(new MemberKey(typeof(global::DisposableType), MemberType.Method, "Dispose", typeof(void), [typeof(global::System.Boolean)]), new XmlComment(@"Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.", null, null, null, null, false, null, [new XmlParameterComment(@"disposing", @"`true` to release both managed and unmanaged resources;
296+
`false` to release only unmanaged resources.", null, false)], null));
292297

293298
return _cache;
294299
}

0 commit comments

Comments
 (0)