Skip to content

Refactor nullOr handling #127

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

Closed
wants to merge 3 commits into from

Conversation

herndlm
Copy link
Contributor

@herndlm herndlm commented Mar 10, 2022

This is similar to the refactored all handling. It avoids building the core expression with invalid types by handling this differently. E.g. int|null is valid input for nullOrGreaterThan and we know that the core greaterThan expression would only be called with int. But this was not the case at the moment because it is building the expression and using information from the original type which still has the null. So this PR adapts that and should make the handling of all nullOr asserts safer by getting the right type when building the expression. It, obviously, has to add null back to the type later on, but I think this is more predictable than the current behaviour.

This is related to #120 and will help me use a stricter type checking approach there to fix the int-range assertions because I don't have the annoying null anymore.

Downside: I kind of started duplicating parts of SpecifiedTypes::normalize which is not part of the API yet. I don't have a problem with that, but if we want to make it part of the API I could get rid of most of the logic in determineVariableTypeFromSpecifiedTypes.

@herndlm herndlm marked this pull request as draft March 10, 2022 10:03
@herndlm herndlm marked this pull request as ready for review March 10, 2022 10:05
@herndlm herndlm force-pushed the refactor-null-or-handling branch from 8570fc7 to bfd1c52 Compare March 10, 2022 10:10
@ondrejmirtes
Copy link
Member

Sorry, I'm not getting it. What's wrong with handling nullOr with an expression that has BooleanOr at the root?

@ondrejmirtes
Copy link
Member

Like - why does it need all the extra code?

@herndlm
Copy link
Contributor Author

herndlm commented Mar 10, 2022

E.g. nullOrGreaterThan($a, 17) with $a being int|null would be translated to

$a === null || $a > 17

which is fine of course. But we're building the $a > 17 expression first with the original type info of $a where there's still the null value there. When being executed it will never be there anymore though. And the fact that it's there makes the handling in #120 weird IMO where I want to actually check which type $a has. I'd like to use !(new IntegerType())->isSuperTypeOf($valueType)->yes()) there but can't because the null is still there.

Maybe you can think of a better solution. It is mostly to fix future issues where I want to skip type specification because the extension won't add any additional info anymore like with the greaterThan that only is useful for int-ranges basically.

Like - why does it need all the extra code?

I think mostly because I couldn't come up with another way of getting rid of the null inside the expression resolvers nicely without hacking around even more :)

@ondrejmirtes
Copy link
Member

I think we need to make https://github.com/phpstan/phpstan-src/blob/master/src/Rules/Comparison/ImpossibleCheckTypeHelper.php somehow smarter so that it does not report these false positives: #118, #119

The logic inside is kind of weird and kept stabbing me in the back when I worked on phpstan/phpstan-src#1058. I feel like the extension should be kept as clean as possible instead of working around these issues.

@herndlm
Copy link
Contributor Author

herndlm commented Mar 10, 2022

OK, good idea and makes sense. I'll try to think about it over the next days

@ondrejmirtes
Copy link
Member

Also maybe in these examples the issue isn't in ImpossibleCheckTypeHelper but in the SpecifiedTypes that TypeSpecifier produces for Greater and similar operators :) Maybe they need a similar treatment as I did for Identical in phpstan/phpstan-src#1058, but I'm just guessing.

@herndlm
Copy link
Contributor Author

herndlm commented Mar 10, 2022

Yeah, could be. And I remember debugging this and seeing different types specified when using this extension and when using the same expression in an if in phpstan itself, I think. But also not sure anymore

@ondrejmirtes
Copy link
Member

I just got an idea how to solve this once and for all, will try it in the next few days 😊

@herndlm herndlm deleted the refactor-null-or-handling branch May 3, 2022 20:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants