|
7 | 7 | use Countable;
|
8 | 8 | use PhpParser\Node\Arg;
|
9 | 9 | use PhpParser\Node\Expr;
|
| 10 | +use PhpParser\Node\Expr\Array_; |
| 11 | +use PhpParser\Node\Expr\ArrayItem; |
| 12 | +use PhpParser\Node\Expr\BinaryOp; |
10 | 13 | use PhpParser\Node\Expr\BinaryOp\BooleanAnd;
|
11 | 14 | use PhpParser\Node\Expr\BinaryOp\BooleanOr;
|
12 | 15 | use PhpParser\Node\Expr\BinaryOp\Greater;
|
|
45 | 48 | use PHPStan\Type\TypeWithClassName;
|
46 | 49 | use ReflectionObject;
|
47 | 50 | use Traversable;
|
| 51 | +use function array_filter; |
48 | 52 | use function array_key_exists;
|
| 53 | +use function array_map; |
| 54 | +use function array_reduce; |
| 55 | +use function array_shift; |
49 | 56 | use function count;
|
50 | 57 | use function key;
|
51 | 58 | use function lcfirst;
|
@@ -366,6 +373,21 @@ private static function getExpressionResolvers(): array
|
366 | 373 | $className
|
367 | 374 | );
|
368 | 375 | },
|
| 376 | + 'isInstanceOfAny' => static function (Scope $scope, Arg $expr, Arg $classes): ?Expr { |
| 377 | + if (!$classes->value instanceof Array_ || $classes->value->items === null) { |
| 378 | + return null; |
| 379 | + } |
| 380 | + |
| 381 | + $resolvers = array_map( |
| 382 | + static function (?ArrayItem $class) use ($scope, $expr) { |
| 383 | + return $class !== null ? self::$resolvers['isInstanceOf']($scope, $expr, new Arg($class->value)) : null; |
| 384 | + }, |
| 385 | + $classes->value->items |
| 386 | + ); |
| 387 | + $resolvers = array_filter($resolvers); |
| 388 | + |
| 389 | + return self::implodeExpr($resolvers, BooleanOr::class); |
| 390 | + }, |
369 | 391 | 'notInstanceOf' => static function (Scope $scope, Arg $expr, Arg $class): ?Expr {
|
370 | 392 | $classType = $scope->getType($class->value);
|
371 | 393 | if ($classType instanceof ConstantStringType) {
|
@@ -779,4 +801,24 @@ private function arrayOrIterable(
|
779 | 801 | );
|
780 | 802 | }
|
781 | 803 |
|
| 804 | + /** |
| 805 | + * @param Expr[] $expressions |
| 806 | + * @param class-string<BinaryOp> $binaryOp |
| 807 | + */ |
| 808 | + private static function implodeExpr(array $expressions, string $binaryOp): ?Expr |
| 809 | + { |
| 810 | + $firstExpression = array_shift($expressions); |
| 811 | + if ($firstExpression === null) { |
| 812 | + return null; |
| 813 | + } |
| 814 | + |
| 815 | + return array_reduce( |
| 816 | + $expressions, |
| 817 | + static function (Expr $carry, Expr $item) use ($binaryOp) { |
| 818 | + return new $binaryOp($carry, $item); |
| 819 | + }, |
| 820 | + $firstExpression |
| 821 | + ); |
| 822 | + } |
| 823 | + |
782 | 824 | }
|
0 commit comments