5
5
*/
6
6
namespace Magento \Framework \Code \Reader ;
7
7
8
+ use Laminas \Code \Reflection \DocBlock \Tag \ParamTag ;
9
+ use Laminas \Code \Reflection \DocBlockReflection ;
8
10
use Magento \Framework \GetParameterClassTrait ;
11
+ use Laminas \Code \Reflection \ParameterReflection ;
9
12
10
13
/**
11
14
* The class arguments reader
12
15
*/
13
- class ArgumentsReader
16
+ class ArgumentsReader extends ParameterReflection
14
17
{
15
18
use GetParameterClassTrait;
16
19
@@ -26,6 +29,11 @@ class ArgumentsReader
26
29
*/
27
30
private $ scalarTypesProvider ;
28
31
32
+ /**
33
+ * @var ParameterReflection
34
+ */
35
+ protected $ parameterReflection ;
36
+
29
37
/**
30
38
* @param NamespaceResolver|null $namespaceResolver
31
39
* @param ScalarTypesProvider|null $scalarTypesProvider
@@ -102,17 +110,14 @@ public function getConstructorArguments(\ReflectionClass $class, $groupByPositio
102
110
*/
103
111
private function processType (\ReflectionClass $ class , \Laminas \Code \Reflection \ParameterReflection $ parameter )
104
112
{
113
+ $ this ->parameterReflection = $ parameter ;
105
114
$ parameterClass = $ this ->getParameterClass ($ parameter );
106
115
107
116
if ($ parameterClass ) {
108
117
return NamespaceResolver::NS_SEPARATOR . $ parameterClass ->getName ();
109
118
}
110
119
111
- // In PHP8, $parameterType could be an instance of ReflectionUnionType, which doesn't have isBuiltin method
112
- if ($ parameterClass === null ) {
113
- return null ;
114
- }
115
- $ type = $ parameter ->detectType ();
120
+ $ type = $ this ->detectType ();
116
121
117
122
/**
118
123
* $type === null if it is unspecified
@@ -281,4 +286,58 @@ public function getAnnotations(\ReflectionClass $class)
281
286
282
287
return $ annotations ;
283
288
}
289
+
290
+ /**
291
+ * ReflectionType does not have an isBuiltin() / getName() method
292
+ *
293
+ * @deprecated this method is unreliable, and should not be used: it will be removed in the next major release.
294
+ * It may crash on parameters with union types, and will return relative types, instead of
295
+ * FQN references
296
+ *
297
+ * @return mixed|string|void|null
298
+ */
299
+ public function detectType ()
300
+ {
301
+ if (null !== ($ type = $ this ->parameterReflection ->getType ())
302
+ && method_exists ($ type , 'isBuiltin ' ) && $ type ->isBuiltin ()
303
+ ) {
304
+ return $ type ->getName ();
305
+ }
306
+
307
+ if (null !== $ type && method_exists ($ type , 'getName ' ) && $ type ->getName () === 'self ' ) {
308
+ $ declaringClass = $ this ->parameterReflection ->getDeclaringClass ();
309
+ // @codingStandardsIgnoreStart
310
+ assert ($ declaringClass !== null , 'A parameter called `self` can only exist on a class ' );
311
+ // @codingStandardsIgnoreEnd
312
+
313
+ return $ declaringClass ->getName ();
314
+ }
315
+
316
+ if (($ class = $ this ->parameterReflection ->getClass ()) instanceof ReflectionClass) {
317
+ return $ class ->getName ();
318
+ }
319
+
320
+ $ docBlock = $ this ->parameterReflection ->getDeclaringFunction ()->getDocBlock ();
321
+
322
+ if (! $ docBlock instanceof DocBlockReflection) {
323
+ return null ;
324
+ }
325
+
326
+ /** @var ParamTag[] $params */
327
+ $ params = $ docBlock ->getTags ('param ' );
328
+ $ paramTag = $ params [$ this ->parameterReflection ->getPosition ()] ?? null ;
329
+ $ variableName = '$ ' . $ this ->parameterReflection ->getName ();
330
+
331
+ if ($ paramTag && ('' === $ paramTag ->getVariableName () || $ variableName === $ paramTag ->getVariableName ())) {
332
+ return $ paramTag ->getTypes ()[0 ] ?? '' ;
333
+ }
334
+
335
+ foreach ($ params as $ param ) {
336
+ if ($ param ->getVariableName () === $ variableName ) {
337
+ return $ param ->getTypes ()[0 ] ?? '' ;
338
+ }
339
+ }
340
+
341
+ return null ;
342
+ }
284
343
}
0 commit comments