Skip to content

Commit 0177e33

Browse files
committed
in_array - simulate Identical/Equal handling from TypeSpecifier for literal arrays
1 parent a92585a commit 0177e33

File tree

2 files changed

+28
-3
lines changed

2 files changed

+28
-3
lines changed

src/Analyser/TypeSpecifier.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1556,7 +1556,7 @@ private function getTypeSpecifyingExtensionsForType(array $extensions, string $c
15561556
return array_merge(...$extensionsForClass);
15571557
}
15581558

1559-
public function resolveEqual(Expr\BinaryOp\Equal $expr, Scope $scope, TypeSpecifierContext $context, Expr $rootExpr): SpecifiedTypes
1559+
public function resolveEqual(Expr\BinaryOp\Equal $expr, Scope $scope, TypeSpecifierContext $context, ?Expr $rootExpr): SpecifiedTypes
15601560
{
15611561
$expressions = $this->findTypeExpressionsFromBinaryOperation($scope, $expr);
15621562
if ($expressions !== null) {
@@ -1673,7 +1673,7 @@ public function resolveEqual(Expr\BinaryOp\Equal $expr, Scope $scope, TypeSpecif
16731673
: $leftTypes->normalize($scope)->intersectWith($rightTypes->normalize($scope));
16741674
}
16751675

1676-
public function resolveIdentical(Expr\BinaryOp\Identical $expr, Scope $scope, TypeSpecifierContext $context, Expr $rootExpr): SpecifiedTypes
1676+
public function resolveIdentical(Expr\BinaryOp\Identical $expr, Scope $scope, TypeSpecifierContext $context, ?Expr $rootExpr): SpecifiedTypes
16771677
{
16781678
$leftExpr = $expr->left;
16791679
$rightExpr = $expr->right;

src/Type/Php/InArrayFunctionTypeSpecifyingExtension.php

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
namespace PHPStan\Type\Php;
44

5+
use PhpParser\Node\Expr\Array_;
6+
use PhpParser\Node\Expr\BinaryOp\Identical;
57
use PhpParser\Node\Expr\FuncCall;
68
use PHPStan\Analyser\Scope;
79
use PHPStan\Analyser\SpecifiedTypes;
@@ -49,9 +51,32 @@ public function specifyTypes(FunctionReflection $functionReflection, FuncCall $n
4951
}
5052

5153
$needleExpr = $node->getArgs()[0]->value;
54+
$arrayExpr = $node->getArgs()[1]->value;
55+
if ($arrayExpr instanceof Array_ && $isStrictComparison) {
56+
$types = null;
57+
foreach ($arrayExpr->items as $item) {
58+
if ($item === null) {
59+
continue;
60+
}
61+
$itemTypes = $this->typeSpecifier->resolveIdentical(new Identical($needleExpr, $item->value), $scope, $context, null);
62+
63+
if ($types === null) {
64+
$types = $itemTypes;
65+
continue;
66+
}
67+
68+
$types = $context->true() ? $types->normalize($scope)->intersectWith($itemTypes->normalize($scope)) : $types->unionWith($itemTypes);
69+
}
70+
71+
if ($types !== null) {
72+
return $types;
73+
}
74+
}
75+
5276
$needleType = $scope->getType($needleExpr);
53-
$arrayType = $scope->getType($node->getArgs()[1]->value);
77+
$arrayType = $scope->getType($arrayExpr);
5478
$arrayValueType = $arrayType->getIterableValueType();
79+
5580
$isStrictComparison = $isStrictComparison
5681
|| $needleType->isEnum()->yes()
5782
|| $arrayValueType->isEnum()->yes();

0 commit comments

Comments
 (0)