refactor(infer): collapse named-lambda-param typing onto the universal CST path#200
Merged
Hessesian merged 4 commits intoJul 4, 2026
Merged
Conversation
…l CST path Task 5 of the lambda-triad collapse. With Gap 1 closed, cst_named_lambda_param_type (which internally uses the now-collection-capable cst_lambda_param_type_via_call) subsumes what the named-param text scan caught. Routing through live_doc_or_parse makes the CST path universal — open files use the live tree, indexed-but-not-open files get a transient parse — the same foundation the it/this resolvers use. find_named_lambda_param_type_in_lines and find_named_lambda_param_type only used their extra params (lines / before_cursor / live_doc) for the deleted text scan, so they collapse into one CST-only find_named_lambda_param_type(param_name, pos, idx, uri). Deletes both text-scan bodies, the LAMBDA_PARAM_SCAN_BACK* constants, and the now-dead find_lambda_brace_for_param; simplifies the scope/completion callers (no more live_doc snapshot dance). Tests: converted the ~15 call sites; the former 'text fallback' / 'text-only' cases now exercise the CST path (transient parse when no live tree), proving it self-sufficient. Two scope_tests that placed the lambda only in the completion 'before' text (never in the document) now put it in the document, mirroring how production's live tree always holds the typed text. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…m<Position>, ungate named-param branch - F2: move mem_lines_for inside the it/this branch of infer_lambda_param_type_at; the named-param branch never used `lines`, so it was needlessly gated on it, blocking resolution in the did_open race window that live_doc_or_parse's disk fallback already handles. - F3: collapse CstParamResult from a tri-state (Resolved/TryFallback/ AuthoritativeNone) to Resolved/Unresolved — PR #200 removed the last consumer that distinguished the two None-like variants, so the enum's "essential for the text-fallback decision" doc was no longer true. - F4: find_named_lambda_param_type now uses into_option() instead of an inline match. - F5: add CursorPos: From<Position>; use it to hoist the duplicate CursorPos construction in infer_lambda_param_type_at into one call above the branch, and convert the whole-Position construction sites in completion.rs. - F6: pass the already-built (Copy) CursorPos directly in two it_this_tests.rs cases instead of re-wrapping it field-by-field. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EJsyQ1UgF8uJYR4HgpxEBB
…class callees on the CST path PR #200 deleted the text fallback whose qualified-callee branch scoped the signature lookup for `Outer.Nested(action = { item -> ... })` to the file defining `Outer`. The CST path fell back to an unscoped global by-name lookup, so with two same-named nested classes the first-indexed file's param type won (decoy test reproduced Some("ProductB") for a `ReducerA.SheetActions` callee). Port the semantics into the CST call-param resolution: - `InferDeps::find_outer_scoped_fun_params` (one new seam method) returns the param texts of `fn_name` declared in `outer`'s defining file; the `OuterScopedParams` result type encodes the fallback decision — `Candidates` (may still fall back globally) vs `ForbidGlobalFallback` (outer unresolved: any global match would come from an unrelated outer type). The Indexer impl is index-only (no rg) and submits `outer` for background enrichment when unresolved, matching the deleted branch. - `receiver_aware_params` now takes the named-arg label and, when the qualifier is a type (uppercase dotted identifier that failed `find_var_type`), consults the outer-scoped lookup before the global one, disambiguating same-named nested classes by the label. - Drop the `.or_else(global)` in `find_enclosing_call_and_param`: it was redundant (`receiver_aware_params` already ends in the same global lookup) and would have defeated `ForbidGlobalFallback`. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EJsyQ1UgF8uJYR4HgpxEBB
There was a problem hiding this comment.
Pull request overview
This PR continues the CST lambda-triad collapse by removing the named-lambda-param text-scan fallback and making named lambda parameter typing route exclusively through the universal CST path (Indexer::live_doc_or_parse), aligning behavior with the existing it/this CST-first resolvers.
Changes:
- Collapses named lambda param typing to a single CST-only entry point (
find_named_lambda_param_type(param_name, pos, idx, uri)), deleting the legacy text-scan logic and related helpers/tests. - Introduces
OuterScopedParams+InferDeps::find_outer_scoped_fun_paramsto scope signature lookup for qualified callees (e.g.Outer.Nested(...)) to the outer type’s defining file, preventing wrong-file by-name matches. - Simplifies call sites (scope + completion) by using
CursorPos::from(Position)and removing now-deadbefore-text plumbing.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| src/types.rs | Adds From<Position> for CursorPos to standardize position conversion at call sites. |
| src/indexer/scope.rs | Routes named-param inference through CST-only find_named_lambda_param_type and simplifies cursor handling. |
| src/indexer/scope_tests.rs | Updates scope tests to exercise CST-based named-param typing using real document content/positions. |
| src/indexer/infer/it_this.rs | Deletes named-param text fallback and collapses to a single CST-only resolver using live_doc_or_parse. |
| src/indexer/infer/it_this_tests.rs | Migrates/deletes fallback tests and adds coverage for qualified callee scoping behavior. |
| src/indexer/infer/deps.rs | Adds OuterScopedParams and InferDeps::find_outer_scoped_fun_params for outer-file-scoped signature lookup. |
| src/indexer/infer/cst_lambda.rs | Uses the new outer-scoped lookup to avoid wrong global by-name matches for qualified callees; simplifies param-result handling now that text fallback is gone. |
| src/indexer.rs | Implements find_outer_scoped_fun_params for Indexer using index-only resolution + signature collection. |
| src/features/completion.rs | Removes CompletionSite.before usage and resolves named lambda param types via CST using CursorPos::from(Position). |
…ation sharp edge Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EJsyQ1UgF8uJYR4HgpxEBB
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Task 5 of the CST lambda-triad collapse. Removes the named-lambda-param text-scan fallback, made redundant by Step 2 (Gap 1 close) + the
live_doc_or_parsefoundation.With Gap 1 closed,
cst_named_lambda_param_type(via the now-collection-capablecst_lambda_param_type_via_call) resolves what the text scan used to catch. Routing throughIndexer::live_doc_or_parsemakes the CST path universal — open files use the live tree, indexed-but-not-open files get a transient parse — exactly like theit/thisresolvers.Since both named-param functions only used their extra params (
lines/before_cursor/live_doc) for the deleted scan, they collapse into one CST-only function:Deleted
find_named_lambda_param_type_in_lines(merged away)LAMBDA_PARAM_SCAN_BACK_LINES/LAMBDA_PARAM_SCAN_BACKfind_lambda_brace_for_param(+ its 4 unit tests)live_docsnapshot dance in thescope.rscaller; thebeforefield onCompletionSite~180 net lines gone.
Verification
cargo test --bin kmp-lsp— 1438 passed, 0 failed.cargo clippy --bin kmp-lsp— clean.scope_teststhat placed the lambda only in the completionbeforetext (never in the document) now put it in the document, mirroring production's live tree.Stacks on the merged #196/#198/#199. Next steps (Tasks 6–8: delete the
ittext-scan body, rewritecompletion_context.build_lambda_scopeto a CST walk, deletereceiver.rs) are HIGH-risk and pause for human review per the plan.🤖 Generated with Claude Code