Skip to content

refactor(infer): delete the it/this text-scan ladder; broken syntax gets CST brace-repair#204

Merged
Hessesian merged 1 commit into
refactor/unified-resolutionfrom
refactor/cst-resolution-s6
Jul 4, 2026
Merged

refactor(infer): delete the it/this text-scan ladder; broken syntax gets CST brace-repair#204
Hessesian merged 1 commit into
refactor/unified-resolutionfrom
refactor/cst-resolution-s6

Conversation

@Hessesian

Copy link
Copy Markdown
Owner

Summary

Task 6 of the CST lambda-triad collapse: the last text fallback — the backward text-scan ladder in find_it_element_type_in_lines_impl — is deleted. The it gate now routes through Indexer::live_doc_or_parse, making the CST path universal for it/this exactly like the this (Task 2b), named-param (Task 5), and completion-scope (Task 7) paths before it.

Broken syntax: repair the source, don't scan it

The deletion surfaced a real capability the text scan silently provided: for items.forEach { it.name (unclosed brace — the mid-typing state), tree-sitter forms no lambda_literal at all (… → statements → ERROR → source_file), so no parse can answer. Instead of keeping a text heuristic, the ERROR case now gets append-only brace repair: a typed LambdaTreeGate distinguishes ERROR-at/above-cursor (repair permitted) from a well-formed tree with no lambda (authoritative None); the repair appends } at EOF (zero offset shift — the cursor position stays valid), transient-parses (never cached into live_trees), self-verifies the cursor now sits in a lambda_literal (capped at 8 attempts), and runs the same resolver on the repaired tree. ItResolutionDoc::{Live, Repaired} keeps a repaired-tree answer from masquerading as an authoritative one. hints_survive_syntax_error now passes via the repair branch.

Root-fix found en route

extract_collection_element_type was stripping type arguments from the element (List<RegularAccount>List) via dotted_ident_prefix(), silently breaking nested chains (collect { it.firstOrNull()?.account?.accountId?.also { … } } — inner it resolved to List instead of String). It now validates via the dotted prefix but returns the full parameterized type; inline_lambda_also_nested_in_outer_lambda pins it, assertion untouched.

Also deleted

  • CstParamResult + into_option() — after the two-state collapse every consumer mapped both variants to None; the type stopped carrying a decision, so it's now plain Option<String> at all three producers.
  • IT_SCAN_BACK_LINES and the ladder's helpers (re-homed to #[cfg(test)] where unit tests still exercise them directly).

Plus: a tempfile-based regression test pinning the scope.rs ungating fix from the s5 stack (named-param resolution from a disk-only file that is neither open nor indexed).

Verification

  • cargo test --bin kmp-lsp1442 passed, 0 failed (baseline 1441 + 1 new regression test); clippy clean.
  • Decoy evidence (RED→GREEN) for the repair branch and the generics fix in the task report; 13 former text-path tests converted to full-document setups and renamed to describe the transient-parse reality.
  • Task-scoped review: Approved, no Critical/Important findings.

Stacked on #202 (refactor/cst-resolution-s7). Next: Task 8 — with this landed, lambda_receiver_type_from_context/lambda_receiver_type_named_arg_ml are down to two cst_lambda call sites; closing those deletes receiver.rs (~480 lines).

🤖 Generated with Claude Code

https://claude.ai/code/session_01EJsyQ1UgF8uJYR4HgpxEBB

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR continues the CST lambda-triad refactor by removing the last production it/this text-scan fallback and routing it resolution through Indexer::live_doc_or_parse, making CST-based inference universal. It also addresses a real regression uncovered by the refactor (loss of element type arguments) and adds targeted regression coverage for disk-only (not live, not indexed) CST parsing.

Changes:

  • Remove the backward text-scan ladder for it inference; always resolve via CST from live_doc_or_parse.
  • Add bounded, append-only brace repair for broken syntax cases where tree-sitter produces no lambda_literal.
  • Fix extract_collection_element_type to preserve the element type’s own type arguments (e.g. List<RegularAccount>), and simplify CST param-type plumbing by collapsing CstParamResult to Option<String>.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated no comments.

Show a summary per file
File Description
src/resolver/infer_lines.rs Preserve element type arguments when extracting collection element types to enable correct chained member substitution.
src/indexer/scope_tests.rs Update it inference tests to use CST-backed find_it_element_type_in_lines, and add regression coverage for disk-only transient parsing.
src/indexer/infer/it_this.rs Delete the production text-scan ladder; introduce CST gating + bounded brace-repair transient parses for broken syntax.
src/indexer/infer/it_this_tests.rs Convert text-based it tests to full-document CST setups with explicit cursor positions; update regression test expectations to transient-parse reality.
src/indexer/infer/cst_lambda.rs Remove CstParamResult tri-state and streamline CST parameter inference APIs to Option<String>; keep text-scan only under #[cfg(test)].
src/indexer/infer/args.rs Mark has_named_params_not_it as test-only now that production named-param detection is CST-based.
src/indexer.rs Adjust re-exports so has_named_params_not_it is only exposed under #[cfg(test)].

…ets CST brace-repair (drop CstParamResult ceremony)

The it gate now takes Indexer::live_doc_or_parse, making the CST path
universal (live tree for open files, transient parse for indexed/disk
files), and the backward text-scan ladder in it_this.rs is deleted.
Broken syntax is no longer a text-scan excuse: tree-sitter forms no
lambda_literal for an unclosed `{` (the brace opens an ERROR node), so a
typed gate detects ERROR-above-cursor-without-lambda and resolves against
an append-only brace-repaired transient reparse — same resolver, repaired
tree, self-verified and bounded, never cached.

Root fixes surfaced by the re-route:
- extract_collection_element_type now preserves the element's own type
  arguments (Flow<List<A>> -> List<A>, not List), so the CST chain walk
  can substitute through subsequent member accesses. Pinned by
  inline_lambda_also_nested_in_outer_lambda, which returned a wrong
  Some("List") on the CST path before.
- it_type_at_lambda gains the lambda_receiver_type_from_context branch the
  deleted ladder had (calls whose callee sits on an inner call_expression
  are not served by the CST signature lookups; verified still required).

Also per the slice plan:
- CstParamResult deleted — every consumer flattened to Option<String>.
- New regression test pins the ungated named-param branch of
  infer_lambda_param_type_at resolving from a disk-only file (13fffc7).
- has_named_params_not_it is cfg(test): its last production caller was the
  deleted ladder.
- 12 former text-fallback tests converted to index the full document and
  resolve via the transient parse; regression_immutable_list_foreach_it_
  text_path renamed to ..._transient_parse to describe reality.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EJsyQ1UgF8uJYR4HgpxEBB
@Hessesian Hessesian force-pushed the refactor/cst-resolution-s6 branch from 09b0ec8 to b1fa44e Compare July 4, 2026 21:07
@Hessesian Hessesian changed the base branch from refactor/cst-resolution-s7 to refactor/unified-resolution July 4, 2026 21:07
@Hessesian Hessesian merged commit df66a4d into refactor/unified-resolution Jul 4, 2026
4 checks passed
@Hessesian Hessesian deleted the refactor/cst-resolution-s6 branch July 4, 2026 21:09
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.

2 participants