|
8 | 8 | use PhpParser\Node\Arg; |
9 | 9 | use PhpParser\Node\Expr; |
10 | 10 | use PhpParser\Node\Expr\Array_; |
| 11 | +use PhpParser\Node\Expr\ArrayDimFetch; |
11 | 12 | use PhpParser\Node\Expr\ArrayItem; |
12 | 13 | use PhpParser\Node\Expr\BinaryOp; |
13 | 14 | use PhpParser\Node\Expr\BinaryOp\BooleanAnd; |
|
25 | 26 | use PhpParser\Node\Expr\FuncCall; |
26 | 27 | use PhpParser\Node\Expr\Instanceof_; |
27 | 28 | use PhpParser\Node\Expr\StaticCall; |
28 | | -use PhpParser\Node\Expr\Variable; |
29 | 29 | use PhpParser\Node\Name; |
30 | | -use PhpParser\Node\Param; |
31 | 30 | use PhpParser\Node\Scalar\LNumber; |
32 | 31 | use PhpParser\Node\Scalar\String_; |
33 | | -use PhpParser\Node\Stmt\Return_; |
34 | 32 | use PHPStan\Analyser\Scope; |
35 | 33 | use PHPStan\Analyser\SpecifiedTypes; |
36 | 34 | use PHPStan\Analyser\TypeSpecifier; |
|
44 | 42 | use PHPStan\Type\Constant\ConstantStringType; |
45 | 43 | use PHPStan\Type\IterableType; |
46 | 44 | use PHPStan\Type\MixedType; |
| 45 | +use PHPStan\Type\NeverType; |
47 | 46 | use PHPStan\Type\ObjectType; |
48 | 47 | use PHPStan\Type\StaticMethodTypeSpecifyingExtension; |
49 | 48 | use PHPStan\Type\StringType; |
|
59 | 58 | use function array_reduce; |
60 | 59 | use function array_shift; |
61 | 60 | use function count; |
62 | | -use function key; |
63 | 61 | use function lcfirst; |
64 | 62 | use function substr; |
65 | 63 |
|
@@ -774,56 +772,35 @@ private function handleAll( |
774 | 772 | Scope $scope |
775 | 773 | ): SpecifiedTypes |
776 | 774 | { |
777 | | - $closureItemVariable = new Variable('item'); |
778 | | - $closureArgs = $node->getArgs(); |
779 | | - $closureArgs[0] = new Arg($closureItemVariable); |
780 | | - |
781 | | - $expression = new BooleanAnd( |
782 | | - new FuncCall(new Name('is_iterable'), [$node->getArgs()[0]]), |
783 | | - new Identical( |
784 | | - $node->getArgs()[0]->value, |
785 | | - new FuncCall( |
786 | | - new Name('array_filter'), |
787 | | - [ |
788 | | - new Arg($node->getArgs()[0]->value), |
789 | | - new Arg( |
790 | | - new Expr\Closure( |
791 | | - [ |
792 | | - 'static' => true, |
793 | | - 'params' => [new Param($closureItemVariable)], |
794 | | - 'stmts' => [ |
795 | | - new Return_(self::createExpression($scope, $methodName, $closureArgs)), |
796 | | - ], |
797 | | - ] |
798 | | - ) |
799 | | - ), |
800 | | - ] |
801 | | - ) |
802 | | - ) |
803 | | - ); |
| 775 | + $args = $node->getArgs(); |
| 776 | + $args[0] = new Arg(new ArrayDimFetch($args[0]->value, new LNumber(0))); |
| 777 | + $expression = self::createExpression($scope, $methodName, $args); |
| 778 | + if ($expression === null) { |
| 779 | + return new SpecifiedTypes(); |
| 780 | + } |
804 | 781 |
|
805 | 782 | $specifiedTypes = $this->typeSpecifier->specifyTypesInCondition( |
806 | 783 | $scope, |
807 | 784 | $expression, |
808 | 785 | TypeSpecifierContext::createTruthy() |
809 | 786 | ); |
810 | 787 |
|
811 | | - if (count($specifiedTypes->getSureTypes()) > 0) { |
812 | | - $sureTypes = $specifiedTypes->getSureTypes(); |
813 | | - $exprString = key($sureTypes); |
814 | | - [$exprNode, $type] = $sureTypes[$exprString]; |
| 788 | + $sureNotTypes = $specifiedTypes->getSureNotTypes(); |
| 789 | + foreach ($specifiedTypes->getSureTypes() as $exprStr => [$exprNode, $type]) { |
| 790 | + if ($exprNode !== $args[0]->value) { |
| 791 | + continue; |
| 792 | + } |
| 793 | + |
| 794 | + $type = TypeCombinator::remove($type, $sureNotTypes[$exprStr][1] ?? new NeverType()); |
815 | 795 |
|
816 | 796 | return $this->arrayOrIterable( |
817 | 797 | $scope, |
818 | | - $exprNode, |
| 798 | + $node->getArgs()[0]->value, |
819 | 799 | static function () use ($type): Type { |
820 | | - return $type->getIterableValueType(); |
| 800 | + return $type; |
821 | 801 | } |
822 | 802 | ); |
823 | 803 | } |
824 | | - if (count($specifiedTypes->getSureNotTypes()) > 0) { |
825 | | - throw new ShouldNotHappenException(); |
826 | | - } |
827 | 804 |
|
828 | 805 | return $specifiedTypes; |
829 | 806 | } |
@@ -861,7 +838,9 @@ private function arrayOrIterable( |
861 | 838 | return $this->typeSpecifier->create( |
862 | 839 | $expr, |
863 | 840 | $specifiedType, |
864 | | - TypeSpecifierContext::createTruthy() |
| 841 | + TypeSpecifierContext::createTruthy(), |
| 842 | + false, |
| 843 | + $scope |
865 | 844 | ); |
866 | 845 | } |
867 | 846 |
|
|
0 commit comments