diff --git a/src/OpenApi/gen/XmlCommentGenerator.Parser.cs b/src/OpenApi/gen/XmlCommentGenerator.Parser.cs
index 022fe4a67427..9b25cf9dd63c 100644
--- a/src/OpenApi/gen/XmlCommentGenerator.Parser.cs
+++ b/src/OpenApi/gen/XmlCommentGenerator.Parser.cs
@@ -94,7 +94,7 @@ public sealed partial class XmlCommentGenerator
if (DocumentationCommentId.GetFirstSymbolForDeclarationId(name, compilation) is ISymbol symbol &&
// Only include symbols that are declared in the application assembly or are
// accessible from the application assembly.
- (SymbolEqualityComparer.Default.Equals(symbol.ContainingAssembly, input.Compilation.Assembly) || symbol.IsAccessibleType()) &&
+ (SymbolEqualityComparer.Default.Equals(symbol.ContainingAssembly, compilation.Assembly) || symbol.IsAccessibleType()) &&
// Skip static classes that are just containers for members with annotations
// since they cannot be instantiated.
symbol is not INamedTypeSymbol { TypeKind: TypeKind.Class, IsStatic: true })
@@ -104,7 +104,7 @@ public sealed partial class XmlCommentGenerator
{
var memberKey = symbol switch
{
- IMethodSymbol methodSymbol => MemberKey.FromMethodSymbol(methodSymbol, input.Compilation),
+ IMethodSymbol methodSymbol => MemberKey.FromMethodSymbol(methodSymbol),
IPropertySymbol propertySymbol => MemberKey.FromPropertySymbol(propertySymbol),
INamedTypeSymbol typeSymbol => MemberKey.FromTypeSymbol(typeSymbol),
_ => null
diff --git a/src/OpenApi/gen/XmlComments/MemberKey.cs b/src/OpenApi/gen/XmlComments/MemberKey.cs
index 9117d02af393..b4be920d9c63 100644
--- a/src/OpenApi/gen/XmlComments/MemberKey.cs
+++ b/src/OpenApi/gen/XmlComments/MemberKey.cs
@@ -21,7 +21,7 @@ internal sealed record MemberKey(
typeQualificationStyle: SymbolDisplayTypeQualificationStyle.NameAndContainingTypesAndNamespaces,
genericsOptions: SymbolDisplayGenericsOptions.IncludeTypeParameters);
- public static MemberKey FromMethodSymbol(IMethodSymbol method, Compilation compilation)
+ public static MemberKey FromMethodSymbol(IMethodSymbol method)
{
string returnType;
if (method.ReturnsVoid)
@@ -32,16 +32,10 @@ public static MemberKey FromMethodSymbol(IMethodSymbol method, Compilation compi
{
// Handle Task/ValueTask for async methods
var actualReturnType = method.ReturnType;
- if (method.IsAsync && actualReturnType is INamedTypeSymbol namedType)
+ if (method.IsAsync
+ && actualReturnType is INamedTypeSymbol { TypeArguments.Length: 1 } namedType)
{
- if (namedType.TypeArguments.Length > 0)
- {
- actualReturnType = namedType.TypeArguments[0];
- }
- else
- {
- actualReturnType = compilation.GetSpecialType(SpecialType.System_Void);
- }
+ actualReturnType = namedType.ConstructedFrom;
}
returnType = actualReturnType.TypeKind == TypeKind.TypeParameter
diff --git a/src/OpenApi/test/Microsoft.AspNetCore.OpenApi.SourceGenerators.Tests/OperationTests.MinimalApis.cs b/src/OpenApi/test/Microsoft.AspNetCore.OpenApi.SourceGenerators.Tests/OperationTests.MinimalApis.cs
index 76fd57471901..6dfdcb5fa879 100644
--- a/src/OpenApi/test/Microsoft.AspNetCore.OpenApi.SourceGenerators.Tests/OperationTests.MinimalApis.cs
+++ b/src/OpenApi/test/Microsoft.AspNetCore.OpenApi.SourceGenerators.Tests/OperationTests.MinimalApis.cs
@@ -14,6 +14,7 @@ public async Task SupportsXmlCommentsOnOperationsFromMinimalApis()
{
var source = """
using System;
+using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Http.HttpResults;
@@ -32,6 +33,14 @@ public async Task SupportsXmlCommentsOnOperationsFromMinimalApis()
app.MapGet("/5", RouteHandlerExtensionMethods.Get5);
app.MapPost("/6", RouteHandlerExtensionMethods.Post6);
app.MapPut("/7", RouteHandlerExtensionMethods.Put7);
+app.MapGet("/8", RouteHandlerExtensionMethods.Get8);
+app.MapGet("/9", RouteHandlerExtensionMethods.Get9);
+app.MapGet("/10", RouteHandlerExtensionMethods.Get10);
+app.MapGet("/11", RouteHandlerExtensionMethods.Get11);
+app.MapGet("/12", RouteHandlerExtensionMethods.Get12);
+app.MapGet("/13", RouteHandlerExtensionMethods.Get13);
+app.MapGet("/14", RouteHandlerExtensionMethods.Get14);
+app.MapGet("/15", RouteHandlerExtensionMethods.Get15);
app.Run();
@@ -114,6 +123,73 @@ public static IResult Put7(int? id, string uuid)
{
return TypedResults.NoContent();
}
+
+ ///
+ /// A summary of Get8.
+ ///
+ public static async Task Get8()
+ {
+ await Task.Delay(1000);
+ return;
+ }
+
+ ///
+ /// A summary of Get9.
+ ///
+ public static async ValueTask Get9()
+ {
+ await Task.Delay(1000);
+ return;
+ }
+
+ ///
+ /// A summary of Get10.
+ ///
+ public static Task Get10()
+ {
+ return Task.CompletedTask;
+ }
+
+ ///
+ /// A summary of Get11.
+ ///
+ public static ValueTask Get11()
+ {
+ return ValueTask.CompletedTask;
+ }
+
+ ///
+ /// A summary of Get12.
+ ///
+ public static Task Get12()
+ {
+ return Task.FromResult("Hello, World!");
+ }
+
+ ///
+ /// A summary of Get13.
+ ///
+ public static ValueTask Get13()
+ {
+ return new ValueTask("Hello, World!");
+ }
+
+ ///
+ /// A summary of Get14.
+ ///
+ public static async Task> Get14()
+ {
+ await Task.Delay(1000);
+ return new Holder { Value = "Hello, World!" };
+ }
+
+ ///
+ /// A summary of Get15.
+ ///
+ public static Task> Get15()
+ {
+ return Task.FromResult(new Holder { Value = "Hello, World!" });
+ }
}
public class User
@@ -121,6 +197,11 @@ public class User
public string Username { get; set; } = string.Empty;
public string Email { get; set; } = string.Empty;
}
+
+public class Holder
+{
+ public T Value { get; set; } = default!;
+}
""";
var generator = new XmlCommentGenerator();
await SnapshotTestHelper.Verify(source, generator, out var compilation);
@@ -159,6 +240,30 @@ await SnapshotTestHelper.VerifyOpenApi(compilation, document =>
var idParam = path7.Parameters.First(p => p.Name == "id");
Assert.True(idParam.Deprecated);
Assert.Equal("Legacy ID parameter - use uuid instead.", idParam.Description);
+
+ var path8 = document.Paths["/8"].Operations[OperationType.Get];
+ Assert.Equal("A summary of Get8.", path8.Summary);
+
+ var path9 = document.Paths["/9"].Operations[OperationType.Get];
+ Assert.Equal("A summary of Get9.", path9.Summary);
+
+ var path10 = document.Paths["/10"].Operations[OperationType.Get];
+ Assert.Equal("A summary of Get10.", path10.Summary);
+
+ var path11 = document.Paths["/11"].Operations[OperationType.Get];
+ Assert.Equal("A summary of Get11.", path11.Summary);
+
+ var path12 = document.Paths["/12"].Operations[OperationType.Get];
+ Assert.Equal("A summary of Get12.", path12.Summary);
+
+ var path13 = document.Paths["/13"].Operations[OperationType.Get];
+ Assert.Equal("A summary of Get13.", path13.Summary);
+
+ var path14 = document.Paths["/14"].Operations[OperationType.Get];
+ Assert.Equal("A summary of Get14.", path14.Summary);
+
+ var path15 = document.Paths["/15"].Operations[OperationType.Get];
+ Assert.Equal("A summary of Get15.", path15.Summary);
});
}
}
diff --git a/src/OpenApi/test/Microsoft.AspNetCore.OpenApi.SourceGenerators.Tests/snapshots/OperationTests.SupportsXmlCommentsOnOperationsFromMinimalApis#OpenApiXmlCommentSupport.generated.verified.cs b/src/OpenApi/test/Microsoft.AspNetCore.OpenApi.SourceGenerators.Tests/snapshots/OperationTests.SupportsXmlCommentsOnOperationsFromMinimalApis#OpenApiXmlCommentSupport.generated.verified.cs
index 0d60c7298d22..4625c785aad1 100644
--- a/src/OpenApi/test/Microsoft.AspNetCore.OpenApi.SourceGenerators.Tests/snapshots/OperationTests.SupportsXmlCommentsOnOperationsFromMinimalApis#OpenApiXmlCommentSupport.generated.verified.cs
+++ b/src/OpenApi/test/Microsoft.AspNetCore.OpenApi.SourceGenerators.Tests/snapshots/OperationTests.SupportsXmlCommentsOnOperationsFromMinimalApis#OpenApiXmlCommentSupport.generated.verified.cs
@@ -198,6 +198,14 @@ private static Dictionary GenerateCacheEntries()
""email"": ""john@example.com""
}", null, null, false, null, [new XmlParameterComment(@"user", @"The user information.", @"{""username"": ""johndoe"", ""email"": ""john@example.com""}", false)], [new XmlResponseComment(@"201", @"Successfully created the user.", @""), new XmlResponseComment(@"400", @"If the user data is invalid.", @"")]));
_cache.Add(new MemberKey(typeof(global::RouteHandlerExtensionMethods), MemberType.Method, "Put7", typeof(global::Microsoft.AspNetCore.Http.IResult), [typeof(global::System.Int32?), typeof(global::System.String)]), new XmlComment(@"Updates an existing record.", null, null, null, null, false, null, [new XmlParameterComment(@"id", @"Legacy ID parameter - use uuid instead.", null, true), new XmlParameterComment(@"uuid", @"Unique identifier for the record.", null, false)], [new XmlResponseComment(@"204", @"Update successful.", @""), new XmlResponseComment(@"404", @"Legacy response - will be removed.", @"")]));
+ _cache.Add(new MemberKey(typeof(global::RouteHandlerExtensionMethods), MemberType.Method, "Get8", typeof(global::System.Threading.Tasks.Task), []), new XmlComment(@"A summary of Get8.", null, null, null, null, false, null, null, null));
+ _cache.Add(new MemberKey(typeof(global::RouteHandlerExtensionMethods), MemberType.Method, "Get9", typeof(global::System.Threading.Tasks.ValueTask), []), new XmlComment(@"A summary of Get9.", null, null, null, null, false, null, null, null));
+ _cache.Add(new MemberKey(typeof(global::RouteHandlerExtensionMethods), MemberType.Method, "Get10", typeof(global::System.Threading.Tasks.Task), []), new XmlComment(@"A summary of Get10.", null, null, null, null, false, null, null, null));
+ _cache.Add(new MemberKey(typeof(global::RouteHandlerExtensionMethods), MemberType.Method, "Get11", typeof(global::System.Threading.Tasks.ValueTask), []), new XmlComment(@"A summary of Get11.", null, null, null, null, false, null, null, null));
+ _cache.Add(new MemberKey(typeof(global::RouteHandlerExtensionMethods), MemberType.Method, "Get12", typeof(global::System.Threading.Tasks.Task<>), []), new XmlComment(@"A summary of Get12.", null, null, null, null, false, null, null, null));
+ _cache.Add(new MemberKey(typeof(global::RouteHandlerExtensionMethods), MemberType.Method, "Get13", typeof(global::System.Threading.Tasks.ValueTask<>), []), new XmlComment(@"A summary of Get13.", null, null, null, null, false, null, null, null));
+ _cache.Add(new MemberKey(typeof(global::RouteHandlerExtensionMethods), MemberType.Method, "Get14", typeof(global::System.Threading.Tasks.Task<>), []), new XmlComment(@"A summary of Get14.", null, null, null, null, false, null, null, null));
+ _cache.Add(new MemberKey(typeof(global::RouteHandlerExtensionMethods), MemberType.Method, "Get15", typeof(global::System.Threading.Tasks.Task<>), []), new XmlComment(@"A summary of Get15.", null, null, null, null, false, null, null, null));
return _cache;
}