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

random_int() return type and parameters rule #99

Merged
merged 9 commits into from Jan 16, 2020

Conversation

cs278
Copy link
Contributor

@cs278 cs278 commented Jan 12, 2020

This PR adds a return type extension which teaches PHPStan that random_int() will return an integer between the min/max parameters. The code I've written to get the lower/upper bounds could probably be extracted to be reused as it should handle crazy types like int<0,10>|20|25|int<30,100> which I don't think PHPStan will even create currently.

Secondly there is a rule which performs validation of the input parameters to ensure $min <= $max always holds true. Not sure on what level this should be configured or if it belongs in the strict rules repo.

Unfortunately it's not possible to validate random_int(PHP_INT_MAX, PHP_INT_MIN) as the min/max constants are just converted to a plain integer type, perhaps there is scope for {Min,Max}IntegerType classes.

Copy link
Member

@ondrejmirtes ondrejmirtes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!

src/Rules/Functions/RandomIntParametersRule.php Outdated Show resolved Hide resolved
conf/config.level0.neon Outdated Show resolved Hide resolved
19,
],
[
'Cannot call random_int() with intersecting $min (int<-5, 0>) and $max (int<-1, 5>) parameters.',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This situation might be fine - the code might be correct. This is typically only reported on level 7 thanks to reportMaybes config option.

Feel free to also add this situation to acceptTypes.php in tests/PHPStan/Levels. If you add an offending code and re-run the tests, the asserting JSON files will be updated automatically. Most of the violations should be reported on level 6, but this one on level 7.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the only thing I have not address yet.

$minType = $scope->getType($node->args[0]->value)->toInteger();
$maxType = $scope->getType($node->args[1]->value)->toInteger();

if ($minType instanceof ConstantIntegerType
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We might be able to get rid of all of these ifs with Type::isSuperTypeOf() method. It's really powerful :) If you imagine types as sets then this abstraction holds really well :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, the eureka moment was realising all I needed to do was create a type representing the allowable values for the $max parameter.

Copy link
Member

@ondrejmirtes ondrejmirtes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, you should look into the level 7 stuff with reportMaybe I suggested in the first review. Otherwise it's mergeable! 👍

src/Rules/Functions/RandomIntParametersRule.php Outdated Show resolved Hide resolved
src/Rules/Functions/RandomIntParametersRule.php Outdated Show resolved Hide resolved
@cs278
Copy link
Contributor Author

cs278 commented Jan 15, 2020

Also, you should look into the level 7 stuff with reportMaybe I suggested in the first review. Otherwise it's mergeable!

Yeah not entirely sure what should be considered a "maybe", if the max argument could be less than the min argument should that be a maybe? e.g. 0, int<-1,1> and int<-5,5>, int<0,10> are maybes, but 0, int<-10,-5> and int<10,20>, int<0,5> are always errors?

Copy link
Member

@ondrejmirtes ondrejmirtes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Last change and we're good to go!

@ondrejmirtes ondrejmirtes merged commit 7e57ca0 into phpstan:master Jan 16, 2020
@ondrejmirtes
Copy link
Member

Thank you, I love it!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants