Skip to content

fix: emit fully qualified names for global-namespace symbols in class proxies - #584

Merged
lisachenko merged 2 commits into
masterfrom
claude/goaop-laravel-bridge-issues-5w9z39
Jul 29, 2026
Merged

fix: emit fully qualified names for global-namespace symbols in class proxies#584
lisachenko merged 2 commits into
masterfrom
claude/goaop-laravel-bridge-issues-5w9z39

Conversation

@lisachenko

Copy link
Copy Markdown
Member

Summary

Fixes a class-loading crash when a DeclareParents introduction adds a global-namespace interface or trait (e.g. Stringable) to a namespaced class. ClassGenerator emitted single-segment names as relative (implements Stringable), so inside the proxy's namespace PHP resolved them as My\Ns\Stringable and failed with Interface "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:
    • Interfaces are now always emitted as Name\FullyQualified — they are documented as FQCNs, and this matches the identical handling (and comment) already present in EnumGenerator.
    • Parent class and trait names honour an explicit leading backslash (\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 by testExtendsSimpleName.
  • 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

🤖 Generated with Claude Code

https://claude.ai/code/session_01KtrBW3xd8DQkxmHvX9qr4p


Generated by Claude Code

… 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
Comment thread src/Proxy/Generator/ClassGenerator.php Outdated
Comment thread src/Proxy/Generator/ClassGenerator.php Outdated
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
@lisachenko
lisachenko marked this pull request as ready for review July 29, 2026 16:26
@lisachenko
lisachenko merged commit 91b44ea into master Jul 29, 2026
5 checks passed
@lisachenko
lisachenko deleted the claude/goaop-laravel-bridge-issues-5w9z39 branch July 29, 2026 16:26
@lisachenko lisachenko added this to the 4.0.0 milestone Jul 29, 2026
@lisachenko lisachenko added the Bug label Jul 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Development

Successfully merging this pull request may close these issues.

2 participants