Skip to content

fix(lsp): replace text heuristics with CST-aware detection, fix diagnostic locations#95

Merged
avrabe merged 2 commits intomainfrom
fix/lsp-hardening
Apr 2, 2026
Merged

fix(lsp): replace text heuristics with CST-aware detection, fix diagnostic locations#95
avrabe merged 2 commits intomainfrom
fix/lsp-hardening

Conversation

@avrabe
Copy link
Copy Markdown
Contributor

@avrabe avrabe commented Apr 2, 2026

Summary

Two safety-relevant LSP fixes driven by STPA analysis (H-1: false negatives, STPA-REQ-020: no diagnostic suppression):

P0: Diagnostics at (0,0) fixed. Analysis diagnostics (naming rules, category rules) now point to the actual declaration in source, not line 0. New resolve_path_to_range() walks the CST to find named elements.

P1: Text heuristics replaced with CST-aware detection. completion_context() and is_in_section() used backward text scanning (rfind, ends_with) — matching keywords in comments/strings and misidentifying sections. Replaced with completion_context_from_cst() using rowan token ancestry:

  • Section detection via CST node kinds (PROPERTY_SECTION, FEATURE_SECTION, etc.)
  • Keyword detection via token kinds (COLON, WITH_KW, PORT_KW)
  • Falls back to text matching only when CST is unavailable

What this fixes

  • Keywords in comments no longer trigger false property/section context
  • Diagnostics actually appear at the right source location
  • Non-standard formatting no longer confuses completion suggestions

Test plan

  • 10 new tests (7 completion context + 3 path resolution)
  • 31 total LSP tests pass, 0 failures
  • Clippy clean
  • CI passes

🤖 Generated with Claude Code

avrabe and others added 2 commits April 2, 2026 13:48
…ostic locations

Two safety-relevant fixes to the LSP server:

P0: Analysis diagnostics no longer placed at (0,0). resolve_path_to_range()
walks the CST to find the named element and maps it to a source Range, so
naming/category diagnostics point to the actual declaration.

P1: completion_context() and is_in_section() text heuristics replaced with
completion_context_from_cst() which uses rowan ancestor walking:
- Section detection via CST node kinds (PROPERTY_SECTION, FEATURE_SECTION, etc.)
- Keyword detection via token kinds (COLON, WITH_KW, PORT_KW, DATA_KW)
- Falls back to simple text matching only when CST is unavailable

The old heuristics matched keywords in comments/strings and used rfind()
which could jump to the wrong occurrence. The CST-based approach is immune
to these false positives.

Adds 10 new tests: 7 for completion context (properties, features, colon,
with, comment false positive, top-level, subcomponents) and 3 for path
resolution (found, missing, single-element).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 2, 2026

Codecov Report

❌ Patch coverage is 77.13004% with 51 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
crates/spar-cli/src/lsp.rs 77.13% 51 Missing ⚠️

📢 Thoughts on this report? Let us know!

@avrabe avrabe merged commit 16f4eb6 into main Apr 2, 2026
10 of 11 checks passed
@avrabe avrabe deleted the fix/lsp-hardening branch April 2, 2026 18:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant