@@ -25,25 +25,25 @@ public function __construct(
2525 */
2626 public function inheritProperty (string $ name , bool $ returnIfExists = false ): Property
2727 {
28- $ extends = $ this ->class ->getExtends ();
2928 if ($ this ->class ->hasProperty ($ name )) {
3029 return $ returnIfExists
3130 ? $ this ->class ->getProperty ($ name )
3231 : throw new Nette \InvalidStateException ("Cannot inherit property ' $ name', because it already exists. " );
33-
34- } elseif (!$ extends ) {
35- throw new Nette \InvalidStateException ("Class ' {$ this ->class ->getName ()}' has not setExtends() set. " );
3632 }
3733
38- try {
39- $ rp = new \ReflectionProperty ($ extends , $ name );
40- } catch (\ReflectionException ) {
41- throw new Nette \InvalidStateException ("Property ' $ name' has not been found in ancestor {$ extends }" );
34+ $ parents = [...(array ) $ this ->class ->getExtends (), ...$ this ->class ->getImplements ()]
35+ ?: throw new Nette \InvalidStateException ("Class ' {$ this ->class ->getName ()}' has neither setExtends() nor setImplements() set. " );
36+
37+ foreach ($ parents as $ parent ) {
38+ try {
39+ $ rp = new \ReflectionProperty ($ parent , $ name );
40+ } catch (\ReflectionException ) {
41+ continue ;
42+ }
43+ return $ this ->implementProperty ($ rp );
4244 }
4345
44- $ property = (new Factory )->fromPropertyReflection ($ rp );
45- $ this ->class ->addMember ($ property );
46- return $ property ;
46+ throw new Nette \InvalidStateException ("Property ' $ name' has not been found in any ancestor: " . implode (', ' , $ parents ));
4747 }
4848
4949
@@ -52,16 +52,15 @@ public function inheritProperty(string $name, bool $returnIfExists = false): Pro
5252 */
5353 public function inheritMethod (string $ name , bool $ returnIfExists = false ): Method
5454 {
55- $ parents = [...(array ) $ this ->class ->getExtends (), ...$ this ->class ->getImplements ()];
5655 if ($ this ->class ->hasMethod ($ name )) {
5756 return $ returnIfExists
5857 ? $ this ->class ->getMethod ($ name )
5958 : throw new Nette \InvalidStateException ("Cannot inherit method ' $ name', because it already exists. " );
60-
61- } elseif (!$ parents ) {
62- throw new Nette \InvalidStateException ("Class ' {$ this ->class ->getName ()}' has neither setExtends() nor setImplements() set. " );
6359 }
6460
61+ $ parents = [...(array ) $ this ->class ->getExtends (), ...$ this ->class ->getImplements ()]
62+ ?: throw new Nette \InvalidStateException ("Class ' {$ this ->class ->getName ()}' has neither setExtends() nor setImplements() set. " );
63+
6564 foreach ($ parents as $ parent ) {
6665 try {
6766 $ rm = new \ReflectionMethod ($ parent , $ name );
@@ -94,6 +93,14 @@ public function implement(string $name): void
9493 $ this ->implementMethod ($ method );
9594 }
9695 }
96+
97+ if (PHP_VERSION_ID >= 80400 ) {
98+ foreach ($ definition ->getProperties () as $ property ) {
99+ if (!$ this ->class ->hasProperty ($ property ->getName ()) && $ property ->isAbstract ()) {
100+ $ this ->implementProperty ($ property );
101+ }
102+ }
103+ }
97104 }
98105
99106
@@ -106,6 +113,15 @@ private function implementMethod(\ReflectionMethod $rm): Method
106113 }
107114
108115
116+ private function implementProperty (\ReflectionProperty $ rp ): Property
117+ {
118+ $ property = (new Factory )->fromPropertyReflection ($ rp );
119+ $ property ->setHooks ([]);
120+ $ this ->class ->addMember ($ property );
121+ return $ property ;
122+ }
123+
124+
109125 /** @deprecated use implement() */
110126 public function implementInterface (string $ interfaceName ): void
111127 {
0 commit comments