@@ -36,7 +36,9 @@ protected function load(
3636
3737 $ metadata = $ class ->getPropertyOrCreate ($ property ->getName ());
3838
39- $ this ->fillType ($ property , $ metadata , $ types );
39+ $ this ->fillReadType ($ property , $ metadata , $ types );
40+ $ this ->fillWriteType ($ property , $ metadata , $ types );
41+
4042 $ this ->fillDefaultValue ($ property , $ metadata );
4143 }
4244
@@ -90,27 +92,63 @@ private function fillDefaultValue(\ReflectionProperty $property, PropertyMetadat
9092 * @throws \InvalidArgumentException
9193 * @throws \Throwable
9294 */
93- private function fillType (
95+ private function fillReadType (
9496 \ReflectionProperty $ property ,
9597 PropertyMetadata $ meta ,
9698 TypeRepositoryInterface $ types ,
9799 ): void {
98- $ statement = $ this ->getTypeStatement ($ property );
100+ $ statement = $ this ->getReadTypeStatement ($ property );
101+
102+ $ meta ->read = $ meta ->write = $ this ->getTypeMetadataByStatement (
103+ statement: $ statement ,
104+ property: $ property ,
105+ types: $ types ,
106+ );
107+ }
108+
109+ /**
110+ * @throws \Throwable
111+ */
112+ private function fillWriteType (
113+ \ReflectionProperty $ property ,
114+ PropertyMetadata $ meta ,
115+ TypeRepositoryInterface $ types ,
116+ ): void {
117+ $ statement = $ this ->findWriteTypeStatement ($ property );
118+
119+ if ($ statement === null ) {
120+ return ;
121+ }
122+
123+ $ meta ->write = $ this ->getTypeMetadataByStatement (
124+ statement: $ statement ,
125+ property: $ property ,
126+ types: $ types ,
127+ );
128+ }
99129
130+ /**
131+ * @throws \Throwable
132+ */
133+ private function getTypeMetadataByStatement (
134+ TypeStatement $ statement ,
135+ \ReflectionProperty $ property ,
136+ TypeRepositoryInterface $ types ,
137+ ): TypeMetadata {
100138 try {
101139 $ type = $ types ->getTypeByStatement ($ statement );
102140 } catch (TypeNotFoundException $ e ) {
103141 $ class = $ property ->getDeclaringClass ();
104142
105143 throw PropertyTypeNotFoundException::becauseTypeOfPropertyNotDefined (
106- class: $ class ->getName () ,
107- property: $ property ->getName () ,
144+ class: $ class ->name ,
145+ property: $ property ->name ,
108146 type: $ e ->getType (),
109147 previous: $ e ,
110148 );
111149 }
112150
113- $ meta -> type = new TypeMetadata (
151+ return new TypeMetadata (
114152 type: $ type ,
115153 statement: $ statement ,
116154 );
@@ -119,7 +157,7 @@ class: $class->getName(),
119157 /**
120158 * @throws \InvalidArgumentException
121159 */
122- private function getTypeStatement (\ReflectionProperty $ property ): TypeStatement
160+ private function getReadTypeStatement (\ReflectionProperty $ property ): TypeStatement
123161 {
124162 $ type = $ property ->getType ();
125163
@@ -130,6 +168,32 @@ private function getTypeStatement(\ReflectionProperty $property): TypeStatement
130168 return $ this ->createTypeStatement ($ type );
131169 }
132170
171+ private function findWriteTypeStatement (\ReflectionProperty $ property ): ?TypeStatement
172+ {
173+ // Only PHP 8.4+ supports different get/set
174+ if (\PHP_VERSION_ID < 80400 ) {
175+ return null ;
176+ }
177+
178+ $ hook = $ property ->getHook (\PropertyHookType::Set);
179+
180+ if ($ hook === null || $ hook ->getNumberOfParameters () < 1 ) {
181+ return null ;
182+ }
183+
184+ foreach ($ hook ->getParameters () as $ parameter ) {
185+ $ type = $ parameter ->getType ();
186+
187+ if ($ type === null ) {
188+ return null ;
189+ }
190+
191+ return $ this ->createTypeStatement ($ type );
192+ }
193+
194+ return null ;
195+ }
196+
133197 private static function isValidProperty (\ReflectionProperty $ property ): bool
134198 {
135199 return !$ property ->isStatic ()
0 commit comments