Skip to content

Commit eb15c46

Browse files
authored
Added rand() dynamic return type extension
1 parent 39aa45f commit eb15c46

File tree

7 files changed

+32
-12
lines changed

7 files changed

+32
-12
lines changed

src/Type/Php/RandomIntFunctionReturnTypeExtension.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,17 @@ class RandomIntFunctionReturnTypeExtension implements \PHPStan\Type\DynamicFunct
1616

1717
public function isFunctionSupported(FunctionReflection $functionReflection): bool
1818
{
19-
return $functionReflection->getName() === 'random_int';
19+
return in_array($functionReflection->getName(), ['random_int', 'rand'], true);
2020
}
2121

2222
public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope): Type
2323
{
24+
if ($functionReflection->getName() === 'rand' && count($functionCall->args) === 0) {
25+
return IntegerRangeType::fromInterval(0, null);
26+
}
27+
2428
if (count($functionCall->args) < 2) {
25-
return ParametersAcceptorSelector::selectSingle($functionReflection->getVariants())->getReturnType();
29+
return ParametersAcceptorSelector::selectFromArgs($scope, $functionCall->args, $functionReflection->getVariants())->getReturnType();
2630
}
2731

2832
$minType = $scope->getType($functionCall->args[0]->value)->toInteger();

tests/PHPStan/Analyser/AnalyserIntegrationTest.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,8 @@ public function testBug2823(): void
219219
public function testTwoSameClassesInSingleFile(): void
220220
{
221221
$errors = $this->runAnalyse(__DIR__ . '/data/two-same-classes.php');
222-
$this->assertCount(4, $errors);
222+
$this->assertCount(5, $errors);
223+
223224
$error = $errors[0];
224225
$this->assertSame('Property TwoSame\Foo::$prop (string) does not accept default value of type int.', $error->getMessage());
225226
$this->assertSame(9, $error->getLine());
@@ -229,10 +230,14 @@ public function testTwoSameClassesInSingleFile(): void
229230
$this->assertSame(13, $error->getLine());
230231

231232
$error = $errors[2];
233+
$this->assertSame('If condition is always false.', $error->getMessage());
234+
$this->assertSame(18, $error->getLine());
235+
236+
$error = $errors[3];
232237
$this->assertSame('Property TwoSame\Foo::$prop (int) does not accept default value of type string.', $error->getMessage());
233238
$this->assertSame(25, $error->getLine());
234239

235-
$error = $errors[3];
240+
$error = $errors[4];
236241
$this->assertSame('Property TwoSame\Foo::$prop2 (int) does not accept default value of type string.', $error->getMessage());
237242
$this->assertSame(28, $error->getLine());
238243
}

tests/PHPStan/Analyser/LegacyNodeScopeResolverTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8317,7 +8317,7 @@ public function dataFilterVarUnchanged(): array
83178317
'filter_var(3.27, FILTER_VALIDATE_FLOAT, FILTER_NULL_ON_FAILURE)',
83188318
],
83198319
[
8320-
'int',
8320+
'int<0, max>',
83218321
'filter_var(rand(), FILTER_VALIDATE_INT)',
83228322
],
83238323
[

tests/PHPStan/Analyser/data/do-not-remember-impure-functions.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,18 @@ public function doFoo()
1111
{
1212
function (): void {
1313
if (rand(0, 1)) {
14-
assertType('int', rand(0, 1));
14+
assertType('int<0, 1>', rand(0, 1));
1515
}
1616
};
1717

1818
function (): void {
1919
if (rand(0, 1) === 0) {
20-
assertType('int', rand(0, 1));
20+
assertType('int<0, 1>', rand(0, 1));
2121
}
2222
};
2323
function (): void {
24-
assertType('\'foo\'|int<min, -1>|int<1, max>', rand(0, 1) ?: 'foo');
25-
assertType('\'foo\'|int', rand(0, 1) ? rand(0, 1) : 'foo');
24+
assertType('1|\'foo\'', rand(0, 1) ?: 'foo');
25+
assertType('\'foo\'|int<0, 1>', rand(0, 1) ? rand(0, 1) : 'foo');
2626
};
2727
}
2828

tests/PHPStan/Analyser/data/random-int.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,6 @@ function (int $i) {
3737

3838
assertType('int<-5, 5>', random_int(random_int(-5, 0), random_int(0, 5)));
3939
assertType('int', random_int(random_int(PHP_INT_MIN, 0), random_int(0, PHP_INT_MAX)));
40+
41+
assertType('int<-5, 5>', rand(-5, 5));
42+
assertType('int<0, max>', rand());

tests/PHPStan/Analyser/data/strval.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ function intvalTest(string $string): void
3636
assertType('1', intval(true));
3737
assertType('0|1', intval(rand(0, 1) === 0));
3838
assertType('42', intval(42));
39-
assertType('int', intval(rand()));
39+
assertType('int<0, max>', intval(rand()));
4040
assertType('int', intval(rand() * 0.1));
4141
assertType('0', intval([]));
4242
assertType('1', intval([null]));

tests/PHPStan/Rules/Comparison/StrictComparisonOfDifferentTypesRuleTest.php

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,11 @@ public function testStrictComparison(): void
167167
466,
168168
],
169169
[
170-
'Strict comparison using === between int and \'foo\' will always evaluate to false.',
170+
'Strict comparison using === between int<0, 1> and 100 will always evaluate to false.',
171+
622,
172+
],
173+
[
174+
'Strict comparison using === between 100 and \'foo\' will always evaluate to false.',
171175
624,
172176
],
173177
[
@@ -341,7 +345,11 @@ public function testStrictComparisonWithoutAlwaysTrue(): void
341345
466,
342346
],
343347
[
344-
'Strict comparison using === between int and \'foo\' will always evaluate to false.',
348+
'Strict comparison using === between int<0, 1> and 100 will always evaluate to false.',
349+
622,
350+
],
351+
[
352+
'Strict comparison using === between 100 and \'foo\' will always evaluate to false.',
345353
624,
346354
],
347355
[

0 commit comments

Comments
 (0)