- Notifications
You must be signed in to change notification settings - Fork 545
Add check the array is not empty #305
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
Conversation
| Also I've changed |
ondrejmirtes left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For correct $context handling look at these additional conditions: https://github.com/phpstan/phpstan-src/blob/7dccb9b13014b14776fbd179e190739980452a2d/src/Analyser/TypeSpecifier.php#L198-L217
What they do:
$context->null()is for cases when there's a separate statement. So it can be used for calls that look like this:
$this->checkType($arg); // throws exceptionBut $context->true() and false() is for cases in conditions, like if ($this->isType($arg)).
src/Analyser/TypeSpecifier.php Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So it looks like this handles X < count($arg) and X <= count($arg). And makes the mistake of handling 0 <= count($arg) also as non-empty which is wrong. (There's the $offset variable a few lines above that can be used for this purpose.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's important to replicate everything from https://github.com/phpstan/phpstan-src/blob/7dccb9b13014b14776fbd179e190739980452a2d/src/Analyser/TypeSpecifier.php#L198-L217
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why PHPStan fails in the build with Comparison operation ">" between 0 and 0 is always false. is exactly why this needs to be done :)
| Can you verify that it solves phpstan/phpstan#3558 as well? |
| And also phpstan/phpstan#3631 |
@ondrejmirtes I'm sorry but I don't understand what you mean. I've tried to remove this conditions to check which tests become failed, but all tests are passes without this conditions. Could you please explain which cases covered by this conditions? |
| phpstan/phpstan#3558 and phpstan/phpstan#3631 are not solved, looks like they does not relate to this PR |
| It's also unhandled for |
It means that if you don't check the $context and have a code like this: count($arg) > 0;Then the array in @dktapps Inverted conditions are handled: phpstan-src/src/Analyser/TypeSpecifier.php Lines 412 to 416 in 0632865
|
| @ondrejmirtes As I understood the following test should fail if count($ints) > 0; assertType('int|false', max($ints));But test is passed. Also I don't understend what this code doing if ($context->truthy() || $leftType->getValue() === 0) { $newContext = $context; if ($leftType->getValue() === 0) { $newContext = $newContext->negate(); } // ... }Why the context changed and why this way? I can't write the tests until I understend what the code doing 😃 |
| The linked code handles these cases: if (count($arg) === 0) { // array is empty } else { // array is not empty }And: if (count($arg) !== 0) { // array is not empty } else { // array is empty }Because when the typeSpecifier->create() is called with $context->true(), the passed type is intersected with the expression type, hence Your code currently doesn't work and fails because: That's why PHPStan fails in the build. Also, I'm just realizing we should cover this scenario: if (count($arrayAccessoryTypes) >= 1) { } else { // array is empty }And: if (count($arrayAccessoryTypes) < 1) { // array is empty } else { // array is not empty } |
| After night of debugging I got how it works 😄 |
| @ondrejmirtes Also please look at this test phpstan-src/tests/PHPStan/Analyser/data/bug-2648.php Lines 13 to 21 in 0632865
After this fix |
| Awesome, thank you very much, just merged it! Fixed the failing test with this: e96481c Now that you're fluent in PHPStan's internals, you could help me out by looking at other bugs, I'd really appreciate it :) Issues from this list should be fairly easy to fix: https://github.com/phpstan/phpstan/milestone/8 If you decide to work on something and realize it's more than 50 lines of code to fix it, please reach out to me so we can work on it together. (It's possible that I' wrong and it's not an easy fix, or that you approached it from a different angle.). Thank you once more :) |
| It's said loudly I'm a fluent in PHPStan's internals 😆 The project definitely requires decreasing class sizes and more detailed commenting the code. Anyway I'll glad to help you. |
Closes phpstan/phpstan#3155
I made this the same way as identical compare works (
count($foo) !== 0) but I don't understand what is context and why the checks needed such$context->null(),$context->truthy()and why changing context may be needed$newContext = $newContext->negate().