Recognize Laravel Macroable::mixin() registrations#256
Open
shuvroroy wants to merge 9 commits into
Open
Conversation
…ource files for rebuilds
… `$this`-body resolution
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.
Summary
PHPantom already recovers
Target::macro('name', $closure)registrations statically (and attaches facade macros to the concrete container-bound class). This PR extends the macro scanner to the otherMacroableregistration path:Target::mixin($object).A mixin object's methods are closure factories — a public method
foo()returns aClosurewhose signature is the macro actually registered asTarget::foo(...). We recover that shape from source without booting the app (Larastan boots and reflects the runtime$macrosstatic; we parse the common literal form instead).What it does
Target::mixin(new X)andTarget::mixin(X::class), resolvingXto an FQN via the file'susestatements.Xwhose body returns a closure/arrow-fn, synthesizes a macro onTargetnamed after the method, taking the returned closure's parameters and return type (mirroring Laravel'sIS_PUBLIC | IS_PROTECTED; private/static/abstract/magic methods are skipped).macro(/mixin(token itself.The result: mixin-contributed methods autocomplete, hover (with the recovered signature and a macro-origin marker), resolve, and type-check on the target class, exactly like a
Target::macro(...)registration.Scope / limitations
new X/X::classarguments are handled; variable or computed targets are skipped, matching the existingmacro()scope.macro()too: variable/computed name arguments and string/array callables in place of a closure (rare, no statically recoverable signature).$thisshould carry an@mixin \Targetdocblock (the idiomatic Laravel pattern) so those$this->…calls resolve — this is handled by PHPantom's existing@mixinsupport, not this PR.Testing
macros_tests.rs): mixin-call extraction for bothnew XandX::class, skipping non-literal args and relativeself::targets, and closure-signature synthesis (including skipping methods that don't return a closure, and non-target classes in the same file).laravel_macros.rs): the mixin macro is surfaced in completion, resolves without diagnostics, go-to-definition lands on the mixin method, hover shows the recovered signature, and a$this-using mixin (with@mixin) resolves in completion + hover.cargo test,clippy(lib + tests), andcargo fmt --checkare clean;analyze --project-root examples/laravelreports only pre-existing unrelated errors.Example
Adds
examples/laravel/app/Support/CollectionMixin.phpregistered viaDemoServiceProvider::boot(), exercised inDemo.php.