Report XML doc parameter names as related symbol uses - #20637
xperiandri wants to merge 3 commits into
Conversation
`XmlDoc` keeps the range of every `///` line and lists the `name` and `cref` attribute values it contains with their source ranges. The checker reports each `<param>`, `<paramref>`, `<typeparam>` and `<typeparamref>` name that matches a parameter or type parameter of the documented declaration as a `RelatedSymbolUseKind.XmlDocParameter` use, for let-bound functions, members, primary constructors, union case fields and signature-file vals. The kind is opt-in: `GetUsesOfSymbolInFile` returns it only when asked for, the `ItemKeyStore` behind Find All References never receives it, and semantic classification ignores it. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
✅ Release notes checked
|
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
Covered cases (
Scanner ( Reverting the emission in |
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
XML scanning and parameter collection miss valid cases and can produce incorrect references.
Review effort: Lite
Findings: 2
Open (2)
What changed in this PR
Adds opt-in XML documentation parameter references to compiler symbol-use data for future rename support.
Changes:
- Tracks XML documentation ranges and attribute references.
- Reports matching parameter and type-parameter references.
- Updates filtering, tests, API baseline, and release notes.
| File | Description |
|---|---|
tests/FSharp.Compiler.Service.Tests/XmlDocTests.fs |
XML reference scanning tests |
tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.bsl |
API baseline update |
tests/FSharp.Compiler.ComponentTests/FSharpChecker/SemanticClassificationRegressions.fs |
Classification regression tests |
tests/FSharp.Compiler.ComponentTests/FSharpChecker/FindReferences.fs |
Related-use tests |
src/Compiler/SyntaxTree/XmlDoc.fsi |
XML documentation reference API |
src/Compiler/SyntaxTree/XmlDoc.fs |
XML documentation scanning and ranges |
src/Compiler/Service/TransparentCompiler.fs |
Filters documentation uses |
src/Compiler/Service/SemanticClassification.fs |
Excludes documentation classification |
src/Compiler/Service/IncrementalBuild.fs |
Filters documentation uses |
src/Compiler/Checking/RelatedSymbolUse.fs |
Adds XML documentation use kind |
src/Compiler/Checking/NameResolution.fsi |
Reporting API declaration |
src/Compiler/Checking/NameResolution.fs |
Reports matching documentation references |
src/Compiler/Checking/Expressions/CheckExpressions.fs |
Reports function and member parameter references |
src/Compiler/Checking/CheckIncrementalClasses.fs |
Reports constructor references |
src/Compiler/Checking/CheckDeclarations.fs |
Reports type and union-case references |
docs/release-notes/.FSharp.Compiler.Service/11.0.200.md |
Release note |
| let rec find i = | ||
| match text.IndexOf(attribute, i, StringComparison.Ordinal) with | ||
| | -1 -> ValueNone | ||
| | at when at >= close -> ValueNone | ||
| | at -> | ||
| let mutable j = at + attribute.Length | ||
|
|
There was a problem hiding this comment.
Confirmed: <param notname="wrong" name="x"> reported wrong. The scanner now walks each tag's attributes as tokens and compares whole names, which also keeps a > inside a quoted value from ending the tag. Covered by only a whole attribute name matches, and a quoted > does not end the tag. Fixed in 008cb20.
| let scan (lines: string[]) (lineRanges: range[]) = | ||
| [| | ||
| for i in 0 .. lines.Length - 1 do | ||
| let text = lines[i] | ||
| let m = lineRanges[i] |
There was a problem hiding this comment.
Confirmed: a name on the line after <param was missed. The whole comment is now scanned as one text and each value is mapped back to its /// line. A value that itself runs over a line break has no single-line range, so it is still skipped. Covered by a tag whose attributes run over several lines and a value that runs over a line break yields nothing. Fixed in 008cb20.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
The scanner looked for the attribute name as a substring of each line, so `<param notname="wrong" name="x">` reported `wrong`, and a tag whose `name` sat on the next `///` line reported nothing. It now walks the attributes of each tag one at a time over the whole comment, keeps a `>` inside a quoted value from ending the tag, maps each value back to its line, and skips a value that runs over a line break. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
🔍 Tooling Safety Check — Affects-Design-Time
|

Fixes #15134
Renaming a parameter in Visual Studio leaves
<param name="x">,<paramref>,<typeparam>and<typeparamref>in the declaration's///comment untouched (#20630), because the compiler kept a single range for the whole comment and reported nothing inside it.XmlDocnow keeps the range of every///line and lists itsnameandcrefattribute values with their source ranges, and the checker reports eachnamethat matches a parameter or type parameter of the declaration as aRelatedSymbolUseKind.XmlDocParameteruse — for let-bound functions, members, primary constructors, union case fields and signature-file vals.The new kind is opt-in:
GetUsesOfSymbolInFilereturns it only when asked for, and Find All References and semantic classification never see it, so symbol search stays free of documentation hits. The editor change that turns it into a rename of the tags follows in a separate PR.🤖 Generated with Claude Code