@@ -130,10 +130,7 @@ public function loadSubAttributes(?object $attribute, \Reflector $reflection): v
130130 if ($ this ->isMultivalueAttribute ($ type )) {
131131 $ subs = $ this ->parser ->getInheritedAttributes ($ reflection , $ type );
132132 foreach ($ subs as $ sub ) {
133- if ($ sub instanceof Finalizable) {
134- $ sub ->finalize ();
135- }
136- $ this ->loadSubAttributes ($ sub , $ reflection );
133+ $ this ->applySubattributeFeatures ($ sub , $ reflection );
137134 }
138135 if ($ callback instanceof \Closure) {
139136 $ callback ($ subs );
@@ -142,10 +139,9 @@ public function loadSubAttributes(?object $attribute, \Reflector $reflection): v
142139 }
143140 } else {
144141 $ sub = $ this ->parser ->getInheritedAttribute ($ reflection , $ type );
145- if ($ sub instanceof Finalizable ) {
146- $ sub -> finalize ( );
142+ if ($ sub ) {
143+ $ this -> applySubattributeFeatures ( $ sub , $ reflection );
147144 }
148- $ this ->loadSubAttributes ($ sub , $ reflection );
149145 if ($ callback instanceof \Closure) {
150146 $ callback ($ sub );
151147 } else {
@@ -156,6 +152,39 @@ public function loadSubAttributes(?object $attribute, \Reflector $reflection): v
156152 }
157153 }
158154
155+ protected function applySubattributeFeatures (object $ attribute , \Reflector $ reflection ): void
156+ {
157+ // For each possible type, check for a FromReflection interface.
158+ if ($ reflection instanceof \ReflectionClass && ! $ reflection instanceof \ReflectionEnum && $ attribute instanceof FromReflectionClass) {
159+ /** @var \ReflectionClass<object> $reflection */
160+ $ attribute ->fromReflection ($ reflection );
161+ }
162+ if ($ reflection instanceof \ReflectionEnum && $ attribute instanceof FromReflectionEnum) {
163+ $ attribute ->fromReflection ($ reflection );
164+ }
165+ if ($ reflection instanceof \ReflectionFunction && $ attribute instanceof FromReflectionFunction) {
166+ $ attribute ->fromReflection ($ reflection );
167+ }
168+ if ($ reflection instanceof \ReflectionProperty && $ attribute instanceof FromReflectionProperty) {
169+ $ attribute ->fromReflection ($ reflection );
170+ }
171+ if ($ reflection instanceof \ReflectionMethod && $ attribute instanceof FromReflectionMethod) {
172+ $ attribute ->fromReflection ($ reflection );
173+ }
174+ if ($ reflection instanceof \ReflectionClassConstant && $ attribute instanceof FromReflectionClassConstant) {
175+ $ attribute ->fromReflection ($ reflection );
176+ }
177+ if ($ reflection instanceof \ReflectionParameter && $ attribute instanceof FromReflectionParameter) {
178+ $ attribute ->fromReflection ($ reflection );
179+ }
180+
181+ if ($ attribute instanceof Finalizable) {
182+ $ attribute ->finalize ();
183+ }
184+ // Call recursively to allow sub-attributes on sub-attributes. (Yo Dawg.)
185+ $ this ->loadSubAttributes ($ attribute , $ reflection );
186+ }
187+
159188 /**
160189 * Determines if a given attribute class allows repeating.
161190 *
0 commit comments