Skip to content

Commit e504c3f

Browse files
authored
Add missing SpecifiedTypes for count and strlen identical expressions
1 parent bbf14bf commit e504c3f

File tree

3 files changed

+61
-2
lines changed

3 files changed

+61
-2
lines changed

src/Analyser/TypeSpecifier.php

+6-2
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,9 @@ public function specifyTypesInCondition(
210210
}
211211
$argType = $scope->getType($exprNode->getArgs()[0]->value);
212212
if ($argType->isArray()->yes()) {
213-
return $this->create($exprNode->getArgs()[0]->value, new NonEmptyArrayType(), $newContext, false, $scope);
213+
$funcTypes = $this->create($exprNode, $constantType, $context, false, $scope);
214+
$valueTypes = $this->create($exprNode->getArgs()[0]->value, new NonEmptyArrayType(), $newContext, false, $scope);
215+
return $funcTypes->unionWith($valueTypes);
214216
}
215217
}
216218
}
@@ -230,7 +232,9 @@ public function specifyTypesInCondition(
230232
}
231233
$argType = $scope->getType($exprNode->getArgs()[0]->value);
232234
if ($argType instanceof StringType) {
233-
return $this->create($exprNode->getArgs()[0]->value, new AccessoryNonEmptyStringType(), $newContext, false, $scope);
235+
$funcTypes = $this->create($exprNode, $constantType, $context, false, $scope);
236+
$valueTypes = $this->create($exprNode->getArgs()[0]->value, new AccessoryNonEmptyStringType(), $newContext, false, $scope);
237+
return $funcTypes->unionWith($valueTypes);
234238
}
235239
}
236240
}

tests/PHPStan/Analyser/TypeSpecifierTest.php

+53
Original file line numberDiff line numberDiff line change
@@ -1022,6 +1022,59 @@ public function dataCondition(): array
10221022
],
10231023
[],
10241024
],
1025+
[
1026+
new Expr\BinaryOp\BooleanAnd(
1027+
$this->createFunctionCall('is_array', 'foo'),
1028+
new Expr\BinaryOp\GreaterOrEqual(
1029+
new FuncCall(
1030+
new Name('count'),
1031+
[new Arg(new Variable('foo'))],
1032+
),
1033+
new LNumber(2),
1034+
),
1035+
),
1036+
[
1037+
'$foo' => 'non-empty-array',
1038+
'count($foo)' => 'mixed~int<min, 1>|false|null',
1039+
],
1040+
[],
1041+
],
1042+
[
1043+
new Expr\BinaryOp\BooleanAnd(
1044+
$this->createFunctionCall('is_array', 'foo'),
1045+
new Identical(
1046+
new FuncCall(
1047+
new Name('count'),
1048+
[new Arg(new Variable('foo'))],
1049+
),
1050+
new LNumber(2),
1051+
),
1052+
),
1053+
[
1054+
'$foo' => 'non-empty-array',
1055+
'count($foo)' => '2',
1056+
],
1057+
[],
1058+
],
1059+
[
1060+
new Expr\BinaryOp\BooleanAnd(
1061+
$this->createFunctionCall('is_string', 'foo'),
1062+
new NotIdentical(
1063+
new FuncCall(
1064+
new Name('strlen'),
1065+
[new Arg(new Variable('foo'))],
1066+
),
1067+
new LNumber(0),
1068+
),
1069+
),
1070+
[
1071+
'$foo' => 'non-empty-string',
1072+
'strlen($foo)' => '~0',
1073+
],
1074+
[
1075+
'$foo' => '~non-empty-string',
1076+
],
1077+
],
10251078
];
10261079
}
10271080

tests/PHPStan/Analyser/data/bug-2648.php

+2
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ public function doBar(array $list): void
3737
assertType('int<0, max>', count($list));
3838

3939
if (count($list) === 1) {
40+
assertType('1', count($list));
41+
$list[] = false;
4042
assertType('int<1, max>', count($list));
4143
break;
4244
}

0 commit comments

Comments
 (0)