diff --git a/src/OpenApi/gen/Helpers/AssemblyTypeSymbolsVisitor.cs b/src/OpenApi/gen/Helpers/AssemblyTypeSymbolsVisitor.cs
index 5f962a0c48fd..548ef98c2b84 100644
--- a/src/OpenApi/gen/Helpers/AssemblyTypeSymbolsVisitor.cs
+++ b/src/OpenApi/gen/Helpers/AssemblyTypeSymbolsVisitor.cs
@@ -44,7 +44,7 @@ public override void VisitNamedType(INamedTypeSymbol type)
{
_cancellationToken.ThrowIfCancellationRequested();
- if (!IsDeclaredInAssembly(type) || !_exportedTypes.Add(type))
+ if (!IsAccessibleType(type) || !_exportedTypes.Add(type))
{
return;
}
@@ -61,7 +61,7 @@ public override void VisitNamedType(INamedTypeSymbol type)
foreach (var property in properties)
{
_cancellationToken.ThrowIfCancellationRequested();
- if (IsDeclaredInAssembly(property) && _exportedProperties.Add(property))
+ if (IsAccessibleType(property) && _exportedProperties.Add(property))
{
property.Type.Accept(this);
}
@@ -70,13 +70,16 @@ public override void VisitNamedType(INamedTypeSymbol type)
foreach (var method in methods)
{
_cancellationToken.ThrowIfCancellationRequested();
- if (IsDeclaredInAssembly(method) && _exportedMethods.Add(method))
+ if (IsAccessibleType(method) && _exportedMethods.Add(method))
{
method.Accept(this);
}
}
}
- private bool IsDeclaredInAssembly(ISymbol symbol) =>
- SymbolEqualityComparer.Default.Equals(symbol.ContainingAssembly, assemblySymbol);
+ private bool IsAccessibleType(ISymbol symbol) =>
+ SymbolEqualityComparer.Default.Equals(symbol.ContainingAssembly, assemblySymbol)
+ && (symbol.DeclaredAccessibility == Accessibility.Public ||
+ symbol.DeclaredAccessibility == Accessibility.Internal ||
+ symbol.DeclaredAccessibility == Accessibility.ProtectedOrInternal);
}
diff --git a/src/OpenApi/test/Microsoft.AspNetCore.OpenApi.SourceGenerators.Tests/AdditionalTextsTests.Schemas.cs b/src/OpenApi/test/Microsoft.AspNetCore.OpenApi.SourceGenerators.Tests/AdditionalTextsTests.Schemas.cs
index 04a8afbd2422..b30dee1a8c3e 100644
--- a/src/OpenApi/test/Microsoft.AspNetCore.OpenApi.SourceGenerators.Tests/AdditionalTextsTests.Schemas.cs
+++ b/src/OpenApi/test/Microsoft.AspNetCore.OpenApi.SourceGenerators.Tests/AdditionalTextsTests.Schemas.cs
@@ -1,6 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using System.Globalization;
using System.Text.Json.Nodes;
using Microsoft.OpenApi.Models;
@@ -67,6 +68,34 @@ public class BoardItem
///
public string Name { get; set; }
}
+
+ private class Element
+ {
+ ///
+ /// The unique identifier for the element.
+ ///
+ ///
+ /// This won't be emitted since it is a public
+ /// property on a private class.
+ ///
+ public string Name { get; set; }
+ }
+
+ protected internal class ProtectedInternalElement
+ {
+ ///
+ /// The unique identifier for the element.
+ ///
+ public string Name { get; set; }
+ }
+
+ protected class ProtectedElement
+ {
+ ///
+ /// The unique identifier for the element.
+ ///
+ public string Name { get; set; }
+ }
}
///
@@ -201,18 +230,17 @@ await SnapshotTestHelper.VerifyOpenApi(compilation, additionalAssemblies, docume
var longTypeExample = Assert.IsAssignableFrom(typeWithExamples.Properties["longType"].Example);
Assert.Equal(1234567890123456789, longTypeExample.GetValue());
- // Broken due to https://github.com/microsoft/OpenAPI.NET/issues/2137
- // var doubleTypeExample = Assert.IsAssignableFrom(typeWithExamples.Properties["doubleType"].Example);
- // Assert.Equal("3.14", doubleTypeExample.GetValue());
+ var doubleTypeExample = Assert.IsAssignableFrom(typeWithExamples.Properties["doubleType"].Example);
+ Assert.Equal(3.14, doubleTypeExample.GetValue());
- // var floatTypeExample = Assert.IsAssignableFrom(typeWithExamples.Properties["floatType"].Example);
- // Assert.Equal(3.14f, floatTypeExample.GetValue());
+ var floatTypeExample = Assert.IsAssignableFrom(typeWithExamples.Properties["floatType"].Example);
+ Assert.Equal(3.14f, floatTypeExample.GetValue());
- // var dateTimeTypeExample = Assert.IsAssignableFrom(typeWithExamples.Properties["dateTimeType"].Example);
- // Assert.Equal(DateTime.Parse("2022-01-01T00:00:00Z", CultureInfo.InvariantCulture), dateTimeTypeExample.GetValue());
+ var dateTimeTypeExample = Assert.IsAssignableFrom(typeWithExamples.Properties["dateTimeType"].Example);
+ Assert.Equal(new DateTime(2022, 01, 01), dateTimeTypeExample.GetValue());
- // var dateOnlyTypeExample = Assert.IsAssignableFrom(typeWithExamples.Properties["dateOnlyType"].Example);
- // Assert.Equal(DateOnly.Parse("2022-01-01", CultureInfo.InvariantCulture), dateOnlyTypeExample.GetValue());
+ var dateOnlyTypeExample = Assert.IsAssignableFrom(typeWithExamples.Properties["dateOnlyType"].Example);
+ Assert.Equal("2022-01-01", dateOnlyTypeExample.GetValue());
var stringTypeExample = Assert.IsAssignableFrom(typeWithExamples.Properties["stringType"].Example);
Assert.Equal("Hello, World!", stringTypeExample.GetValue());
@@ -223,15 +251,14 @@ await SnapshotTestHelper.VerifyOpenApi(compilation, additionalAssemblies, docume
var byteTypeExample = Assert.IsAssignableFrom(typeWithExamples.Properties["byteType"].Example);
Assert.Equal(255, byteTypeExample.GetValue());
- // Broken due to https://github.com/microsoft/OpenAPI.NET/issues/2137
- // var timeOnlyTypeExample = Assert.IsAssignableFrom(typeWithExamples.Properties["timeOnlyType"].Example);
- // Assert.Equal(TimeOnly.Parse("12:30:45", CultureInfo.InvariantCulture), timeOnlyTypeExample.GetValue());
+ var timeOnlyTypeExample = Assert.IsAssignableFrom(typeWithExamples.Properties["timeOnlyType"].Example);
+ Assert.Equal("12:30:45", timeOnlyTypeExample.GetValue());
- // var timeSpanTypeExample = Assert.IsAssignableFrom(typeWithExamples.Properties["timeSpanType"].Example);
- // Assert.Equal(TimeSpan.Parse("P3DT4H5M", CultureInfo.InvariantCulture), timeSpanTypeExample.GetValue());
+ var timeSpanTypeExample = Assert.IsAssignableFrom(typeWithExamples.Properties["timeSpanType"].Example);
+ Assert.Equal("P3DT4H5M", timeSpanTypeExample.GetValue());
- // var decimalTypeExample = Assert.IsAssignableFrom(typeWithExamples.Properties["decimalType"].Example);
- // Assert.Equal(3.14159265359m, decimalTypeExample.GetValue());
+ var decimalTypeExample = Assert.IsAssignableFrom(typeWithExamples.Properties["decimalType"].Example);
+ Assert.Equal(3.14159265359m, decimalTypeExample.GetValue());
var uriTypeExample = Assert.IsAssignableFrom(typeWithExamples.Properties["uriType"].Example);
Assert.Equal("https://example.com", uriTypeExample.GetValue());
diff --git a/src/OpenApi/test/Microsoft.AspNetCore.OpenApi.SourceGenerators.Tests/SchemaTests.cs b/src/OpenApi/test/Microsoft.AspNetCore.OpenApi.SourceGenerators.Tests/SchemaTests.cs
index 19760ed60d63..1caa65378abd 100644
--- a/src/OpenApi/test/Microsoft.AspNetCore.OpenApi.SourceGenerators.Tests/SchemaTests.cs
+++ b/src/OpenApi/test/Microsoft.AspNetCore.OpenApi.SourceGenerators.Tests/SchemaTests.cs
@@ -27,6 +27,7 @@ public async Task SupportsXmlCommentsOnSchemas()
app.MapPost("/todo", (Todo todo) => { });
app.MapPost("/project", (Project project) => { });
app.MapPost("/board", (ProjectBoard.BoardItem boardItem) => { });
+app.MapPost("/protected-internal-element", (ProjectBoard.ProtectedInternalElement element) => { });
app.MapPost("/project-record", (ProjectRecord project) => { });
app.MapPost("/todo-with-description", (TodoWithDescription todo) => { });
app.MapPost("/type-with-examples", (TypeWithExamples typeWithExamples) => { });
@@ -58,6 +59,43 @@ public class BoardItem
{
public string Name { get; set; }
}
+
+ ///
+ /// No XML comment processed here.
+ ///
+ private class Element
+ {
+ ///
+ /// The unique identifier for the element.
+ ///
+ ///
+ /// This won't be emitted since it is a public
+ /// property on a private class.
+ ///
+ public string Name { get; set; }
+ }
+
+ ///
+ /// Can find this XML comment.
+ ///
+ protected internal class ProtectedInternalElement
+ {
+ ///
+ /// The unique identifier for the element.
+ ///
+ public string Name { get; set; }
+ }
+
+ ///
+ /// No XML comment processed here.
+ ///
+ protected class ProtectedElement
+ {
+ ///
+ /// The unique identifier for the element.
+ ///
+ public string Name { get; set; }
+ }
}
///
@@ -130,7 +168,7 @@ public interface IUser
}
///
-public class User : IUser
+internal class User : IUser
{
///
public int Id { get; set; }
@@ -155,6 +193,11 @@ await SnapshotTestHelper.VerifyOpenApi(compilation, document =>
var board = path.RequestBody.Content["application/json"].Schema;
Assert.Equal("An item on the board.", board.Description);
+ path = document.Paths["/protected-internal-element"].Operations[OperationType.Post];
+ var element = path.RequestBody.Content["application/json"].Schema;
+ Assert.Equal("The unique identifier for the element.", element.Properties["name"].Description);
+ Assert.Equal("Can find this XML comment.", element.Description);
+
path = document.Paths["/project-record"].Operations[OperationType.Post];
project = path.RequestBody.Content["application/json"].Schema;
@@ -179,18 +222,17 @@ await SnapshotTestHelper.VerifyOpenApi(compilation, document =>
var longTypeExample = Assert.IsAssignableFrom(typeWithExamples.Properties["longType"].Example);
Assert.Equal(1234567890123456789, longTypeExample.GetValue());
- // Broken due to https://github.com/microsoft/OpenAPI.NET/issues/2137
- // var doubleTypeExample = Assert.IsAssignableFrom(typeWithExamples.Properties["doubleType"].Example);
- // Assert.Equal("3.14", doubleTypeExample.GetValue());
+ var doubleTypeExample = Assert.IsAssignableFrom(typeWithExamples.Properties["doubleType"].Example);
+ Assert.Equal(3.14, doubleTypeExample.GetValue());
- // var floatTypeExample = Assert.IsAssignableFrom(typeWithExamples.Properties["floatType"].Example);
- // Assert.Equal(3.14f, floatTypeExample.GetValue());
+ var floatTypeExample = Assert.IsAssignableFrom(typeWithExamples.Properties["floatType"].Example);
+ Assert.Equal(3.14f, floatTypeExample.GetValue());
- // var dateTimeTypeExample = Assert.IsAssignableFrom(typeWithExamples.Properties["dateTimeType"].Example);
- // Assert.Equal(DateTime.Parse("2022-01-01T00:00:00Z", CultureInfo.InvariantCulture), dateTimeTypeExample.GetValue());
+ var dateTimeTypeExample = Assert.IsAssignableFrom(typeWithExamples.Properties["dateTimeType"].Example);
+ Assert.Equal(new DateTime(2022, 01, 01), dateTimeTypeExample.GetValue());
- // var dateOnlyTypeExample = Assert.IsAssignableFrom(typeWithExamples.Properties["dateOnlyType"].Example);
- // Assert.Equal(DateOnly.Parse("2022-01-01", CultureInfo.InvariantCulture), dateOnlyTypeExample.GetValue());
+ var dateOnlyTypeExample = Assert.IsAssignableFrom(typeWithExamples.Properties["dateOnlyType"].Example);
+ Assert.Equal("2022-01-01", dateOnlyTypeExample.GetValue());
var stringTypeExample = Assert.IsAssignableFrom(typeWithExamples.Properties["stringType"].Example);
Assert.Equal("Hello, World!", stringTypeExample.GetValue());
@@ -201,15 +243,14 @@ await SnapshotTestHelper.VerifyOpenApi(compilation, document =>
var byteTypeExample = Assert.IsAssignableFrom(typeWithExamples.Properties["byteType"].Example);
Assert.Equal(255, byteTypeExample.GetValue());
- // Broken due to https://github.com/microsoft/OpenAPI.NET/issues/2137
- // var timeOnlyTypeExample = Assert.IsAssignableFrom(typeWithExamples.Properties["timeOnlyType"].Example);
- // Assert.Equal(TimeOnly.Parse("12:30:45", CultureInfo.InvariantCulture), timeOnlyTypeExample.GetValue());
+ var timeOnlyTypeExample = Assert.IsAssignableFrom(typeWithExamples.Properties["timeOnlyType"].Example);
+ Assert.Equal("12:30:45", timeOnlyTypeExample.GetValue());
- // var timeSpanTypeExample = Assert.IsAssignableFrom(typeWithExamples.Properties["timeSpanType"].Example);
- // Assert.Equal(TimeSpan.Parse("P3DT4H5M", CultureInfo.InvariantCulture), timeSpanTypeExample.GetValue());
+ var timeSpanTypeExample = Assert.IsAssignableFrom(typeWithExamples.Properties["timeSpanType"].Example);
+ Assert.Equal("P3DT4H5M", timeSpanTypeExample.GetValue());
- // var decimalTypeExample = Assert.IsAssignableFrom(typeWithExamples.Properties["decimalType"].Example);
- // Assert.Equal(3.14159265359m, decimalTypeExample.GetValue());
+ var decimalTypeExample = Assert.IsAssignableFrom(typeWithExamples.Properties["decimalType"].Example);
+ Assert.Equal(3.14159265359m, decimalTypeExample.GetValue());
var uriTypeExample = Assert.IsAssignableFrom(typeWithExamples.Properties["uriType"].Example);
Assert.Equal("https://example.com", uriTypeExample.GetValue());
diff --git a/src/OpenApi/test/Microsoft.AspNetCore.OpenApi.SourceGenerators.Tests/snapshots/SchemaTests.SupportsXmlCommentsOnSchemas#OpenApiXmlCommentSupport.generated.verified.cs b/src/OpenApi/test/Microsoft.AspNetCore.OpenApi.SourceGenerators.Tests/snapshots/SchemaTests.SupportsXmlCommentsOnSchemas#OpenApiXmlCommentSupport.generated.verified.cs
index 1eab4e75a810..0a5b3be9e07f 100644
--- a/src/OpenApi/test/Microsoft.AspNetCore.OpenApi.SourceGenerators.Tests/snapshots/SchemaTests.SupportsXmlCommentsOnSchemas#OpenApiXmlCommentSupport.generated.verified.cs
+++ b/src/OpenApi/test/Microsoft.AspNetCore.OpenApi.SourceGenerators.Tests/snapshots/SchemaTests.SupportsXmlCommentsOnSchemas#OpenApiXmlCommentSupport.generated.verified.cs
@@ -189,8 +189,10 @@ private static Dictionary GenerateCacheEntries()
_cache.Add(new MemberKey(typeof(global::Todo), MemberType.Type, null, null, []), new XmlComment(@"This is a todo item.", null, null, null, null, false, null, null, null));
_cache.Add(new MemberKey(typeof(global::Project), MemberType.Type, null, null, []), new XmlComment(@"The project that contains Todo items.", null, null, null, null, false, null, null, null));
_cache.Add(new MemberKey(typeof(global::ProjectBoard.BoardItem), MemberType.Type, null, null, []), new XmlComment(@"An item on the board.", null, null, null, null, false, null, null, null));
+ _cache.Add(new MemberKey(typeof(global::ProjectBoard.ProtectedInternalElement), MemberType.Type, null, null, []), new XmlComment(@"Can find this XML comment.", null, null, null, null, false, null, null, null));
_cache.Add(new MemberKey(typeof(global::ProjectRecord), MemberType.Type, null, null, []), new XmlComment(@"The project that contains Todo items.", null, null, null, null, false, null, [new XmlParameterComment(@"Name", @"The name of the project.", null, false), new XmlParameterComment(@"Description", @"The description of the project.", null, false)], null));
_cache.Add(new MemberKey(typeof(global::User), MemberType.Type, null, null, []), new XmlComment(null, null, null, null, null, false, null, null, null));
+ _cache.Add(new MemberKey(typeof(global::ProjectBoard.ProtectedInternalElement), MemberType.Property, "Name", null, []), new XmlComment(@"The unique identifier for the element.", null, null, null, null, false, null, null, null));
_cache.Add(new MemberKey(typeof(global::ProjectRecord), MemberType.Property, "Name", null, []), new XmlComment(@"The name of the project.", null, null, null, null, false, null, null, null));
_cache.Add(new MemberKey(typeof(global::ProjectRecord), MemberType.Property, "Description", null, []), new XmlComment(@"The description of the project.", null, null, null, null, false, null, null, null));
_cache.Add(new MemberKey(typeof(global::TodoWithDescription), MemberType.Property, "Id", null, []), new XmlComment(@"The identifier of the todo.", null, null, null, null, false, null, null, null));