Skip to content

Unify handling of documentation IDs in OpenAPI XML comment generator #62691

Open
@captainsafia

Description

@captainsafia

Following an investigation on the issue reported at captainsafia/aspnet-openapi-xml#5 and the proposed solution at captainsafia/aspnet-openapi-xml#5 (comment) this is a prompt to resolve this issue in our current implementation.

Summary

XmlCommentGenerator.Parser currently produces different documentation-comment IDs for some symbols than the IDs contained in XML files that come from referenced projects or NuGet packages. Because the keys don’t match, valid comments are silently dropped and never reach the XmlCommentCache that the generator emits.

Current behavior

  1. In-memory ID generation
// src/OpenApi/gen/XmlCommentGenerator.Parser.cs
if (DocumentationCommentId.CreateDeclarationId(method) is string name)
{
    comments.Add((name, xml));
}

When the method symbol comes from the current compilation, Roslyn’s
CreateDeclarationId returns an ID that can include the return type, e.g.

M:Api.ProjectBoardApis.DeleteProjectBoard(System.Int32)~System.Threading.Tasks.Task
  1. XML file IDs

The same member in a referenced XML file is emitted by the C# compiler
without the return-type suffix:

<member name="M:Api.ProjectBoardApis.DeleteProjectBoard(System.Int32)">
  1. Merge step
if (DocumentationCommentId.GetFirstSymbolForDeclarationId(name, compilation) is ISymbol symbol)
{
    ...
}

When name is missing the ~returnType suffix the lookup fails, so the
comment is discarded. The generated cache therefore contains entries for the in-memory ID only.
Down-stream tooling that expects the compiler-style ID (the one in the XML
file) can no longer resolve the comment.

Desired behaviour

Both the IDs we emit and the IDs we use to query should match. DocumentationCommentId.GetFirstSymbolForDeclarationId should be in the
canonical compiler format (the same text that appears in the
element of an XML doc file).

Proposed fix

Area Change
Parser – collection phase Before calling comments.Add((name, xml)) normalise name with a new helper NormalizeDocId(string) that strips the ~ReturnType suffix for ordinary methods (retain it for op_Implicit / op_Explicit).
Parser – merge phase Apply the same NormalizeDocId to the key read from the XML file before the lookup.
Emitter The XmlCommentCache keys are whatever the parser produces. After normalisation they will exactly match the XML compiler output, so no change is needed here—the existing generator already writes whatever keys it receives.
Tests Add a unit test that passes an XML file containing a member likeM:Sample.Namespace.MyApi(System.Int32)and a source file that definesTask MyApi(int id).The test should assert that the cache contains one merged entry keyed by the compiler-style ID.

Metadata

Metadata

Assignees

Labels

area-minimalIncludes minimal APIs, endpoint filters, parameter binding, request delegate generator etcarea-mvcIncludes: MVC, Actions and Controllers, Localization, CORS, most templatesfeature-openapi

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions