fix(lsp): scan injected languages for diagnostics#2528
Conversation
📝 WalkthroughWalkthroughThe LSP diagnostic flow now performs per-injected-language scans instead of a single global pass and requires Changes
Sequence DiagramsequenceDiagram
participant Client as LSP Client
participant Server as LSP Server
participant Gatherer as Injection Gatherer
participant Rules as Rule Engine
participant Scanner as Per-Lang Scanner
participant Aggregator as Result Aggregator
Client->>Server: Request diagnostics for document (HTML with TS)
Server->>Gatherer: Collect injected-language contexts
Gatherer-->>Server: [TypeScript, ...]
loop for each injected language
Server->>Rules: Get rules for language
Rules-->>Server: Language-specific rule refs
Server->>Scanner: Run scan on injected subtree
Scanner-->>Server: (rule, matches) pairs
Server->>Aggregator: Add diagnostics & fixes
end
Aggregator-->>Server: Aggregated diagnostics & code actions
Server-->>Client: Publish diagnostics & respond to code action requests
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 minutes Possibly related issues
Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@crates/lsp/src/lib.rs`:
- Around line 291-297: The code currently returns early when
rule_refs.is_empty(), which skips calling
CombinedScan::set_unused_suppression_rule and loses unused-suppression hints for
languages with zero rules; instead ensure the unused-suppression rule is always
set: create the unused_suppression_rule via
CombinedScan::unused_config(Severity::Hint, injected.lang().clone()) and call
CombinedScan::new(rule_refs) (or create an empty CombinedScan) and then call
scan.set_unused_suppression_rule(&unused_suppression_rule) before any early
continue or skip logic so that set_unused_suppression_rule runs even when
rule_refs.is_empty().
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 65bd0178-1fd1-45cf-8875-6a03f4c8eb01
📒 Files selected for processing (2)
crates/lsp/src/lib.rscrates/lsp/tests/basic.rs
a119b4d to
8e6230f
Compare
There was a problem hiding this comment.
♻️ Duplicate comments (1)
crates/lsp/src/lib.rs (1)
290-297:⚠️ Potential issue | 🟡 MinorDon’t skip unused-suppression scanning when a language has no rules.
The
continueon Line 291 still bypassesset_unused_suppression_rule, so host or injected regions with zero configured rules lose the unused-suppression hint entirely.CombinedScan::new(rule_refs)needs to run even for an empty rule set here.Suggested fix
let rule_refs = rules.get_rule_from_lang(&path, injected.lang().clone()); - if rule_refs.is_empty() { - continue; - } let unused_suppression_rule = CombinedScan::unused_config(Severity::Hint, injected.lang().clone()); let mut scan = CombinedScan::new(rule_refs); scan.set_unused_suppression_rule(&unused_suppression_rule);🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@crates/lsp/src/lib.rs` around lines 290 - 297, The current early return skips creating a CombinedScan and setting the unused-suppression hint when rules.get_rule_from_lang(&path, injected.lang().clone()) yields an empty rule_refs; remove the continue and always construct CombinedScan::new(rule_refs) (even when empty), then call scan.set_unused_suppression_rule(&unused_suppression_rule) using CombinedScan::unused_config(Severity::Hint, injected.lang().clone()); this ensures the unused-suppression hint is applied for host or injected regions with zero configured rules while preserving existing logic that processes non-empty rule sets.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In `@crates/lsp/src/lib.rs`:
- Around line 290-297: The current early return skips creating a CombinedScan
and setting the unused-suppression hint when rules.get_rule_from_lang(&path,
injected.lang().clone()) yields an empty rule_refs; remove the continue and
always construct CombinedScan::new(rule_refs) (even when empty), then call
scan.set_unused_suppression_rule(&unused_suppression_rule) using
CombinedScan::unused_config(Severity::Hint, injected.lang().clone()); this
ensures the unused-suppression hint is applied for host or injected regions with
zero configured rules while preserving existing logic that processes non-empty
rule sets.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: a48e2562-6841-4d7f-a44c-3b84af7c6e8c
📒 Files selected for processing (2)
crates/lsp/src/lib.rscrates/lsp/tests/basic.rs
🚧 Files skipped from review as they are similar to previous changes (1)
- crates/lsp/tests/basic.rs
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #2528 +/- ##
=======================================
Coverage 84.47% 84.48%
=======================================
Files 113 113
Lines 18685 18686 +1
=======================================
+ Hits 15784 15786 +2
+ Misses 2901 2900 -1 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
##### [\`v0.42.0\`](https://github.com/ast-grep/ast-grep/blob/HEAD/CHANGELOG.md#0420) - chore(deps): update dependency dprint to v0.53.0 [`#2547`](ast-grep/ast-grep#2547) - chore(deps): update rust crate tree-sitter to v0.26.7 [`#2541`](ast-grep/ast-grep#2541) - chore(deps): update dependency web-tree-sitter to v0.26.7 [`#2540`](ast-grep/ast-grep#2540) - chore(deps): update dependency [@types/node](https://github.com/types/node) to v24.12.0 [`#2518`](ast-grep/ast-grep#2518) - fix(deps): update rust crate tree-sitter-lua to 0.5.0 [`#2506`](ast-grep/ast-grep#2506) - chore(deps): update rust crate clap to v4.6.0 [`#2538`](ast-grep/ast-grep#2538) - fix(deps): update rust crate tree-sitter-scala to 0.25.0 [`#2536`](ast-grep/ast-grep#2536) - chore(deps): update dependency oxlint to v1.55.0 [`#2533`](ast-grep/ast-grep#2533) - chore(deps): update rust crate clap\_complete to v4.6.0 [`#2539`](ast-grep/ast-grep#2539) - chore(deps): update rust crate bit-set to v0.9.1 [`#2537`](ast-grep/ast-grep#2537) - chore(deps): update rust crate bit-set to 0.9.0 [`#2527`](ast-grep/ast-grep#2527) - chore(deps): update rust crate assert\_cmd to v2.2.0 [`#2529`](ast-grep/ast-grep#2529) - chore(deps): update rust crate tempfile to v3.27.0 [`#2531`](ast-grep/ast-grep#2531) - fix(lsp): scan injected languages for diagnostics [`#2528`](ast-grep/ast-grep#2528) - chore(deps): update dependency [@ast-grep/napi](https://github.com/ast-grep/napi) to v0.41.1 [`#2526`](ast-grep/ast-grep#2526) - chore(deps): update dependency oxlint to v1.52.0 [`#2524`](ast-grep/ast-grep#2524) - feat: support nth-child esquery [`#2546`](ast-grep/ast-grep#2546) - feat: support :is selector [`#2545`](ast-grep/ast-grep#2545) - feat: support :not selector [`#2544`](ast-grep/ast-grep#2544) - feat: support :has rule [`#2543`](ast-grep/ast-grep#2543) - fix(lsp): scan injected languages for diagnostics ([#2528](ast-grep/ast-grep#2528)) [`#2522`](ast-grep/ast-grep#2522) - feat: add parameterized util [`3d90372`](ast-grep/ast-grep@3d90372) - refactor: limit parameterized utils to globals [`2d69a34`](ast-grep/ast-grep@2d69a34) - refactor: move parameterized\_util [`c77e38d`](ast-grep/ast-grep@c77e38d) ##### [\`v0.41.1\`](https://github.com/ast-grep/ast-grep/blob/HEAD/CHANGELOG.md#0411) > 10 March 2026 - fix: lsp on change encounter deadlock [`#2511`](ast-grep/ast-grep#2511) - chore(deps): update dependency oxlint to v1.51.0 [`#2512`](ast-grep/ast-grep#2512) - chore(deps): update rust crate tempfile to v3.26.0 [`#2497`](ast-grep/ast-grep#2497) - chore(deps): update rust crate inquire to v0.9.4 [`#2498`](ast-grep/ast-grep#2498) - chore(deps): update dependency [@types/node](https://github.com/types/node) to v24.11.0 [`#2502`](ast-grep/ast-grep#2502) - chore(deps): update dependency dprint to v0.52.0 [`#2499`](ast-grep/ast-grep#2499) - fix: override severity on `rule` & `inline-rules` flags [`#2505`](ast-grep/ast-grep#2505) - chore(deps): update github artifact actions [`#2507`](ast-grep/ast-grep#2507) - chore(deps): update rust crate tree-sitter to v0.26.6 [`#2501`](ast-grep/ast-grep#2501) - chore(deps): update dependency web-tree-sitter to v0.26.6 [`#2500`](ast-grep/ast-grep#2500) - chore(deps): update dependency ava to v7 [`#2508`](ast-grep/ast-grep#2508) - chore(deps): update dependency oxlint to v1.50.0 [`#2495`](ast-grep/ast-grep#2495) - chore(deps): update dependency [@ast-grep/napi](https://github.com/ast-grep/napi) to v0.41.0 [`#2494`](ast-grep/ast-grep#2494) - fix: bump ls-types version [`#2525`](ast-grep/ast-grep#2525) - refactor: change versioned ast work [`a86b2ab`](ast-grep/ast-grep@a86b2ab) - fix: bump wasm-bindgen [`d23e334`](ast-grep/ast-grep@d23e334) - fix: fix wasm package [`0b92e94`](ast-grep/ast-grep@0b92e94) Renovate-Branch: renovate/2024.6-ast-grep-cli-0.x Change-Id: I91bcfa93167c7af0833afeb42df774621bad595c Priv-Id: ef06dc14816a639036bb167212251f765ce38ad8
Summary by CodeRabbit
New Features
Refactor
Tests