Skip to content

Commit 4b1d6ce

Browse files
committed
Move named argument to use symbol map
1 parent c2a8a77 commit 4b1d6ce

4 files changed

Lines changed: 436 additions & 118 deletions

File tree

docs/CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1111

1212
- **Docblock navigation.** Go-to-definition and hover now work on class names inside callable type annotations (`\Closure(Request): Response`), and Ctrl+Click on object shape properties (`$profile->name` from `@return object{name: string}`) jumps to the key inside the docblock.
1313

14+
### Changed
15+
16+
- **Named-argument completion uses symbol map.** Detection now uses precomputed `CallSite` data from the AST-based symbol map as the primary path, falling back to text scanning for broken ASTs. This correctly handles chain-resolution on `$this->prop->method(`, `$obj->first()->second(`, `(new Foo())->bar(`, and strings containing parentheses.
17+
- **Member-access completion uses symbol map.** `try_member_access_completion` now consults the symbol map's `MemberAccess` entries before falling back to text-based subject extraction. This improves accuracy for `(new Foo)->`, call-result chains, array access chains, and null-safe chains when the parser successfully recovers the AST.
18+
1419
### Fixed
1520

21+
- **Named-argument resolution for non-variable subjects.** `resolve_named_arg_params` now routes all instance-method subjects (bare class names, chain results) through `resolve_target_classes` instead of returning empty results when the subject does not start with `$`. The same fix is applied to static-method resolution, which now falls back to variable/chain resolution when the class name is not found directly.
1622
- **GTD for `@method`/`@property` on interfaces.** Go-to-definition now walks implemented interfaces (own and from parents) before checking `@mixin` classes, so virtual members declared on interfaces resolve correctly.
1723
- **`?->` null-safe chain resolution.** The `rfind("->")` split incorrectly matched the `->` inside `?->`, leaving a trailing `?` on the left-hand side. Fixed at all seven call sites across resolver, text resolution, handler, foreach resolution, and signature help.
1824
- **`(new Canvas())->easel` property access.** Parenthesized `new` expressions on the left side of `->` now resolve correctly for variable type inference.

docs/todo.md

Lines changed: 32 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -16,67 +16,13 @@ Each item carries two ratings:
1616

1717
---
1818

19-
<!-- ============================================================ -->
20-
<!-- TIER 0 — CRITICAL (infrastructure refactors) -->
21-
<!-- ============================================================ -->
22-
23-
## Critical
24-
25-
### 1. Named-argument completion: migrate to symbol map
26-
**Impact: Critical · Effort: Low**
27-
28-
`detect_named_arg_context` in `named_args.rs` uses `find_enclosing_open_paren`
29-
and `extract_call_expression` (character-level backward scanning) to detect
30-
which function or method call the cursor is inside. This suffers from chain-
31-
resolution failures on `$this->prop->method(`, `$obj->first()->second(`,
32-
`(new Foo())->bar(`, and strings containing parentheses.
33-
34-
The `CallSite` vector and `find_enclosing_call_site` are now available in
35-
`SymbolMap` (added during the signature help refactor). Named-arg completion
36-
can use `find_enclosing_call_site` as its primary detection path and fall
37-
back to the text scanner for broken ASTs, mirroring the approach already
38-
working in signature help.
39-
40-
`resolve_named_arg_params` also has an `else { vec![] }` bug: when the
41-
subject of a `->` call doesn't start with `$` (e.g. a chain result or
42-
bare class name), it returns no parameters. The fix is the same one
43-
applied to signature help's `resolve_callable`: route all subjects
44-
through `resolve_target_classes` instead of guarding on `starts_with('$')`.
45-
46-
---
47-
48-
### 2. Completion member access: add symbol-map primary path
49-
**Impact: Critical · Effort: Medium**
50-
51-
`try_member_access_completion` calls `extract_completion_target` (in
52-
`target.rs`), which uses `collapse_continuation_lines`,
53-
`extract_arrow_subject`, and `extract_double_colon_subject` from
54-
`subject_extraction.rs`. This is pure character-level backward scanning
55-
with no symbol-map involvement (confirmed: zero references to
56-
`symbol_map` in the entire `completion/` directory).
57-
58-
Hover and go-to-definition already use `SymbolMap::lookup` to get a
59-
pre-extracted `MemberAccess { subject_text, member_name, is_static,
60-
is_method_call }` from the AST. Completion should adopt the same
61-
"symbol map primary, text fallback" pattern so it benefits from the
62-
AST's correct handling of `(new Foo())->`, call-result chains, array
63-
access chains, and null-safe chains.
64-
65-
The main challenge is that completion fires while the user is actively
66-
typing, so the AST is frequently broken at the cursor. The text scanner
67-
is more resilient in that scenario, which is why it should remain as a
68-
fallback rather than being removed. The symbol-map path would improve
69-
accuracy for all cases where the parser successfully recovers.
70-
71-
---
72-
7319
<!-- ============================================================ -->
7420
<!-- TIER 1 — HIGH IMPACT -->
7521
<!-- ============================================================ -->
7622

