@@ -131,18 +131,7 @@ protected function addFunction(FunctionNode $node, ?string $namespace = null)
131
131
132
132
$ parameter ->setVariadic ($ param ->variadic );
133
133
134
- $ type = $ param ->type ;
135
- $ typeStr = $ this ->typeToString ($ type );
136
-
137
- if (null !== $ typeStr ) {
138
- $ typeArr = [[$ typeStr , false ]];
139
-
140
- if ($ param ->type instanceof NullableType) {
141
- $ typeArr [] = ['null ' , false ];
142
- }
143
-
144
- $ parameter ->setHint ($ this ->resolveHint ($ typeArr ));
145
- }
134
+ $ this ->manageHint ($ param ->type , $ parameter );
146
135
147
136
$ function ->addParameter ($ parameter );
148
137
}
@@ -167,18 +156,7 @@ protected function addFunction(FunctionNode $node, ?string $namespace = null)
167
156
$ function ->setModifiersFromTags ();
168
157
$ function ->setErrors ($ errors );
169
158
170
- $ returnType = $ node ->getReturnType ();
171
- $ returnTypeStr = $ this ->typeToString ($ returnType );
172
-
173
- if (null !== $ returnTypeStr ) {
174
- $ returnTypeArr = [[$ returnTypeStr , false ]];
175
-
176
- if ($ returnType instanceof NullableType) {
177
- $ returnTypeArr [] = ['null ' , false ];
178
- }
179
-
180
- $ function ->setHint ($ this ->resolveHint ($ returnTypeArr ));
181
- }
159
+ $ this ->manageHint ($ node ->getReturnType (), $ function );
182
160
183
161
$ this ->context ->addFunction ($ function );
184
162
@@ -188,7 +166,7 @@ protected function addFunction(FunctionNode $node, ?string $namespace = null)
188
166
}
189
167
190
168
/**
191
- * @param \PhpParser\Node\Identifier|\PhpParser\Node\Name|NullableType|UnionType|IntersectionType|null $type Type declaration
169
+ * @param \PhpParser\Node\ComplexType|\PhpParser\Node\ Identifier|\PhpParser\Node\Name|NullableType|UnionType|IntersectionType|null $type Type declaration
192
170
*/
193
171
protected function typeToString ($ type ): ?string
194
172
{
@@ -206,9 +184,13 @@ protected function typeToString($type): ?string
206
184
} elseif ($ type instanceof IntersectionType) {
207
185
$ typeString = [];
208
186
foreach ($ type ->types as $ type ) {
209
- $ typeString [] = $ type ->__toString ();
187
+ $ typeAsStr = $ type ->__toString ();
188
+ if ($ type instanceof FullyQualified && 0 !== strpos ($ typeAsStr , '\\' )) {
189
+ $ typeAsStr = '\\' . $ typeAsStr ;
190
+ }
191
+ $ typeString [] = $ typeAsStr ;
210
192
}
211
- $ typeString = implode ('& ' , $ typeString );
193
+ return implode ('& ' , $ typeString );
212
194
}
213
195
214
196
if ($ typeString === null ) {
@@ -332,18 +314,7 @@ protected function addMethod(ClassMethodNode $node)
332
314
333
315
$ parameter ->setVariadic ($ param ->variadic );
334
316
335
- $ type = $ param ->type ;
336
- $ typeStr = $ this ->typeToString ($ type );
337
-
338
- if (null !== $ typeStr ) {
339
- $ typeArr = [[$ typeStr , false ]];
340
-
341
- if ($ param ->type instanceof NullableType) {
342
- $ typeArr [] = ['null ' , false ];
343
- }
344
-
345
- $ parameter ->setHint ($ this ->resolveHint ($ typeArr ));
346
- }
317
+ $ this ->manageHint ($ param ->type , $ parameter );
347
318
348
319
$ method ->addParameter ($ parameter );
349
320
}
@@ -371,18 +342,7 @@ protected function addMethod(ClassMethodNode $node)
371
342
$ method ->setModifiersFromTags ();
372
343
$ method ->setErrors ($ errors );
373
344
374
- $ returnType = $ node ->getReturnType ();
375
- $ returnTypeStr = $ this ->typeToString ($ returnType );
376
-
377
- if (null !== $ returnTypeStr ) {
378
- $ returnTypeArr = [[$ returnTypeStr , false ]];
379
-
380
- if ($ returnType instanceof NullableType) {
381
- $ returnTypeArr [] = ['null ' , false ];
382
- }
383
-
384
- $ method ->setHint ($ this ->resolveHint ($ returnTypeArr ));
385
- }
345
+ $ this ->manageHint ($ node ->getReturnType (), $ method );
386
346
387
347
if ($ this ->context ->getFilter ()->acceptMethod ($ method )) {
388
348
$ this ->context ->getClass ()->addMethod ($ method );
@@ -417,6 +377,14 @@ protected function addTagFromCommentToMethod(
417
377
if (is_array ($ firstTagFound )) {
418
378
$ hint = $ firstTagFound [0 ];
419
379
$ hintDescription = $ firstTagFound [1 ] ?? null ;
380
+ if (is_array ($ hint ) && isset ($ hint [0 ]) && stripos ($ hint [0 ][0 ] ?? '' , '& ' ) !== false ) {// Detect intersection type
381
+ $ methodOrFunctionOrProperty ->setIntersectionType (true );
382
+ $ intersectionParts = explode ('& ' , $ hint [0 ][0 ]);
383
+ $ hint = [];
384
+ foreach ($ intersectionParts as $ part ) {
385
+ $ hint [] = [$ part , false ];
386
+ }
387
+ }
420
388
$ methodOrFunctionOrProperty ->setHint (is_array ($ hint ) ? $ this ->resolveHint ($ hint ) : $ hint );
421
389
if ($ hintDescription !== null ) {
422
390
if (is_string ($ hintDescription )) {
@@ -458,36 +426,21 @@ protected function addProperty(PropertyNode $node)
458
426
}
459
427
460
428
/**
461
- * @return array<int,PropertyReflection|string[]>
462
- * @phpstan-return array{ PropertyReflection,string[]}
429
+ * @param \PhpParser\Node\ComplexType|\PhpParser\Node\Identifier|\PhpParser\Node\Name|NullableType|UnionType|IntersectionType|null $type Type declaration
430
+ * @param MethodReflection|FunctionReflection|ParameterReflection| PropertyReflection $object
463
431
*/
464
- protected function getPropertyReflectionFromParserProperty ( PropertyNode $ node , PropertyProperty $ prop ): array
432
+ protected function manageHint ( $ type , Reflection $ object ): void
465
433
{
466
- $ property = new PropertyReflection ($ prop ->name ->toString (), $ prop ->getLine ());
467
- $ property ->setModifiers ($ node ->flags );
468
-
469
- $ property ->setDefault ($ prop ->default );
470
-
471
- $ docComment = $ node ->getDocComment ();
472
- $ docComment = $ docComment === null ? null : $ docComment ->__toString ();
473
- $ comment = $ this ->context ->getDocBlockParser ()->parse ($ docComment , $ this ->context , $ property );
474
- $ property ->setDocComment ($ docComment );
475
- $ property ->setShortDesc ($ comment ->getShortDesc ());
476
- $ property ->setLongDesc ($ comment ->getLongDesc ());
477
- $ property ->setSee ($ this ->resolveSee ($ comment ->getTag ('see ' )));
478
-
479
- $ type = $ node ->type ;
480
-
481
434
if ($ type instanceof IntersectionType) {
482
- $ property ->setIntersectionType (true );
435
+ $ object ->setIntersectionType (true );
483
436
484
437
$ typeArr = [];
485
438
foreach ($ type ->types as $ type ) {
486
439
$ typeStr = $ this ->typeToString ($ type );
487
440
$ typeArr [] = [$ typeStr , false ];
488
441
}
489
442
490
- $ property ->setHint ($ this ->resolveHint ($ typeArr ));
443
+ $ object ->setHint ($ this ->resolveHint ($ typeArr ));
491
444
} else {
492
445
$ typeStr = $ this ->typeToString ($ type );
493
446
@@ -497,9 +450,31 @@ protected function getPropertyReflectionFromParserProperty(PropertyNode $node, P
497
450
if ($ type instanceof NullableType) {
498
451
$ typeArr [] = ['null ' , false ];
499
452
}
500
- $ property ->setHint ($ this ->resolveHint ($ typeArr ));
453
+ $ object ->setHint ($ this ->resolveHint ($ typeArr ));
501
454
}
502
455
}
456
+ }
457
+
458
+ /**
459
+ * @return array<int,PropertyReflection|string[]>
460
+ * @phpstan-return array{PropertyReflection,string[]}
461
+ */
462
+ protected function getPropertyReflectionFromParserProperty (PropertyNode $ node , PropertyProperty $ prop ): array
463
+ {
464
+ $ property = new PropertyReflection ($ prop ->name ->toString (), $ prop ->getLine ());
465
+ $ property ->setModifiers ($ node ->flags );
466
+
467
+ $ property ->setDefault ($ prop ->default );
468
+
469
+ $ docComment = $ node ->getDocComment ();
470
+ $ docComment = $ docComment === null ? null : $ docComment ->__toString ();
471
+ $ comment = $ this ->context ->getDocBlockParser ()->parse ($ docComment , $ this ->context , $ property );
472
+ $ property ->setDocComment ($ docComment );
473
+ $ property ->setShortDesc ($ comment ->getShortDesc ());
474
+ $ property ->setLongDesc ($ comment ->getLongDesc ());
475
+ $ property ->setSee ($ this ->resolveSee ($ comment ->getTag ('see ' )));
476
+
477
+ $ this ->manageHint ($ node ->type , $ property );
503
478
504
479
if ($ errors = $ comment ->getErrors ()) {
505
480
$ property ->setErrors ($ errors );
@@ -643,6 +618,9 @@ protected function updateMethodParametersFromTags(Reflection $method, array $tag
643
618
return $ errors ;
644
619
}
645
620
621
+ /**
622
+ * @phpstan-param $hints array{0: string, 1: bool}
623
+ */
646
624
protected function resolveHint (array $ hints ): array
647
625
{
648
626
foreach ($ hints as $ i => $ hint ) {
@@ -652,6 +630,9 @@ protected function resolveHint(array $hints): array
652
630
return $ hints ;
653
631
}
654
632
633
+ /**
634
+ * @phpstan-param $alias array{0: string, 1: bool}
635
+ */
655
636
protected function resolveAlias ($ alias )
656
637
{
657
638
// not a class
0 commit comments