Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added rand() return-type extension #606

Merged
merged 13 commits into from
Aug 12, 2021
8 changes: 6 additions & 2 deletions src/Type/Php/RandomIntFunctionReturnTypeExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,17 @@ class RandomIntFunctionReturnTypeExtension implements \PHPStan\Type\DynamicFunct

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

public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope): Type
{
if ($functionReflection->getName() === 'rand' && count($functionCall->args) === 0) {
staabm marked this conversation as resolved.
Show resolved Hide resolved
return IntegerRangeType::fromInterval(0, null);
}

if (count($functionCall->args) < 2) {
return ParametersAcceptorSelector::selectSingle($functionReflection->getVariants())->getReturnType();
return ParametersAcceptorSelector::selectFromArgs($scope, $functionCall->args, $functionReflection->getVariants())->getReturnType();
}

$minType = $scope->getType($functionCall->args[0]->value)->toInteger();
Expand Down
9 changes: 7 additions & 2 deletions tests/PHPStan/Analyser/AnalyserIntegrationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,8 @@ public function testBug2823(): void
public function testTwoSameClassesInSingleFile(): void
{
$errors = $this->runAnalyse(__DIR__ . '/data/two-same-classes.php');
$this->assertCount(4, $errors);
$this->assertCount(5, $errors);
staabm marked this conversation as resolved.
Show resolved Hide resolved
staabm marked this conversation as resolved.
Show resolved Hide resolved

$error = $errors[0];
$this->assertSame('Property TwoSame\Foo::$prop (string) does not accept default value of type int.', $error->getMessage());
$this->assertSame(9, $error->getLine());
Expand All @@ -229,10 +230,14 @@ public function testTwoSameClassesInSingleFile(): void
$this->assertSame(13, $error->getLine());

$error = $errors[2];
$this->assertSame('If condition is always false.', $error->getMessage());
$this->assertSame(18, $error->getLine());

$error = $errors[3];
$this->assertSame('Property TwoSame\Foo::$prop (int) does not accept default value of type string.', $error->getMessage());
$this->assertSame(25, $error->getLine());

$error = $errors[3];
$error = $errors[4];
$this->assertSame('Property TwoSame\Foo::$prop2 (int) does not accept default value of type string.', $error->getMessage());
$this->assertSame(28, $error->getLine());
}
Expand Down
2 changes: 1 addition & 1 deletion tests/PHPStan/Analyser/LegacyNodeScopeResolverTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -8317,7 +8317,7 @@ public function dataFilterVarUnchanged(): array
'filter_var(3.27, FILTER_VALIDATE_FLOAT, FILTER_NULL_ON_FAILURE)',
],
[
'int',
'int<0, max>',
'filter_var(rand(), FILTER_VALIDATE_INT)',
],
[
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,18 @@ public function doFoo()
{
function (): void {
if (rand(0, 1)) {
assertType('int', rand(0, 1));
assertType('int<0, 1>', rand(0, 1));
}
};

function (): void {
if (rand(0, 1) === 0) {
assertType('int', rand(0, 1));
assertType('int<0, 1>', rand(0, 1));
}
};
function (): void {
assertType('\'foo\'|int<min, -1>|int<1, max>', rand(0, 1) ?: 'foo');
assertType('\'foo\'|int', rand(0, 1) ? rand(0, 1) : 'foo');
assertType('1|\'foo\'', rand(0, 1) ?: 'foo');
assertType('\'foo\'|int<0, 1>', rand(0, 1) ? rand(0, 1) : 'foo');
};
}

Expand Down
3 changes: 3 additions & 0 deletions tests/PHPStan/Analyser/data/random-int.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,6 @@ function (int $i) {

assertType('int<-5, 5>', random_int(random_int(-5, 0), random_int(0, 5)));
assertType('int', random_int(random_int(PHP_INT_MIN, 0), random_int(0, PHP_INT_MAX)));

assertType('int<-5, 5>', rand(-5, 5));
assertType('int<0, max>', rand());
2 changes: 1 addition & 1 deletion tests/PHPStan/Analyser/data/strval.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ function intvalTest(string $string): void
assertType('1', intval(true));
assertType('0|1', intval(rand(0, 1) === 0));
assertType('42', intval(42));
assertType('int', intval(rand()));
assertType('int<0, max>', intval(rand()));
assertType('int', intval(rand() * 0.1));
assertType('0', intval([]));
assertType('1', intval([null]));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,11 @@ public function testStrictComparison(): void
466,
],
[
'Strict comparison using === between int and \'foo\' will always evaluate to false.',
'Strict comparison using === between int<0, 1> and 100 will always evaluate to false.',
622,
],
[
'Strict comparison using === between 100 and \'foo\' will always evaluate to false.',
624,
],
[
Expand Down Expand Up @@ -341,7 +345,11 @@ public function testStrictComparisonWithoutAlwaysTrue(): void
466,
],
[
'Strict comparison using === between int and \'foo\' will always evaluate to false.',
'Strict comparison using === between int<0, 1> and 100 will always evaluate to false.',
622,
],
[
'Strict comparison using === between 100 and \'foo\' will always evaluate to false.',
624,
],
[
Expand Down