Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

class_exists(Interface::class) is always false #2838

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

Open
janedbal wants to merge 3 commits into phpstan:1.10.x
base: 1.10.x
Choose a base branch
Loading
from janedbal:class-exists-iface

Conversation

@janedbal
Copy link
Contributor

@janedbal janedbal commented Dec 20, 2023

Copy link
Contributor

staabm commented Dec 20, 2023
edited
Loading

I tried similar things in #2277
I think you can get inspiration about a few more cases which need to be handled here in the linked PR.

beware: ondrej might have different opinions.. feedback on the linked PR was not discussed yet


and we should have an eye on issuebot, as IIRC there should be more open issues regarding this topic.

Comment on lines +86 to +93
$argType = $scope->getType($node->getArgs()[0]->value);
if (count($argType->getConstantStrings()) !== 1) {
return null;
}
$argConstantString = $argType->getConstantStrings()[0];
if (!$this->reflectionProvider->hasClass($argConstantString->getValue())) {
return null;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

you are missing things like

$c = _Enum::class;
if (rand(0,1)) {
 $c = _Class::class;
}
class_exists($c);

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, I dont want to cover all edgecases..

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.

I'd rather be if this was somehow done in ClassExistsFunctionTypeSpecifyingExtension instead of ImpossibleCheckTypeHelper.

ClassExistsFunctionTypeSpecifyingExtension is "closer to the core" and can influence the correctness in more places, for example class_exists($foo) for $foo being class-string<SomeInterface> should lead to NeverType for $foo.

ImpossibleCheckTypeHelper is only informing the rules right at the end of the analysis.

I understand this can lead to some more work because telling that Scalar\String_ should be NeverType can break assumptions in some places.

}

if ($functionName === 'enum_exists' && ($reflection->isClass() || $reflection->isInterface() || $reflection->isTrait())) {
return false;
Copy link
Member

@ondrejmirtes ondrejmirtes Jan 3, 2024

Choose a reason for hiding this comment

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

I think these conditions could be improved. Name what it cannot be instead of what it can be, for example:

if ($functionName === 'interface_exists' && !$reflection->isInterface()) {

Copy link
Contributor Author

@janedbal janedbal Jan 5, 2024

Choose a reason for hiding this comment

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

But that can break if some future PHP version onboards new struct type. But that would probably lead to many changes everywhere, so why not...

Copy link
Contributor Author

janedbal commented Jan 5, 2024
edited
Loading

I'd rather be if this was somehow done in ClassExistsFunctionTypeSpecifyingExtension

I agree, but cannot we do it as next step and merge this?


Note: I dont feel implementing that in near future.

Copy link
Member

We're in no rush here and doing this correctly can always teach us something new :)

Copy link
Contributor Author

janedbal commented Jan 5, 2024

We're in no rush here and doing this correctly can always teach us something new :)

Ok, then we can probably close this PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@ondrejmirtes ondrejmirtes ondrejmirtes requested changes

+1 more reviewer

@staabm staabm staabm left review comments

Reviewers whose approvals may not affect merge requirements

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

AltStyle によって変換されたページ (->オリジナル) /