Skip to content

Commit 6a30305

Browse files
github-actions[bot]CopilotCopilotsergey-tihon
authored
[Repo Assist] improve: enrich XML documentation for generated API methods (#349)
* improve: enrich XML documentation for generated methods with param descriptions and remarks - Build structured XML doc (<summary>, <remarks>, <param>) instead of plain text - Add <param name="..."> entries for OpenAPI parameters that have descriptions - Add <remarks> for operation.Description when it differs from Summary - Apply same improvement to both v2 (SwaggerClientProvider) and v3 (OpenApiClientProvider) - XML-escape description text to prevent malformed doc comments - Resolves the TODO comment that has been in the code since the initial implementation 241 unit tests pass; format check passes. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * ci: trigger checks * refactor: extract shared XML doc generation to Utils.fs Agent-Logs-Url: https://github.com/fsprojects/SwaggerProvider/sessions/1ebc143c-89b5-4035-8920-2271a97cde2b Co-authored-by: sergey-tihon <1197905+sergey-tihon@users.noreply.github.com> --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: sergey-tihon <1197905+sergey-tihon@users.noreply.github.com>
1 parent a8f5a63 commit 6a30305

File tree

3 files changed

+49
-6
lines changed

3 files changed

+49
-6
lines changed

src/SwaggerProvider.DesignTime/Utils.fs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,35 @@ module SchemaReader =
332332
resolvedPath
333333
}
334334

335+
module XmlDoc =
336+
open System
337+
338+
let private escapeXml(s: string) =
339+
s.Replace("&", "&amp;").Replace("<", "&lt;").Replace(">", "&gt;")
340+
341+
/// Builds a structured XML doc string from summary, description, and parameter descriptions.
342+
/// paramDescriptions is a sequence of (camelCaseName, description) pairs.
343+
let buildXmlDoc (summary: string) (description: string) (paramDescriptions: (string * string) seq) =
344+
let summaryPart =
345+
if String.IsNullOrEmpty summary then
346+
""
347+
else
348+
$"<summary>{escapeXml summary}</summary>"
349+
350+
let remarksPart =
351+
if String.IsNullOrEmpty description || description = summary then
352+
""
353+
else
354+
$"<remarks>{escapeXml description}</remarks>"
355+
356+
let paramParts =
357+
[ for name, desc in paramDescriptions do
358+
if not(String.IsNullOrWhiteSpace desc) then
359+
yield $"<param name=\"{name}\">{escapeXml desc}</param>" ]
360+
|> String.concat ""
361+
362+
summaryPart + remarksPart + paramParts
363+
335364
type UniqueNameGenerator(?occupiedNames: string seq) =
336365
let hash = System.Collections.Generic.HashSet<_>()
337366

src/SwaggerProvider.DesignTime/v2/OperationCompiler.fs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -252,8 +252,14 @@ type OperationCompiler(schema: SwaggerObject, defCompiler: DefinitionCompiler, i
252252
| true, None -> (awaitTask responseUnit).Raw
253253
)
254254

255-
if not <| String.IsNullOrEmpty(op.Summary) then
256-
m.AddXmlDoc(op.Summary) // TODO: Use description of parameters in docs
255+
let xmlDoc =
256+
let paramDescriptions =
257+
[ for p in op.Parameters -> niceCamelName p.Name, p.Description ]
258+
259+
XmlDoc.buildXmlDoc op.Summary op.Description paramDescriptions
260+
261+
if not(String.IsNullOrEmpty xmlDoc) then
262+
m.AddXmlDoc xmlDoc
257263

258264
if op.Deprecated then
259265
m.AddObsoleteAttribute("Operation is deprecated", false)

src/SwaggerProvider.DesignTime/v3/OperationCompiler.fs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ type OperationCompiler(schema: OpenApiDocument, defCompiler: DefinitionCompiler,
9696
let (|NoMediaType|_|)(content: IDictionary<string, OpenApiMediaType>) =
9797
if isNull content || content.Count = 0 then Some() else None
9898

99-
let payloadMime, parameters, ctArgIndex =
99+
let payloadTy, payloadMime, parameters, ctArgIndex =
100100
/// handles de-duplicating Swagger parameter names if the same parameter name
101101
/// appears in multiple locations in a given operation definition.
102102
let uniqueParamName usedNames (param: IOpenApiParameter) =
@@ -195,7 +195,7 @@ type OperationCompiler(schema: OpenApiDocument, defCompiler: DefinitionCompiler,
195195

196196
ctArgIndex, requiredProvidedParams @ optionalProvidedParams @ [ ctParam ]
197197

198-
payloadTy.ToMediaType(), parameters, ctArgIndex
198+
payloadTy, payloadTy.ToMediaType(), parameters, ctArgIndex
199199

200200
// find the inner type value
201201
let retMimeAndTy =
@@ -494,8 +494,16 @@ type OperationCompiler(schema: OpenApiDocument, defCompiler: DefinitionCompiler,
494494
| _ -> Expr.Coerce(<@ RuntimeHelpers.asyncCast t %(awaitTask responseObj) @>, overallReturnType)
495495
)
496496

497-
if not <| String.IsNullOrEmpty(operation.Summary) then
498-
m.AddXmlDoc(operation.Summary) // TODO: Use description of parameters in docs
497+
let xmlDoc =
498+
let paramDescriptions =
499+
[ for p in openApiParameters -> niceCamelName p.Name, p.Description
500+
if not(isNull operation.RequestBody) then
501+
yield niceCamelName(payloadTy.ToString()), operation.RequestBody.Description ]
502+
503+
XmlDoc.buildXmlDoc operation.Summary operation.Description paramDescriptions
504+
505+
if not(String.IsNullOrEmpty xmlDoc) then
506+
m.AddXmlDoc xmlDoc
499507

500508
if operation.Deprecated then
501509
m.AddObsoleteAttribute("Operation is deprecated", false)

0 commit comments

Comments
 (0)