@@ -354,6 +354,8 @@ function _checkTypehint(callable $callback, $object)
354
354
355
355
// Extract the type of the argument and handle different possibilities
356
356
$ type = $ expectedException ->getType ();
357
+
358
+ $ isTypeUnion = true ;
357
359
$ types = [];
358
360
359
361
switch (true ) {
@@ -362,6 +364,8 @@ function _checkTypehint(callable $callback, $object)
362
364
case $ type instanceof \ReflectionNamedType:
363
365
$ types = [$ type ];
364
366
break ;
367
+ case $ type instanceof \ReflectionIntersectionType:
368
+ $ isTypeUnion = false ;
365
369
case $ type instanceof \ReflectionUnionType;
366
370
$ types = $ type ->getTypes ();
367
371
break ;
@@ -374,16 +378,30 @@ function _checkTypehint(callable $callback, $object)
374
378
return true ;
375
379
}
376
380
377
- // Search for one matching named-type for success, otherwise return false
378
- // A named-type can be either a class-name or a built-in type like string, int, array, etc.
379
381
foreach ($ types as $ type ) {
382
+ if (!$ type instanceof \ReflectionNamedType) {
383
+ throw new \LogicException ('This implementation does not support groups of intersection or union types ' );
384
+ }
385
+
386
+ // A named-type can be either a class-name or a built-in type like string, int, array, etc.
380
387
$ matches = ($ type ->isBuiltin () && \gettype ($ object ) === $ type ->getName ())
381
388
|| (new \ReflectionClass ($ type ->getName ()))->isInstance ($ object );
382
389
390
+
391
+ // If we look for a single match (union), we can return early on match
392
+ // If we look for a full match (intersection), we can return early on mismatch
383
393
if ($ matches ) {
384
- return true ;
394
+ if ($ isTypeUnion ) {
395
+ return true ;
396
+ }
397
+ } else {
398
+ if (!$ isTypeUnion ) {
399
+ return false ;
400
+ }
385
401
}
386
402
}
387
403
388
- return false ;
404
+ // If we look for a single match (union) and did not return early, we matched no type and are false
405
+ // If we look for a full match (intersection) and did not return early, we matched all types and are true
406
+ return $ isTypeUnion ? false : true ;
389
407
}
0 commit comments