7723
## High Impact
7824

79-
### 3. Pipe operator (PHP 8.5)
25+
### 1. Pipe operator (PHP 8.5)
8026
**Impact: High · Effort: Low**
8127

8228
PHP 8.5 introduced the pipe operator (`|>`):
@@ -102,7 +48,7 @@ callable syntax (`htmlspecialchars(...)`), reuse the existing
10248

10349
---
10450

105-
### 4. Function-level `@template` generic resolution
51+
### 2. Function-level `@template` generic resolution
10652
**Impact: High · Effort: Medium**
10753

10854
`MethodInfo` has `template_params` and `template_bindings` fields that
@@ -203,7 +149,7 @@ manifestation of this gap.
203149

204150
---
205151

206-
### 5. Parse and resolve `($param is T ? A : B)` return types
152+
### 3. Parse and resolve `($param is T ? A : B)` return types
207153
**Impact: High · Effort: Medium**
208154

209155
PHPStan's stubs use conditional return type syntax in docblocks:
@@ -242,7 +188,7 @@ extend the existing `ConditionalReturnType` infrastructure.
242188

243189
---
244190

245-
### 6. Warn when composer.json is missing or classmap is not optimized
191+
### 4. Warn when composer.json is missing or classmap is not optimized
246192
**Impact: High · Effort: Medium**
247193

