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

Support for class-string $class parameter in is_subclass_of() #1039

Merged
merged 1 commit into from Feb 27, 2022

Conversation

arnaud-lb
Copy link
Contributor

@arnaud-lb arnaud-lb commented Feb 26, 2022

This adds support for $class parameter of type class-string in is_subclass_of().

I tried to unify the logic for the cases when $class is a constant string, a class string, or something else.

I also tried to narrow the specified type when we know that the $object parameter is either a string or an object. For example if the parameter is a string, it will no longer be specified as class-string|object.

There is one caveat: the type specifier extension may now specify the $object parameter as *NEVER* in some impossible cases. Is this acceptable ?

This fixes phpstan/phpstan#6698

@staabm
Copy link
Contributor

staabm commented Feb 26, 2022

There is one caveat: the type specifier extension may now specify the $object parameter as NEVER in some impossible cases. Is this acceptable ?

when does this happen? Could it use $overwrite=true In this cases?

This would work, when the *NEVER* type is generated because of type validation in

if ($specifiedTypes->shouldOverwrite()) {

@herndlm
Copy link
Contributor

herndlm commented Feb 26, 2022

Hi, I found some inconsistencies with falsey contexts and is_a that I wanted to look into. Or my constant type tests are just odd.
Anyways, since is_a and is_subclass_of are extremely similar (https://3v4l.org/WDt9u) and both have a specifying extension I wanted to mention this. Maybe we can duplicate some logic there or even re-use it and fix bugs for both :)

UPDATE: phpstan/phpstan#6704 is what I was referring to.

@arnaud-lb
Copy link
Contributor Author

@staabm this happens when the $object param is a string, and the $allow_string param is false, or if $object is not a super type of object|string. Both of these cases are not possible in a truthy context and IsSubclassOfFunctionTypeSpecifyingExtension will specify $object to *NEVER* because it intersects between the original $object type and the inferred type.

I took more time to have a better understanding of TypeSpecifyingExtension / TypeSpecifier, and I've found that the intersect is not needed as it's already done by TypeSpecifier::create(). So I've just removed the intersect.

@ondrejmirtes
Copy link
Member

Thank you!

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