Skip to content

feat(laravel): go-to-definition for view, route, and translation keys#101

Merged
AJenbo merged 2 commits into
PHPantom-dev:mainfrom
MingJen:feat/laravel-view-route-trans
May 3, 2026
Merged

feat(laravel): go-to-definition for view, route, and translation keys#101
AJenbo merged 2 commits into
PHPantom-dev:mainfrom
MingJen:feat/laravel-view-route-trans

Conversation

@MingJen
Copy link
Copy Markdown
Contributor

@MingJen MingJen commented May 3, 2026

Summary

Adds Go-to-Definition for Laravel view names, route names, and translation keys, plus Find References for translation keys across all locale files. Users can now Ctrl+Click on view('admin.users.index'), route('admin.users.create'), __('auth.failed'), etc. and jump directly to the corresponding Blade template, route declaration, or translation array entry.

Changes

  • Adds Go-to-Definition for view() / View::make() — resolves dot-notation names to .blade.php files under resources/views/
  • Adds Go-to-Definition for route() — scans route files, resolves ->name('...') declarations including nested route group name prefixes (both fluent ->name('prefix.') chains and Route::group(['as' => ...]) static arrays)
  • Adds Go-to-Definition for __() / trans() / trans_choice() / Lang::get() — maps dot-notation keys to the exact array entry in translation files, falling back to line 0 when key is absent
  • Adds Find References for translation keys — locates all usages of a translation key across the codebase using pre-built symbol map spans
  • Refactors resolve_definition() return type from Option<Location> to Vec<Location> to support multi-target jumps
  • Extends LaravelStringKind enum with View, Route, and Trans variants; extraction now records these spans at parse time alongside the existing Config variant

How It Works

  1. Extraction (parse time)extraction.rs recognises call expressions like view(...), route(...), __() and tags them as SymbolKind::LaravelStringKey { kind, key } spans in the symbol map. No work is done at request time.

  2. Go-to-Definitionresolve_definition() matches LaravelStringKey → delegates to laravel::resolve_laravel_string_key(backend, kind, key) → dispatches to the appropriate module:

    • view_names::resolve_view_definitions — converts 'admin.users.index'resources/views/admin/users/index.blade.php, scans symbol map for matching file suffix
    • route_names::resolve_route_definitions — walks route file ASTs, tracks accumulated group name prefix via recursive scan_group_body() / chain_name_prefix(), matches when prefix + local name equals the target
    • trans_keys::resolve_trans_definitions — parses translation PHP files, walks nested array assignments, collects dot-joined key paths, returns the line of the matching entry
  3. Find Referencesfind_laravel_string_key_references() scans pre-built symbol_map.spans for LaravelStringKey { kind, key } entries. Zero file re-parses per call, consistent with the cross-file scanner rule.

  4. Route group prefix resolutionroute_names.rs handles both forms:

    • Fluent: Route::prefix('/admin')->name('admin.')->middleware(...)->group(fn() { ... })
    • Static: Route::group(['as' => 'admin.', 'prefix' => '/admin'], fn() { ... })
    • Nested groups accumulate prefixes as the AST is traversed depth-first.

Why Core Library Was Modified

resolve_definition() return type changed from Option<Location> to Vec<Location> in src/definition/resolve.rs. This was needed because a view name can resolve to multiple file paths (e.g., both .blade.php and .php variants), and route group structures can in principle yield multiple declaration sites. All existing call sites were updated to handle the Vec — existing single-target definitions (class, method, config) simply wrap their result in vec![...].

Tests

tests/integration/definition_laravel.rs — new test functions:

  • test_goto_definition_laravel_view_simpleview('welcome')resources/views/welcome.blade.php
  • test_goto_definition_laravel_view_nestedview('admin.users.index') → nested directory path
  • test_goto_definition_laravel_view_facadeView::make('dashboard') facade form
  • test_goto_definition_laravel_route_simpleroute('home')->name('home') declaration
  • test_goto_definition_laravel_route_dottedroute('admin.users.create') with dotted name
  • test_goto_definition_laravel_route_group_name_prefix — fluent ->name('prefix.') group chain
  • test_goto_definition_laravel_route_nested_group_prefix — two levels of nested groups
  • test_goto_definition_laravel_route_static_group_callRoute::group(fn() { ... }) without prefix
  • test_goto_definition_laravel_route_static_group_with_as_prefixRoute::group(['as' => 'admin.']) array form
  • test_goto_definition_laravel_route_in_subdirectory — route file located under routes/api/
  • test_goto_definition_laravel_trans_basic__('messages.welcome') → array entry in lang/en/messages.php
  • test_goto_definition_laravel_trans_lang_facadeLang::get('auth.failed') facade form
  • test_goto_definition_laravel_trans_nested_key — nested array key 'errors.required'

tests/integration/references_laravel_trans.rs:

  • test_find_references_laravel_trans_lists_all_locales__('auth.failed') find-references returns usages from both en and zh-TW locale PHP files without re-parsing

…upport

Change resolve_definition (and the underlying resolve_from_symbol /
resolve_laravel_string_key) from Option<Location> to Vec<Location> so
go-to-definition can point to multiple files — required by translation
keys that live in one file per locale.

All existing features (Variable, Member, Class, Config …) are adapted
to wrap their single result in vec![]; behaviour is unchanged.
server.rs now returns GotoDefinitionResponse::Scalar for one result,
::Array for many, and None for zero.
@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented May 3, 2026

Codecov Report

❌ Patch coverage is 81.67053% with 79 lines in your changes missing coverage. Please review.
✅ Project coverage is 86.57%. Comparing base (18aff5b) to head (67b009e).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
src/virtual_members/laravel/trans_keys.rs 65.42% 37 Missing ⚠️
src/virtual_members/laravel/helpers.rs 58.82% 21 Missing ⚠️
src/virtual_members/laravel/route_names.rs 88.42% 14 Missing ⚠️
src/symbol_map/extraction.rs 95.45% 3 Missing ⚠️
src/virtual_members/laravel/mod.rs 95.55% 2 Missing ⚠️
src/definition/resolve.rs 95.83% 1 Missing ⚠️
src/rename/mod.rs 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #101      +/-   ##
==========================================
- Coverage   86.58%   86.57%   -0.02%     
==========================================
  Files         168      171       +3     
  Lines      108128   108531     +403     
==========================================
+ Hits        93622    93956     +334     
- Misses      14506    14575      +69     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Add go-to-definition and find-references for three Laravel string-key
navigation patterns:

- view('name') / View::make('name') / View::exists('name')
  → jumps to the Blade template file

- route('name') / Route::group(['as'=>'prefix.'], ...)
  → jumps to the route() / ->name() declaration, including nested group
  prefix resolution (both fluent chain and array form)

- __('key') / trans('key') / trans_choice('key') / Lang::get('key')
  → jumps to every locale file that defines the key (multiple results
  via the Vec<Location> foundation from the previous PR)

Implementation follows the established LaravelStringKind pattern:
extraction in symbol_map/extraction.rs, resolution in dedicated
view_names/route_names/trans_keys modules, find-references reusing
find_string_key_usages() over the pre-built symbol map (zero re-parse).
@AJenbo AJenbo force-pushed the feat/laravel-view-route-trans branch from 2f9616f to 67b009e Compare May 3, 2026 12:38
@AJenbo AJenbo merged commit 53273b9 into PHPantom-dev:main May 3, 2026
7 checks passed
@AJenbo
Copy link
Copy Markdown
Collaborator

AJenbo commented May 3, 2026

view('admin.users.index')

This ons is particularly nice imo

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.

3 participants