248194
PHPantom relies on Composer artifacts (`vendor/composer/autoload_classmap.php`,
@@ -317,7 +263,7 @@ For the non-optimized classmap case, offer action buttons:
317263

318264
---
319265

320-
### 7. Find References (`textDocument/references`)
266+
### 5. Find References (`textDocument/references`)
321267
**Impact: High · Effort: Medium-High**
322268

323269
Can't find all usages of a symbol. The precomputed `SymbolMap` (built
@@ -341,7 +287,7 @@ variable within its scope" without re-parsing.
341287

342288
## Medium-High Impact
343289

344-
### 8. File system watching for vendor and project changes
290+
### 6. File system watching for vendor and project changes
345291
**Impact: Medium-High · Effort: Medium**
346292

347293
PHPantom loads Composer artifacts (classmap, PSR-4 mappings, autoload
@@ -399,7 +345,7 @@ supports glob patterns like `**/vendor/composer/autoload_*.php`.
399345

400346
## Medium Impact
401347

402-
### 9. No reverse jump: implementation → interface method declaration
348+
### 7. No reverse jump: implementation → interface method declaration
403349
**Impact: Medium · Effort: Low**
404350

405351
Go-to-implementation lets you jump from an interface method to its concrete
@@ -416,7 +362,7 @@ target.
416362

417363
---
418364

419-
### 10. Suppress GTD on parameter variable names and class declaration names
365+
### 8. Suppress GTD on parameter variable names and class declaration names
420366
**Impact: Medium · Effort: Low**
421367

422368
Go-to-definition fires on parameter variable names (`$supplier`, `$country`)
@@ -452,7 +398,7 @@ expect `None` instead.
452398

453399
---
454400

455-
### 11. `BackedEnum::from()` / `::tryFrom()` return type refinement
401+
### 9. `BackedEnum::from()` / `::tryFrom()` return type refinement
456402
**Impact: Medium · Effort: Low**
457403

458404
When calling `MyEnum::from($value)` or `MyEnum::tryFrom($value)`,
@@ -469,14 +415,14 @@ See `BackedEnumFromMethodDynamicReturnTypeExtension` in PHPStan.
469415

470416
---
471417

472-
### 12. Document Symbols (`textDocument/documentSymbol`)
418+
### 10. Document Symbols (`textDocument/documentSymbol`)
473419
**Impact: Medium · Effort: Low**
474420

475421
No outline view. Editors can't show a file's class/method/property structure.
476422

477423
---
478424

479-
### 13. Workspace Symbols (`workspace/symbol`)
425+
### 11. Workspace Symbols (`workspace/symbol`)
480426
**Impact: Medium · Effort: Low-Medium**
481427

482428
Can't search for classes/functions across the project. The `ast_map`
@@ -488,7 +434,7 @@ LSP `Location`s.
488434

489435
---
490436

491-
### 14. No go-to-definition for built-in (stub) functions and constants
437+
### 12. No go-to-definition for built-in (stub) functions and constants
492438
**Impact: Medium · Effort: Medium**
493439

494440
Clicking on a built-in function name like `array_map`, `strlen`, or
@@ -510,7 +456,7 @@ limitation.
510456

511457
---
512458

513-
### 15. Property hooks (PHP 8.4)
459+
### 13. Property hooks (PHP 8.4)
514460
**Impact: Medium · Effort: Medium**
515461

516462
PHP 8.4 introduced property hooks (`get` / `set`):
@@ -545,7 +491,7 @@ scopes, and parse the set-visibility modifier into a new
545491

546492
---
547493

548-
### 16. Narrow types of `&$var` parameters after function calls
494+
### 14. Narrow types of `&$var` parameters after function calls
549495
**Impact: Medium · Effort: Medium**
550496

551497
When a function takes a parameter by reference, the variable's type
@@ -574,7 +520,7 @@ extension) or use a built-in map for known functions.
574520

575521
---
576522

577-
### 17. SPL iterator generic stubs
523+
### 15. SPL iterator generic stubs
578524
**Impact: Medium · Effort: Medium**
579525

580526
PHPStan's `iterable.stub` provides full `@template TKey` /
@@ -595,7 +541,7 @@ certainly missing these generic annotations. We should either:
595541

596542
---
597543

598-
### 18. Partial result streaming via `$/progress`
544+
### 16. Partial result streaming via `$/progress`
599545
**Impact: Medium · Effort: Medium-High**
600546

601547
The LSP spec (3.17) allows requests that return arrays — such as
@@ -675,7 +621,7 @@ developer arrive before vendor matches, even within a single phase.
675621

676622
---
677623

678-
### 19. Rename (`textDocument/rename`)
624+
### 17. Rename (`textDocument/rename`)
679625
**Impact: Medium · Effort: Medium-High**
680626

681627
No rename refactoring support. Rename builds on find-references (§8) —
@@ -690,7 +636,7 @@ position without text scanning.
690636

691637
---
692638

693-
### 20. Array functions needing new code paths
639+
### 18. Array functions needing new code paths
694640
**Impact: Medium · Effort: High**
695641

696642
These functions have return type semantics that don't fit into either
@@ -729,7 +675,7 @@ These functions have return type semantics that don't fit into either
729675

730676
## Low-Medium Impact
731677

732-
### 21. Asymmetric visibility (PHP 8.4)
678+
### 19. Asymmetric visibility (PHP 8.4)
733679
**Impact: Low-Medium · Effort: Low**
734680

735681
Separate from property hooks, PHP 8.4 allows asymmetric visibility on
@@ -759,7 +705,7 @@ is just to store the value; context-aware filtering can follow later.
759705

760706
---
761707

762-
### 22. `str_contains` / `str_starts_with` / `str_ends_with` → non-empty-string narrowing
708+
### 20. `str_contains` / `str_starts_with` / `str_ends_with` → non-empty-string narrowing
763709
**Impact: Low-Medium · Effort: Low**
764710

765711
When `str_contains($haystack, $needle)` appears in a condition and
@@ -776,7 +722,7 @@ See `StrContainingTypeSpecifyingExtension` in PHPStan.
776722

777723
---
778724

779-
### 23. `count` / `sizeof` comparison → non-empty-array narrowing
725+
### 21. `count` / `sizeof` comparison → non-empty-array narrowing
780726
**Impact: Low-Medium · Effort: Low**
781727

782728
`if (count($arr) > 0)` or `if (count($arr) >= 1)` narrows `$arr` to
@@ -788,7 +734,7 @@ branches in `TypeSpecifier::specifyTypesInCondition`.
788734

789735
---
790736

791-
### 24. Go-to-definition for array shape keys via bracket access
737+
### 22. Go-to-definition for array shape keys via bracket access
792738
**Impact: Low · Effort: Medium**
793739

794740
Array shape keys accessed via bracket notation (`$status['code']`)
@@ -813,7 +759,7 @@ key inside the matching `array{…}` annotation.
813759

814760
## Low Impact
815761

816-
### 25. Short-name collisions in `find_implementors`
762+
### 23. Short-name collisions in `find_implementors`
817763
**Impact: Low · Effort: Low**
818764

819765
`class_implements_or_extends` matches interfaces by both short name and
@@ -829,7 +775,7 @@ before comparison.
829775

830776
---
831777

832-
### 26. Fiber type resolution
778+
### 24. Fiber type resolution
833779
**Impact: Low · Effort: Low**
834780

835781
`Generator<TKey, TValue, TSend, TReturn>` has dedicated support for
@@ -844,7 +790,7 @@ Generator extraction in `docblock/types.rs`.
844790

845791
---
846792

847-
### 27. Non-empty-string propagation through string functions
793+
### 25. Non-empty-string propagation through string functions
848794
**Impact: Low · Effort: Low**
849795

850796
PHPStan tracks `non-empty-string` through string-manipulating
@@ -862,7 +808,7 @@ See `NonEmptyStringFunctionsReturnTypeExtension` in PHPStan.
862808

863809
---
864810

865-
### 28. `Closure::bind()` / `Closure::fromCallable()` return type preservation
811+
### 26. `Closure::bind()` / `Closure::fromCallable()` return type preservation
866812
**Impact: Low · Effort: Low-Medium**
867813

868814
Variables holding closure literals, arrow functions, and first-class
@@ -878,7 +824,7 @@ See `ClosureBindDynamicReturnTypeExtension` and
878824

879825
---
880826

881-
### 29. Remove deprecated text-search fallbacks
827+
### 27. Remove deprecated text-search fallbacks
882828
**Impact: Low · Effort: Medium**
883829

884830
The go-to-definition subsystem now uses the precomputed `SymbolMap` as
@@ -910,7 +856,7 @@ would let that deprecated function be removed entirely.
910856

911857
---
912858

913-
### 30. Non-array functions with dynamic return types
859+
### 28. Non-array functions with dynamic return types
914860
**Impact: Low · Effort: High**
915861

916862
PHPStan also provides dynamic return type extensions for many non-array
@@ -941,7 +887,7 @@ return types (less impactful for class-based completion).
941887

942888
---
943889

944-
### 31. Language construct signature help and hover
890+
### 29. Language construct signature help and hover
945891
**Impact: Low · Effort: Low**
946892

947893
PHP language constructs that use parentheses (`unset()`, `isset()`, `empty()`,
@@ -958,22 +904,22 @@ need a similar hardcoded lookup.
958904

959905
---
960906

961-
### 32. Diagnostics
907+
### 30. Diagnostics
962908
**Impact: Low (large scope) · Effort: Very High**
963909

964910
No error reporting (undefined methods, type mismatches, etc.).
965911

966912
---
967913

968-
### 33. Code Actions
914+
### 31. Code Actions
969915
**Impact: Low · Effort: Very High**
970916

971917
No quick fixes or refactoring suggestions. No `codeActionProvider` in
972918
`ServerCapabilities`, no `textDocument/codeAction` handler, and no
973919
`WorkspaceEdit` generation infrastructure beyond trivial `TextEdit`s for
974920
use-statement insertion.
975921

976-
#### 33a. Extract Function refactoring
922+
#### 31a. Extract Function refactoring
977923

978924
Select a range of statements inside a method/function and extract them into a
979925
new function. The LSP would need to:

0 commit comments

Comments
 (0)