Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- **Container string aliases and global facades resolve.** `resolve('blade.compiler')` and `app('cache')` resolve to the concrete class Laravel binds the string to, so member access on the result completes, navigates, and type-checks. Bare global facade aliases such as `\App` and `\DB` resolve to their facade class without an explicit import. Both alias tables are read by parsing the framework the project actually has installed (never a version-specific list baked into PHPantom), so a name that only a service provider registers stays unresolved rather than being guessed. A project class whose short name collides with a facade alias (e.g. an app's own `Request` in the current namespace) still wins, since the alias table is only consulted after namespace-aware resolution misses.
- **`model-property<T>` pseudo-type recognition.** The Larastan `model-property<Model>` type no longer triggers "unknown class" diagnostics. It is treated as a string subtype.
- **`compact()` strings are linked to local variables.** A string argument to `compact('user')` is now treated as a reference to the matching local variable. Renaming the variable updates the string (and renaming from the string updates the variable and its other uses), find-references includes the string, and go-to-definition on the string jumps to the variable's assignment. Contributed by @calebdw in https://github.com/PHPantom-dev/phpantom_lsp/pull/159.
- **Laravel string key completion (route, config, view, trans).** Typing inside the first string argument of `route()`, `to_route()`, `config()`, `Config::get()`, `view()`, `View::make()`, `__()`, `trans()`, `Lang::get()`, and related helpers now offers autocompletion from the project's actual route names, config keys, view templates, and translation keys. Route names are collected from `routes/*.php` (including group prefixes and `Route::group([], __DIR__ . '/sub.php')` file includes), `Route::resource()` and `Route::apiResource()` generate conventional named routes (`index`, `create`, `store`, `show`, `edit`, `update`, `destroy`) respecting `->only()` and `->except()` modifiers, config keys from `config/*.php` array declarations, view names from `resources/views/` file paths, and translation keys from `lang/` files. Go-to-definition on route names also follows file includes and resolves resource routes. Laravel container attributes (`#[Config('key')]`, `#[Database('conn')]`, `#[Cache('store')]`, `#[Log('channel')]`, `#[Storage('disk')]`, `#[Auth('guard')]`) offer completion from the relevant config sub-keys (e.g. `#[Database('')]` shows database connection names from `config/database.php`). Facade methods like `Auth::guard()`, `DB::connection()`, `Cache::store()`, `Log::channel()`, `Storage::disk()`, and the `auth()` helper also complete from their respective config sub-keys. Contributed by @calebdw.
- **Hover for Laravel string keys.** Hovering over a route name, config key, view name, or translation key string now shows the key kind, the key value, and where it's defined (e.g. `routes/web/ems.php`, `config/app.php`). Contributed by @calebdw.
- **Diagnostics for invalid Laravel string keys.** A typo in `route('dashbaord')`, `config('app.naem')`, `view('layouts.ap')`, or `__('auth.failedd')` now produces a warning: `Unknown route: 'dashbaord'`. Only plain string literals are flagged; dynamic keys with variables are ignored. Contributed by @calebdw.
- **Imported and same-namespace symbols rank first in completion.** Classes, functions, and constants that are already imported via a `use` statement or live in the same namespace now always appear above non-imported symbols in the completion list, regardless of dependency provenance. Previously a non-imported project class could outrank an already-imported vendor class, forcing users to scroll past irrelevant results. Contributed by @calebdw.
- **Laravel route controller method navigation and completion.** Method-name strings inside `Route::controller(X::class)->group(fn(){…})` closures now resolve as references to the controller's methods. Go-to-definition, find-references, rename, hover, and diagnostics all work on the action string (e.g. `Route::patch('cancel', 'cancel')` resolves `'cancel'` to `WorkItemController::cancel()`). Autocompletion inside the action string offers the controller's methods. Handles `->controller()` anywhere in the fluent chain, chained route calls (`->name()`, etc.), and nested groups where an inner `->controller()` shadows the outer one. Contributed by @calebdw.
- **Package provenance displayed in hover.** Hovering over a class, method, property, constant, or function now shows a colored badge indicating where the symbol comes from: 🟢 for direct Composer dependencies (e.g. `laravel/framework`), 🟠 for transitive dependencies with an italic *(transitive)* marker, and 🟣 for PHP core/extension symbols. Project-local symbols show no badge. The package name is resolved from `vendor/composer/installed.json`. Closes #228. Contributed by @calebdw.
Expand Down
49 changes: 0 additions & 49 deletions docs/todo/laravel.md
Original file line number Diff line number Diff line change
Expand Up @@ -589,55 +589,6 @@ The scanners already enumerate every valid key for go-to-definition. The
items below mostly wire that existing enumeration into three more LSP
endpoints rather than building new analysis.

#### L14. Diagnostics for Laravel string keys

**Impact: High · Effort: Medium**

No Laravel string key is currently validated. A typo in `route('dashbaord')`,
`config('app.naem')`, `env('DB_CONNCTION')`, `__('auth.failedd')`, or
`view('layouts.ap')` produces no warning — the bug surfaces only at runtime.
This is the single highest-value gap, because it catches a class of error
that PHP itself never reports.

Emit a warning when a string argument in a recognised context resolves to no
declaration. The candidate set is the same one the go-to-definition scanners
already build, so the diagnostic is "key not in the collected set." Each
construct reuses its existing scanner:

- `route('name')` → not in collected `->name()` declarations.
- `config('a.b.c')` → not in flattened `config/*.php` keys.
- `env('KEY')` → not in `.env` / `.env.example`.
- `__()`/`trans()`/`trans_choice()` → not in `lang/**` keys.
- `view('a.b')` → no matching file under `resources/views/`.

Pair each with a quick-fix where cheap: "create missing view file,"
"add missing key to `.env` (copy from `.env.example`)" (mirrors the
extension's two quick-fixes). Guard against false positives from genuinely
dynamic keys (e.g. `config($key)` with a variable, or
`route("admin.$section")` interpolation) by only flagging plain string
literals.

#### L15. Completion for Laravel string keys

**Impact: High · Effort: Medium**

Completion exists only for Eloquent relations/columns. Extend it to offer
route names, config keys (dot-notation drill-down), env var names,
translation keys, and view names inside the corresponding string contexts.
The candidate lists are exactly the declaration sets the go-to scanners
already produce; the work is detecting the string-literal cursor context
(the symbol-map already records these as `LaravelStringKey`) and returning
the collected keys as completion items.

#### L16. Hover for Laravel string keys

**Impact: Medium · Effort: Low-Medium**

`SymbolKind::LaravelStringKey` currently returns `None` from hover
(`hover/mod.rs`). Show the resolved target: the config/env/translation
*value*, the route's URI + action, or the view's file path. The data is
already loaded by the go-to scanners; this is formatting it as hover markdown.

#### L17. Additional string contexts without booting

**Impact: Medium · Effort: Medium**
Expand Down
11 changes: 11 additions & 0 deletions src/completion/handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,17 @@ impl Backend {
return Ok(Some(response));
}

// ── Laravel string key completion (route/config/view/trans) ──
// Inside `route('|')`, `config('|')`, `view('|')`, `__('|')`,
// etc., offer matching key names from the project.
if matches!(
string_ctx,
StringContext::InStringLiteral | StringContext::NotInString
) && let Some(response) = self.try_laravel_string_key_completion(&content, position)
{
return Ok(Some(response));
}

// ── Eloquent relation/column string completion ──────────
// Like array shape completion, this triggers inside string
// literals where the cursor is in a method argument position
Expand Down
Loading
Loading