Skip to content

PHPantom — Roadmap

This document tracks planned work for PHPantom. Each item links to a domain document with full context. Items are grouped into time-boxed sprints (roughly 1-2 weeks each) and a backlog of ideas not yet scheduled.

Guiding priorities: Completion accuracy → Type intelligence → Cross-file navigation → Diagnostics → Code actions → Performance.

Items inside each sprint are ordered by priority (top = do first): low-complexity items (easiest to assign, least implementation risk) before heavy lifts, dependencies before their dependents, and within the same complexity tier by impact descending. The backlog is ordered by impact (descending), then complexity (ascending) within the same impact tier.

Complexity measures how hard the task is to implement correctly, not how long it takes (time estimates are consistently wrong; skill required is not). Use it to decide who to assign: a Low-complexity item (e.g. adding a hundred repetitive docblock tags) is safe for a low-skill contributor even if it's tedious; a High-complexity item (e.g. a 50-line change to the forward walker) needs an experienced contributor even though it's short.

Label Scale
Impact Critical, High, Medium-High, Medium, Low-Medium, Low
Complexity Low (mechanical/boilerplate, no design decisions), Medium (self-contained, follows an existing pattern), Medium-High (spans modules, some new design), High (shared/core subsystem, correctness or performance tradeoffs), Very High (cross-cutting architecture, wide blast radius)

Scheduled Sprints

Sprint 6 — 0.10.0 release, full indexing

# Item Impact Complexity
Release 0.10.0

Sprint 7 — 1.0 release & IDE extensions

# Item Impact Complexity
Clear refactoring gate
E1 External stub packages (ide-helper, etc.) Medium-High Low
E5 Extension stub coverage audit Medium Low
E4 Embedded stub override with external stubs (depends on E1) Medium Low
E3 IDE-provided and .phpantom.toml stub paths (depends on E2) Low-Medium Low
D10 PHPMD diagnostic proxy Low Medium
L1 Facade completion (upstream facade-documenter PRs) High High
E2 Project-level stubs as type resolution source (depends on E1) Medium High
F20 Migrate to the maintained tower-lsp fork Low-Medium Very High
F21 Static typeHierarchyProvider advertisement (depends on F20; also needs an upstream lsp-types fix) Low-Medium Low
Release 1.0.0 + IDE extensions

Sprint 8 — Blade support

# Item Impact Complexity
Clear refactoring gate
BL23 Unbalanced component tag diagnostics Low-Medium Medium
BL14 Folding ranges for Blade files Low-Medium Medium
BL24 Named slot variables scoped to the component that receives them Low-Medium Medium
BL17 format --check CLI subcommand for CI (depends on BL16) Low-Medium Medium
BL1 Blade-aware code actions Medium Medium-High
BL15 Document outline (symbols) for Blade files Low-Medium Medium-High
BL16 Blade-aware formatting Low-Medium High

Backlog

Items not yet assigned to a sprint. Worth doing eventually but unlikely to move the needle for most users.

