fix: emit fully qualified names for global-namespace symbols in class proxies - #584
Merged
Merged
Conversation
… proxies A DeclareParents introduction of a global-namespace interface (e.g. Stringable) or trait generated "implements Stringable" inside the proxy's namespace, where the name resolved relative to that namespace and crashed class loading with "Interface ...\Stringable not found". ClassGenerator now always emits interfaces fully qualified (they are FQCNs by contract, matching EnumGenerator) and honours an explicit leading backslash on parent/trait names, while bare short trait names (Foo__AopProxied) keep resolving in the proxy's own namespace. Reported in goaop/goaop-laravel-bridge#21. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KtrBW3xd8DQkxmHvX9qr4p
This was referenced Jul 29, 2026
Merged
lisachenko
commented
Jul 29, 2026
Review feedback on #584: extends/implements/traits/aliases now all go through one classNameNode() rule — explicitly rooted or multi-segment names are emitted fully qualified, bare short names resolve in the generated class's own namespace. Global-namespace names from ::class constants are already rooted upstream (AdviceMatcher normalizes introduced trait/interface names with a leading backslash). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KtrBW3xd8DQkxmHvX9qr4p
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
Fixes a class-loading crash when a
DeclareParentsintroduction adds a global-namespace interface or trait (e.g.Stringable) to a namespaced class.ClassGeneratoremitted single-segment names as relative (implements Stringable), so inside the proxy's namespace PHP resolved them asMy\Ns\Stringableand failed withInterface "My\Ns\Stringable" not found. Multi-segment names were unaffected, which is why ordinary advices never hit this.Found while triaging goaop/goaop-laravel-bridge#21 (inter-type declarations failing under Laravel): the legacy 2.x report was a dissect-grammar parse error, but reproducing the scenario on 4.x surfaced this current bug — the end-to-end DeclareParents weaving test in the bridge (goaop/goaop-laravel-bridge#35) fails without this patch and passes with it.
Changes
src/Proxy/Generator/ClassGenerator.php:Name\FullyQualified— they are documented as FQCNs, and this matches the identical handling (and comment) already present inEnumGenerator.\Exception,\GlobalTrait) as "fully qualified", while bare short names (Foo__AopProxied, same-namespace parents) keep resolving relative to the proxy's namespace, preserving the existing behavior covered bytestExtendsSimpleName.tests/Proxy/Generator/ClassGeneratorTest.php: three new tests covering a global-namespace interface in a namespaced proxy, an explicitly-rooted global parent, and an explicitly-rooted global trait mixed with a deliberate short trait name.Testing
./vendor/bin/phpunit— 2474 tests, 2877 assertions, green (20 pre-existing deprecations, 1 pre-existing skip)phpstan analyze --memory-limit=512M— level 10, no errorsDeclareParentsWeavingTestfails without this fix, passes with it🤖 Generated with Claude Code
https://claude.ai/code/session_01KtrBW3xd8DQkxmHvX9qr4p
Generated by Claude Code