You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
1. "open" matches a keyword token, not a declaration node
In tree-sitter-fsharp 0.3.11 (fsharp/src/node-types.json), open is "named": false — it is the bare openkeyword token. The F# import declaration node is import_decl ("named": true, one long_identifier child).
The open keyword token always spans exactly one line, so start.row < end.row in the emit guard is never true. The arm is unreachable in effect.
2. "xml_doc" never spans more than one line
The grammar emits one xml_doc node per /// line, so a multi-line doc block is N single-line nodes, and the start_position().row != end_position().row guard is never satisfied. The arm is dead too.
Reproduction
Adding to the fixture in test_folding_range_on_fsharp_file (src/sharplsp/tests/e2e_modules/folding.rs):
moduleMopenSystem(* a multi-line block comment *)/// Computes the area of a shape./// The doc block spans two lines, so it folds.typeShape=...
textDocument/foldingRange returns 4 ranges — three region folds and exactly onecomment fold (the (* *) block, lines 2–3). There is no imports fold for open System and no comment fold for the two /// lines.
The existing assertion passes only because kinds.contains(&"comment") is satisfied by the (* *) block alone.
Expected
Consecutive /// (xml_doc) sibling nodes should merge into a single comment fold spanning the run — this is what Visual Studio / Rider / C# Dev Kit do for /// blocks, and F# is a first-class citizen (CLAUDE.md aim Expand Forge LSP features, editor tooling, and CI packaging #2).
Consecutive import_decl (F#) / using_directive (C#) siblings should merge into a single imports fold. Note the C# side has the same latent problem: a one-line using X; also fails the start.row < end.row guard, so FoldingRangeKind::Imports is likely never emitted for either language today.
Both need sibling-run grouping in collect_folding, not just a node-kind rename.
Notes
Coverage does not catch this: the arms share instrumented lines with live arms, so the file reports 220/224 lines covered on both Linux CI and macOS.
Found while auditing PR #218's Rust coverage gate.
Summary
src/sharplsp/src/syntax.rscollect_foldinggained F# node kinds on PR #218. Two of the new match arms can never produce a fold:1.
"open"matches a keyword token, not a declaration nodeIn
tree-sitter-fsharp0.3.11 (fsharp/src/node-types.json),openis"named": false— it is the bareopenkeyword token. The F# import declaration node isimport_decl("named": true, onelong_identifierchild).The
openkeyword token always spans exactly one line, sostart.row < end.rowin the emit guard is never true. The arm is unreachable in effect.2.
"xml_doc"never spans more than one lineThe grammar emits one
xml_docnode per///line, so a multi-line doc block is N single-line nodes, and thestart_position().row != end_position().rowguard is never satisfied. The arm is dead too.Reproduction
Adding to the fixture in
test_folding_range_on_fsharp_file(src/sharplsp/tests/e2e_modules/folding.rs):textDocument/foldingRangereturns 4 ranges — threeregionfolds and exactly onecommentfold (the(* *)block, lines 2–3). There is noimportsfold foropen Systemand nocommentfold for the two///lines.The existing assertion passes only because
kinds.contains(&"comment")is satisfied by the(* *)block alone.Expected
///(xml_doc) sibling nodes should merge into a singlecommentfold spanning the run — this is what Visual Studio / Rider / C# Dev Kit do for///blocks, and F# is a first-class citizen (CLAUDE.md aim Expand Forge LSP features, editor tooling, and CI packaging #2).import_decl(F#) /using_directive(C#) siblings should merge into a singleimportsfold. Note the C# side has the same latent problem: a one-lineusing X;also fails thestart.row < end.rowguard, soFoldingRangeKind::Importsis likely never emitted for either language today.Both need sibling-run grouping in
collect_folding, not just a node-kind rename.Notes
Coverage does not catch this: the arms share instrumented lines with live arms, so the file reports 220/224 lines covered on both Linux CI and macOS.
Found while auditing PR #218's Rust coverage gate.