Skip to content

Commit ae8eb1a

Browse files
committed
Port _checkType implementation from v2
1 parent 30284b0 commit ae8eb1a

File tree

1 file changed

+33
-17
lines changed

1 file changed

+33
-17
lines changed

src/functions.php

Lines changed: 33 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -342,33 +342,49 @@ function _checkTypehint(callable $callback, \Throwable $reason): bool
342342
return true;
343343
}
344344

345-
$type = $parameters[0]->getType();
345+
$expectedException = $parameters[0];
346346

347-
if (!$type) {
348-
return true;
349-
}
347+
// PHP before v8 used an easy API:
348+
if (\PHP_VERSION_ID < 70100 || \defined('HHVM_VERSION')) {
349+
if (!$expectedException->getClass()) {
350+
return true;
351+
}
350352

351-
$types = [$type];
353+
return $expectedException->getClass()->isInstance($reason);
354+
}
352355

353-
if ($type instanceof \ReflectionUnionType) {
354-
$types = $type->getTypes();
356+
// Extract the type of the argument and handle different possibilities
357+
$type = $expectedException->getType();
358+
$types = [];
359+
360+
switch (true) {
361+
case $type === null:
362+
break;
363+
case $type instanceof \ReflectionNamedType:
364+
$types = [$type];
365+
break;
366+
case $type instanceof \ReflectionUnionType;
367+
$types = $type->getTypes();
368+
break;
369+
default:
370+
throw new \LogicException('Unexpected return value of ReflectionParameter::getType');
355371
}
356372

357-
$mismatched = false;
373+
// If there is no type restriction, it matches
374+
if (empty($types)) {
375+
return true;
376+
}
358377

378+
// Search for one matching named-type for success, otherwise return false
379+
// A named-type can be either a class-name or a built-in type like string, int, array, etc.
359380
foreach ($types as $type) {
360-
if (!$type || $type->isBuiltin()) {
361-
continue;
362-
}
381+
$matches = ($type->isBuiltin() && \gettype($reason) === $type->getName())
382+
|| (new \ReflectionClass($type->getName()))->isInstance($reason);
363383

364-
$expectedClass = $type->getName();
365-
366-
if ($reason instanceof $expectedClass) {
384+
if ($matches) {
367385
return true;
368386
}
369-
370-
$mismatched = true;
371387
}
372388

373-
return !$mismatched;
389+
return false;
374390
}

0 commit comments

Comments
 (0)