Skip to content

Commit 3ff9877

Browse files
Respect phpstan level in ParameterCastableToNumberRule
1 parent f0fc378 commit 3ff9877

File tree

3 files changed

+67
-8
lines changed

3 files changed

+67
-8
lines changed

src/Rules/ParameterCastableToStringCheck.php

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use PHPStan\Analyser\ArgumentsNormalizer;
77
use PHPStan\Analyser\Scope;
88
use PHPStan\DependencyInjection\AutowiredService;
9+
use PHPStan\Node\Expr\TypeExpr;
910
use PHPStan\Reflection\ParameterReflection;
1011
use PHPStan\Type\ErrorType;
1112
use PHPStan\Type\Type;
@@ -34,22 +35,31 @@ public function checkParameter(
3435
return null;
3536
}
3637

37-
$typeResult = $this->ruleLevelHelper->findTypeToCheck(
38+
$arrayTypeResult = $this->ruleLevelHelper->findTypeToCheck(
3839
$scope,
3940
$parameter->value,
4041
'',
41-
static fn (Type $type): bool => $type->isArray()->yes() && !$castFn($type->getIterableValueType()) instanceof ErrorType,
42+
static fn (Type $type): bool => $type->isArray()->yes(),
43+
);
44+
45+
$arrayType = $arrayTypeResult->getType();
46+
if (!$arrayType->isArray()->yes()) {
47+
return null;
48+
}
49+
50+
$typeResult = $this->ruleLevelHelper->findTypeToCheck(
51+
$scope,
52+
new TypeExpr($arrayType->getIterableValueType()),
53+
'',
54+
static fn (Type $type): bool => !$castFn($type) instanceof ErrorType,
4255
);
4356

44-
if (
45-
! $typeResult->getType()->isArray()->yes()
46-
|| !$castFn($typeResult->getType()->getIterableValueType()) instanceof ErrorType
47-
) {
57+
if (!$castFn($typeResult->getType()) instanceof ErrorType) {
4858
return null;
4959
}
5060

5161
return RuleErrorBuilder::message(
52-
sprintf($errorMessageTemplate, $parameterName, $functionName, $typeResult->getType()->describe(VerbosityLevel::typeOnly())),
62+
sprintf($errorMessageTemplate, $parameterName, $functionName, $arrayTypeResult->getType()->describe(VerbosityLevel::typeOnly())),
5363
)->identifier('argument.type')->build();
5464
}
5565

tests/PHPStan/Rules/Functions/ParameterCastableToNumberRuleTest.php

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,18 @@
1818
class ParameterCastableToNumberRuleTest extends RuleTestCase
1919
{
2020

21+
private bool $checkUnion = true;
22+
23+
private bool $checkExplicitMixed = true;
24+
25+
private bool $checkImplicitMixed = true;
26+
2127
protected function getRule(): Rule
2228
{
2329
$broker = self::createReflectionProvider();
2430
return new ParameterCastableToNumberRule(
2531
$broker,
26-
new ParameterCastableToStringCheck(new RuleLevelHelper($broker, true, false, true, true, true, false, true)),
32+
new ParameterCastableToStringCheck(new RuleLevelHelper($broker, true, false, $this->checkUnion, $this->checkExplicitMixed, $this->checkImplicitMixed, false, true)),
2733
self::getContainer()->getByType(PhpVersion::class),
2834
);
2935
}
@@ -213,6 +219,39 @@ public function testBug13775Bis(): void
213219
$this->analyse([__DIR__ . '/data/bug-13775-bis.php'], $this->hackPhp74ErrorMessages($errors));
214220
}
215221

222+
public function testBug13775TerWithoutMixed(): void
223+
{
224+
$this->checkExplicitMixed = false;
225+
$this->checkImplicitMixed = false;
226+
227+
$this->analyse([__DIR__ . '/data/bug-13775-ter.php'], $this->hackPhp74ErrorMessages([
228+
[
229+
'Parameter #1 $array of function array_sum expects an array of values castable to number, array<int, int|string> given.',
230+
9,
231+
],
232+
[
233+
'Parameter #1 $array of function array_product expects an array of values castable to number, array<int, int|string> given.',
234+
10,
235+
],
236+
]));
237+
}
238+
239+
public function testBug13775TerWithoutUnion(): void
240+
{
241+
$this->checkUnion = false;
242+
243+
$this->analyse([__DIR__ . '/data/bug-13775-ter.php'], $this->hackPhp74ErrorMessages([
244+
[
245+
'Parameter #1 $array of function array_sum expects an array of values castable to number, array<int, mixed> given.',
246+
5,
247+
],
248+
[
249+
'Parameter #1 $array of function array_product expects an array of values castable to number, array<int, mixed> given.',
250+
6,
251+
],
252+
]));
253+
}
254+
216255
public function testBug12146(): void
217256
{
218257
$this->analyse([__DIR__ . '/data/bug-12146.php'], $this->hackPhp74ErrorMessages([
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php declare(strict_types = 1);
2+
3+
/** @var mixed $a */
4+
$a = doFoo();
5+
echo array_sum([$a]) . "\n\n";
6+
echo array_product([$a]) . "\n\n";
7+
8+
$b = rand(0, 1) ? 42 : '';
9+
echo array_sum([$b]) . "\n\n";
10+
echo array_product([$b]) . "\n\n";

0 commit comments

Comments
 (0)