# Item Impact Complexity
Completion
C1 Array functions needing new code paths Medium High
C11 Smarter member ordering after -> / :: Medium High
C8 Filesystem proximity as an affinity tiebreaker Low-Medium Medium
C3 Go-to-definition for array shape keys via bracket access Low-Medium Medium
C7 class_alias() support Low-Medium Medium-High
C5 #[ReturnTypeContract] parameter-dependent return types Low Medium
C6 #[ExpectedValues] parameter value suggestions Low Medium
C10 Deprecation markers on class-name completions from all sources Low Medium
C12 The implicit $value of a set hook is not offered by variable completion Low Medium
C4 Non-array functions with dynamic return types Low High
Type Inference
T20 Type narrowing reconciliation engine (CNF clause algebra, sure/sureNot tracking) Medium-High Very High
T41 @param-out is parsed but never read Medium Medium
T28 Template inference depth priority (shallowest bound wins) Medium Medium-High
T3 Property hooks (PHP 8.4) Medium Medium-High
T34 static::CONST over-narrows to the declaring class's value Medium Medium-High
T29 Definite vs possible variable existence tracking Medium High
T30 Literal type collapse limit Low-Medium Medium
T40 pathinfo() returns a shape or a string depending on the flags argument Low-Medium Medium
T26 Globbed constant unions (Foo::BAR_*) Low-Medium Medium
T33 Class constant on an expression ($obj::CONST) resolves to nothing Low-Medium Medium
T6 Closure::bind() / Closure::fromCallable() return type preservation Low-Medium Medium-High
T13 Closure variables lose callable signature detail Low-Medium Medium-High
T31 Closure literal-return shape inference Low-Medium Medium-High
T4 Non-empty-* type narrowing and propagation Low-Medium High
T5 Fiber type resolution Low Medium
T10 Ternary expression as RHS of list destructuring Low Medium
T11 Nested list destructuring Low Medium
Bugs
B218 new ReflectionProperty(Foo::class, 'bar') forgets what it reflects Low Medium
B226 A function-static variable's type is not tracked across its own reads Low-Medium Medium-High
Diagnostics
D6 Unreachable code diagnostic Low-Medium Medium
D16 unreachable_match_arm ignores literal subject types Low-Medium Medium
D5 External tool diagnostic suppression actions Low Low
D15 Unused parameter diagnostic Low Medium
D17 docblock_native_mismatch only judges nullability Low Medium-High
D18 array<int, T> is accepted wherever a list<T> is declared Low Medium-High
Code Actions
A40 Generate method from call Medium-High Medium-High
A28 Explicit nullable parameter type (PHP 8.4 deprecation) Medium Low
A16 Snippet placeholder for extracted method name (lets the user type over the generated name immediately) Medium Medium
A46 Honor context.only in code action responses Medium Medium
A25 strposstr_contains (PHP 8.0+) Medium Medium
A41 Create class from non-existing name Medium Medium-High
A34 Unified code action handler architecture (closure-based resolve, unified fix type) Medium Very High
A29 Simplify boolean return (if (cond) return true; return false;return cond;) Low-Medium Medium
A45 Simplify with ?: (replace $x ? $x : $y with $x ?: $y) Low-Medium Medium
A31 Remove always-else (extract guard clause) Low-Medium Medium-High
A37 Simplify with ?-> (replace null-checked chains with the nullsafe operator) Low-Medium Medium-High
A38 Convert if/elseif chain to switch Low-Medium Medium-High
A43 Update docblock generics Low Medium
PHPStan Code Actions
H4 assign.byRefForeachExpr — unset by-reference foreach variable Medium Medium
H13 property.notFound — declare missing property (same-class) Medium Medium
H15 Template bound from tip — add @template T of X Medium Medium
H16 match.unhandled — add missing match arms Medium Medium-High
H19 property.unused / method.unused — remove unused member Low Low
H23 instanceof.alwaysTrue — remove redundant instanceof check Low Low
H24 catch.neverThrown — remove unnecessary catch clause Low Low
H20 generics.callSiteVarianceRedundant — remove redundant variance annotation Low Medium
CLI Fix Rules
FX7 add_return_type — generate @return docblocks from function bodies Medium-High Medium-High
FX1 deprecated — replace deprecated symbol usage Medium Low
FX3 phpstan.return.unusedType — remove unused type from return union Medium Low
FX4 phpstan.missingType.iterableValue — add @return with iterable type Medium Low
FX2 unused_variable — remove unused variables Medium Medium
FX5 phpstan.property.unused / phpstan.method.unused — remove unused member Low Low
FX6 phpstan.generics.callSiteVarianceRedundant — remove redundant variance Low Medium
LSP Features
F11 VS Code extension High Medium-High
F12 IntelliJ / PHPStorm plugin High Medium-High
F13 Homebrew formula Medium Low
F17 Wire class move to workspace/willRenameFiles Medium Medium
F5 Call hierarchy (incoming/outgoing calls) Medium Medium
F2 Partial result streaming via $/progress Medium Medium-High
F7 Evaluatable expression support (DAP integration) Low-Medium Low
F15 Go-to-declaration Low-Medium Low
F14 Helix upstream PR (depends on F13) Low-Medium Low
F16 On-type } brace de-indent Low Low
F19 Connect to a remote/TCP language server Low Medium
Signature Help
S2 Closure / arrow function parameter signature help Medium Medium
S3 Multiple overloaded signatures Medium Medium-High
S4 Named argument awareness in active parameter Low-Medium Medium
S5 Language construct signature help and hover Low Medium
Laravel
L24 Translation depth: JSON lang files, locales, placeholders Medium-High Medium-High
L46 ->can() on a user model the receiver does not name Medium-High Medium-High
L30 Eloquent attribute-array key completion Medium Medium
L32 Config-backed named-resource strings (log channels, cache stores, guards, connections, rate limiters) Medium Medium
L49 Unguarded Eloquent mass assignment diagnostic Medium Medium
L17 Additional string contexts without booting (middleware, assets, validation, Inertia) Medium Medium-High
L25 Storage disk name strings Low-Medium Low
L31 String-key rename, highlight, and semantic tokens Low-Medium Medium
L42 Morph alias completion in array positions Low-Medium Medium
L3 $dates array (deprecated) Low-Medium Medium
L12 HasUuids / HasUlids trait — $id typed as string Low-Medium Medium
L44 Sibling resource registrations and degenerate resource names Low-Medium Medium
L50 "Create route" quick-fix for an unresolved route name Low-Medium Medium
L47 Morph aliases in *_type column comparisons Low-Medium Medium-High
L8 withSum/withAvg/withMin/withMax aggregate properties Low-Medium High
L45 *_count properties are offered on every relationship Low-Medium High
L29 Livewire and Volt component names (Livewire projects only) Low Low
L27 Legacy Controller@method action strings Low Low
L10 View::withX() / RedirectResponse::withX() dynamic methods Low Medium
L39 Unused view and translation key detection Low Medium
L51 "Convert facade call to dependency injection" refactor Low Medium
Blade
BL11 Custom directive discovery (Blade::directive() / Blade::if() registrations) Medium Medium
External Stubs
E7 Stub-based framework patches Medium Medium-High
E6 Stub install prompt for non-Composer projects Low Medium
Performance
P16 Pre-parsed stub format (eliminate raw PHP embedding) High Very High
P35 Diagnostic passes reach only a fraction of available cores Medium-High Very High
P30 Evaluate migrating parse/resolve/docblock pipeline to mago-hir (parked — re-evaluated at mago 1.46.0, still no mago-hir consumers upstream) Medium-High Very High
P52 The diagnostic benchmarks measure a path no consumer takes Medium Low
P53 The deprecated collector deep-copies a class per member access Medium Low
P51 CI-gated scaling and memory invariants Medium Low-Medium
P17 mago-names resolution on the parse hot path Medium High
P18 Subtype result caching (per-request HashMap for hierarchy walks) Medium High
P47 The resolved-class cache lock caps concurrent class resolution Medium Very High
P20 Content-hash gated resolution cache persistence Medium Very High
P21 Offset-shifting for cached diagnostics on partial edits Medium Very High
P3 Parallel pre-filter in find_implementors Low-Medium Medium-High
P50 Cache the top-level scope for global keyword resolution Low-Medium High
P48 Higher-order collection proxy injection repeats work Low Medium
P49 A very long method chain costs superlinear time to analyse Low Medium
P15 Two-phase stub index construction (eliminate RwLock on stub maps) Low Medium-High
P6 O(n²) transitive eviction in evict_fqn Low High
Indexing
X7 Recency tracking Medium Medium-High
X6 Disk cache (evaluate later) Medium Very High
X2 Parallel file processing — remaining work Low-Medium Medium-High
X9 Honor editor file excludes and PHP associations during indexing Low-Medium Medium-High
Inline Completion
N1 Template engine (type-aware snippets) Medium Medium
N2 N-gram prediction from PHP corpus Medium Very High
N3 Fine-tuned GGUF sidecar model Medium Very High