A container key leads to the provider that binds it - #335
Merged
AJenbo merged 3 commits intoAug 16, 2026
Merged
Conversation
|
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
shuvroroy
marked this pull request as ready for review
August 10, 2026 14:05
This wires through hover, go-to-definition, and references for container keys, adds container-key behavior in completion/diagnostics paths, and includes broad unit/integration coverage plus Laravel demo/assertion updates. Todo docs were updated to mark the service-provider binding item as completed.
AJenbo
force-pushed
the
feat/container-binding-registrations-from-service-providers
branch
from
August 16, 2026 03:01
9914763 to
b439bfb
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A service provider's string bindings were already indexed, so
app('payments')->charge()resolved to the bound class. Three things were still missing: the$bindings/$singletonsarrays Laravel reads off a provider, factories that declare what they return rather than building it inline, and any way to navigate from the key itself. This PR finishes all three.app('payments'),resolve('payments'),App::make('payments'), and$this->app->make('payments')now hover with the class the key resolves to and the provider that registered it, Ctrl+Click jumps to the registration, and find-references collects every other call that asks for the same key — including the registration itself.What changed
Registrations recovered
$bindings/$singletonsprovider arrays. Laravel applies these itself inApplication::register(), after callingregister(), so an array entry now beats whatregister()bound the same key to — the class the container actually ends up holding. Integer keys are skipped: that is Laravel's shorthand for binding a class to itself, which needs no table.singleton('k', function ($app): Gateway { … })resolves through the hint when the body hands back something the scan cannot follow.static::$abstract). Analias()records its own key's position rather than the registration it points at, so each key navigates to where it is written.Navigation
LaravelStringKind::ContainerBinding, emitted forapp()/resolve(), theAppfacade's static calls, and container-receiver method calls ($this->app->,$app->,app()->). Registrations are marked as writes;extend()is a read, since it decorates a key that must already exist.Resolves to \X`` plus the registering provider.Declared types are unchanged. A
Contract::classkey binds a name that already resolves, soapp(Gateway::class)stays the contract. An argument spelled as a class name is a class reference, not a binding key, and is never recorded as one.Refactors
Three, each because the alternative was code that could not be reached or tested:
declared_factory_returnre-derived the closure signature behind a?that its only two callers make impossible. It takes the return-type hint directly now.string_key_candidates/string_key_item_kindand unit-tested directly, including that those three offer nothing — which pins the documented decision rather than leaving it as an unexercised arm.LaravelStringKindtwice, once to filter and once to check, so the second match needed a dead arm for kinds the first had already dropped. It now carries aCheckedStringKind(seven variants, all reachable), stating the "not judged here" reason once instead of twice.The third touches a hot path, so the full integration suite was re-run and the failing-test list diffed against baseline: identical.
Two things worth flagging
Provider registrations are not refreshed on edit.
build_provider_resourcesruns only atinitializedand in theanalyzeCLI; there is norefresh_provider_resourcesthe way macros, gates, the morph map, and commands each have one. A newly written binding needs a restart before it resolves. This is pre-existing for the whole provider scan — view directories, route files, component namespaces — and not something this PR introduces, so I left it alone rather than widen the diff. It is the obvious follow-up if the feature should feel live while editing a provider; whoever does it must also resetlaravel_aliasesand clear the class-not-found cache, asbuild_provider_resourcesalready does.No completion for container keys. L36 asked for the alias-table merge, go-to-definition, and hover, and this PR delivers those. Typing inside
app('…')still offers nothing: the completion detector never reports this kind, and the extractedstring_key_candidatesreturns an empty list for it. Worth doing as its own change — happy to add it here instead if you'd rather it ship together.Checklist
If applicable:
CHANGELOG.mdREADME.md,docs/,examples/)config-schema.json)