@@ -44,6 +44,15 @@ class ReflectionExtractor implements PropertyListExtractorInterface, PropertyTyp
44
44
*/
45
45
public static $ arrayMutatorPrefixes = array ('add ' , 'remove ' );
46
46
47
+ private $ supportsParameterType ;
48
+ private $ supportsCallable ;
49
+
50
+ public function __construct ()
51
+ {
52
+ $ this ->supportsParameterType = method_exists ('ReflectionParameter ' , 'getType ' );
53
+ $ this ->supportsCallable = method_exists ('ReflectionParameter ' , 'isCallable ' );
54
+ }
55
+
47
56
/**
48
57
* {@inheritdoc}
49
58
*/
@@ -131,71 +140,57 @@ private function extractFromMutator($class, $property)
131
140
return ;
132
141
}
133
142
143
+ $ collection = $ phpType = $ typeClass = $ collectionKeyType = $ collectionValueType = null ;
134
144
$ reflectionParameters = $ reflectionMethod ->getParameters ();
135
145
$ reflectionParameter = $ reflectionParameters [0 ];
136
-
146
+ $ nullable = $ reflectionParameter -> allowsNull ();
137
147
$ arrayMutator = in_array ($ prefix , self ::$ arrayMutatorPrefixes );
138
148
139
- if (method_exists ($ reflectionParameter , 'getType ' ) && $ reflectionType = $ reflectionParameter ->getType ()) {
140
- $ fromReflectionType = $ this ->extractFromReflectionType ($ reflectionType );
149
+ if ($ this ->supportsParameterType ) {
150
+ if ($ reflectionType = $ reflectionParameter ->getType ()) {
151
+ $ fromReflectionType = $ this ->extractFromReflectionType ($ reflectionType );
141
152
142
- if (!$ arrayMutator ) {
143
- return array ($ fromReflectionType );
153
+ // HHVM reports not-builtin-"array" as type hints for variadics
154
+ if ($ reflectionType ->isBuiltin () || Type::BUILTIN_TYPE_ARRAY !== $ fromReflectionType ->getBuiltinType ()) {
155
+ if (!$ arrayMutator ) {
156
+ return array ($ fromReflectionType );
157
+ }
158
+ $ collectionValueType = $ fromReflectionType ;
159
+ }
144
160
}
145
-
146
- $ phpType = Type::BUILTIN_TYPE_ARRAY ;
147
- $ collectionKeyType = new Type (Type::BUILTIN_TYPE_INT );
148
- $ collectionValueType = $ fromReflectionType ;
149
- }
150
-
151
- if ($ reflectionParameter ->isArray ()) {
161
+ } elseif ($ reflectionParameter ->isArray ()) {
152
162
$ phpType = Type::BUILTIN_TYPE_ARRAY ;
153
163
$ collection = true ;
164
+ } elseif ($ this ->supportsCallable && $ reflectionParameter ->isCallable ()) {
165
+ $ phpType = Type::BUILTIN_TYPE_CALLABLE ;
166
+ } else {
167
+ try {
168
+ if ($ typeClass = $ reflectionParameter ->getClass ()) {
169
+ $ typeClass = $ typeClass ->name ;
170
+ }
171
+ } catch (\ReflectionException $ e ) {
172
+ // mandatory; extract it from the exception message
173
+ $ typeClass = str_replace (array ('Class ' , ' does not exist ' ), '' , $ e ->getMessage ());
174
+ }
175
+ if ($ typeClass ) {
176
+ $ phpType = Type::BUILTIN_TYPE_OBJECT ;
177
+ }
154
178
}
155
179
156
180
if ($ arrayMutator ) {
157
181
$ collection = true ;
158
182
$ nullable = false ;
159
- $ collectionNullable = $ reflectionParameter ->allowsNull ();
160
- } else {
161
- $ nullable = $ reflectionParameter ->allowsNull ();
162
- $ collectionNullable = false ;
163
- }
164
-
165
- if (!isset ($ collection )) {
166
- $ collection = false ;
167
- }
168
-
169
- if (method_exists ($ reflectionParameter , 'isCallable ' ) && $ reflectionParameter ->isCallable ()) {
170
- $ phpType = Type::BUILTIN_TYPE_CALLABLE ;
171
- }
172
-
173
- if ($ typeHint = $ reflectionParameter ->getClass ()) {
174
- if ($ collection ) {
175
- $ phpType = Type::BUILTIN_TYPE_ARRAY ;
176
- $ collectionKeyType = new Type (Type::BUILTIN_TYPE_INT );
177
- $ collectionValueType = new Type (Type::BUILTIN_TYPE_OBJECT , $ collectionNullable , $ typeHint ->name );
178
- } else {
179
- $ phpType = Type::BUILTIN_TYPE_OBJECT ;
180
- $ typeClass = $ typeHint ->name ;
183
+ if ($ phpType ) {
184
+ $ collectionValueType = new Type ($ phpType , $ nullable , $ typeClass );
185
+ $ typeClass = null ;
181
186
}
187
+ $ phpType = Type::BUILTIN_TYPE_ARRAY ;
188
+ $ collectionKeyType = new Type (Type::BUILTIN_TYPE_INT );
182
189
}
183
190
184
- // Nothing useful extracted
185
- if (!isset ($ phpType )) {
186
- return ;
191
+ if ($ phpType ) {
192
+ return array (new Type ($ phpType , $ nullable , $ typeClass , $ collection , $ collectionKeyType , $ collectionValueType ));
187
193
}
188
-
189
- return array (
190
- new Type (
191
- $ phpType ,
192
- $ nullable ,
193
- isset ($ typeClass ) ? $ typeClass : null ,
194
- $ collection ,
195
- isset ($ collectionKeyType ) ? $ collectionKeyType : null ,
196
- isset ($ collectionValueType ) ? $ collectionValueType : null
197
- ),
198
- );
199
194
}
200
195
201
196
/**
@@ -213,7 +208,7 @@ private function extractFromAccessor($class, $property)
213
208
return ;
214
209
}
215
210
216
- if (method_exists ( $ reflectionMethod , ' getReturnType ' ) && $ reflectionType = $ reflectionMethod ->getReturnType ()) {
211
+ if ($ this -> supportsParameterType && $ reflectionType = $ reflectionMethod ->getReturnType ()) {
217
212
return array ($ this ->extractFromReflectionType ($ reflectionType ));
218
213
}
219
214
@@ -231,15 +226,13 @@ private function extractFromAccessor($class, $property)
231
226
*/
232
227
private function extractFromReflectionType (\ReflectionType $ reflectionType )
233
228
{
234
- $ phpTypeOrClass = method_exists ( $ reflectionType, ' getName ' ) ? $ reflectionType ->getName () : ( string ) $ reflectionType ;
229
+ $ phpTypeOrClass = $ reflectionType instanceof \ReflectionNamedType ? $ reflectionType ->getName () : $ reflectionType-> __toString () ;
235
230
$ nullable = $ reflectionType ->allowsNull ();
236
231
237
- if ($ reflectionType ->isBuiltin ()) {
238
- if (Type::BUILTIN_TYPE_ARRAY === $ phpTypeOrClass ) {
239
- $ type = new Type (Type::BUILTIN_TYPE_ARRAY , $ nullable , null , true );
240
- } else {
241
- $ type = new Type ($ phpTypeOrClass , $ nullable );
242
- }
232
+ if (Type::BUILTIN_TYPE_ARRAY === $ phpTypeOrClass ) {
233
+ $ type = new Type (Type::BUILTIN_TYPE_ARRAY , $ nullable , null , true );
234
+ } elseif ($ reflectionType ->isBuiltin ()) {
235
+ $ type = new Type ($ phpTypeOrClass , $ nullable );
243
236
} else {
244
237
$ type = new Type (Type::BUILTIN_TYPE_OBJECT , $ nullable , $ phpTypeOrClass );
245
238
}
0 commit comments