Skip to content

Commit

Permalink
Simplify rule logic
Browse files Browse the repository at this point in the history
  • Loading branch information
cs278 committed Jan 14, 2020
1 parent 181132e commit f6ca8ee
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 63 deletions.
81 changes: 25 additions & 56 deletions src/Rules/Functions/RandomIntParametersRule.php
Expand Up @@ -9,6 +9,7 @@
use PHPStan\Rules\RuleErrorBuilder;
use PHPStan\Type\Constant\ConstantIntegerType;
use PHPStan\Type\IntegerRangeType;
use PHPStan\Type\IntegerType;
use PHPStan\Type\VerbosityLevel;

/**
Expand Down Expand Up @@ -43,64 +44,32 @@ public function processNode(Node $node, Scope $scope): array
$minType = $scope->getType($node->args[0]->value)->toInteger();
$maxType = $scope->getType($node->args[1]->value)->toInteger();

if ($minType instanceof ConstantIntegerType
&& $maxType instanceof ConstantIntegerType
&& $minType->getValue() > $maxType->getValue()
) {
return [
RuleErrorBuilder::message(sprintf(
'Cannot call random_int() with $min parameter (%d) greater than $max parameter (%d).',
$minType->getValue(),
$maxType->getValue()
))->build(),
];
}

if ($minType instanceof IntegerRangeType
&& $maxType instanceof ConstantIntegerType
&& $minType->getMax() > $maxType->getValue()
) {
$message = $minType->getMin() > $maxType->getValue()
? 'Cannot call random_int() with $min parameter (%s) greater than $max parameter (%d).'
: 'Cannot call random_int() when $min parameter (%s) can be greater than $max parameter (%d).';

return [
RuleErrorBuilder::message(sprintf(
$message,
$minType->describe(VerbosityLevel::value()),
$maxType->getValue()
))->build(),
];
}

if ($minType instanceof ConstantIntegerType
&& $maxType instanceof IntegerRangeType
&& $minType->getValue() > $maxType->getMin()
) {
$message = $minType->getValue() > $maxType->getMax()
? 'Cannot call random_int() with $max parameter (%s) less than $min parameter (%d).'
: 'Cannot call random_int() when $max parameter (%s) can be less than $min parameter (%d).';

return [
RuleErrorBuilder::message(sprintf(
$message,
$maxType->describe(VerbosityLevel::value()),
$minType->getValue()
))->build(),
];
if ($minType->equals(new IntegerType()) || $maxType->equals(new IntegerType())) {
return [];
}

if ($minType instanceof IntegerRangeType
&& $maxType instanceof IntegerRangeType
&& $minType->getMax() > $maxType->getMin()
) {
return [
RuleErrorBuilder::message(sprintf(
'Cannot call random_int() with intersecting $min (%s) and $max (%s) parameters.',
$minType->describe(VerbosityLevel::value()),
$maxType->describe(VerbosityLevel::value())
))->build(),
];
if ($minType instanceof ConstantIntegerType || $minType instanceof IntegerRangeType) {
if ($minType instanceof ConstantIntegerType) {
$maxPermittedType = IntegerRangeType::fromInterval($minType->getValue(), PHP_INT_MAX);
} else {
$maxPermittedType = IntegerRangeType::fromInterval($minType->getMax(), PHP_INT_MAX);
}

if (!$maxPermittedType->isSuperTypeOf($maxType)->yes()) {
$message = 'Cannot call random_int() when $min parameter (%s) can be greater than $max parameter (%s).';

if ($maxType->isSuperTypeOf($minType)->no()) {
$message = 'Cannot call random_int() when $min parameter (%s) is greater than $max parameter (%s).';
}

return [
RuleErrorBuilder::message(sprintf(
$message,
$minType->describe(VerbosityLevel::value()),
$maxType->describe(VerbosityLevel::value())
))->build(),
];
}
}

return [];
Expand Down
18 changes: 11 additions & 7 deletions tests/PHPStan/Rules/Functions/RandomIntParametersRuleTest.php
Expand Up @@ -17,37 +17,41 @@ public function testFile(): void
{
$this->analyse([__DIR__ . '/data/random-int.php'], [
[
'Cannot call random_int() with $min parameter (1) greater than $max parameter (0).',
'Cannot call random_int() when $min parameter (1) is greater than $max parameter (0).',
8,
],
[
'Cannot call random_int() with $min parameter (0) greater than $max parameter (-1).',
'Cannot call random_int() when $min parameter (0) is greater than $max parameter (-1).',
9,
],
[
'Cannot call random_int() with $max parameter (int<-10, -1>) less than $min parameter (0).',
'Cannot call random_int() when $min parameter (0) is greater than $max parameter (int<-10, -1>).',
11,
],
[
'Cannot call random_int() when $max parameter (int<-10, 10>) can be less than $min parameter (0).',
'Cannot call random_int() when $min parameter (0) can be greater than $max parameter (int<-10, 10>).',
12,
],
[
'Cannot call random_int() with $min parameter (int<1, 10>) greater than $max parameter (0).',
'Cannot call random_int() when $min parameter (int<1, 10>) is greater than $max parameter (0).',
15,
],
[
'Cannot call random_int() when $min parameter (int<-10, 10>) can be greater than $max parameter (0).',
16,
],
[
'Cannot call random_int() with intersecting $min (int<-5, 1>) and $max (int<0, 5>) parameters.',
'Cannot call random_int() when $min parameter (int<-5, 1>) can be greater than $max parameter (int<0, 5>).',
19,
],
[
'Cannot call random_int() with intersecting $min (int<-5, 0>) and $max (int<-1, 5>) parameters.',
'Cannot call random_int() when $min parameter (int<-5, 0>) can be greater than $max parameter (int<-1, 5>).',
20,
],
[
'Cannot call random_int() when $min parameter (int<0, 10>) can be greater than $max parameter (int<0, 10>).',
31,
],
]);
}

Expand Down
1 change: 1 addition & 0 deletions tests/PHPStan/Rules/Functions/data/random-int.php
Expand Up @@ -28,5 +28,6 @@
random_int(0, $x);
random_int($x, random_int(0, PHP_INT_MAX));
random_int(random_int(PHP_INT_MIN, 0), $x);
random_int(random_int(0, 10), random_int(0, 10)); // Equal args are okay except ranges.

random_int(PHP_INT_MAX, PHP_INT_MIN); // @todo this should error

0 comments on commit f6ca8ee

Please sign in to comment.