Skip to content

Fix get_class() on HasMethodType#2350

Closed
staabm wants to merge 4 commits intophpstan:1.10.xfrom
staabm:bug4890
Closed

Fix get_class() on HasMethodType#2350
staabm wants to merge 4 commits intophpstan:1.10.xfrom
staabm:bug4890

Conversation

@staabm
Copy link
Contributor

@staabm staabm commented Apr 19, 2023

@phpstan-bot
Copy link
Collaborator

You've opened the pull request against the latest branch 1.11.x. If your code is relevant on 1.10.x and you want it to be released sooner, please rebase your pull request and change its target to 1.10.x.

@staabm staabm changed the base branch from 1.11.x to 1.10.x April 19, 2023 13:25
Copy link
Member

Choose a reason for hiding this comment

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

I think it'd make more sense to get rid of this whole monstrosity (because it'd still fail for HasPropertyType for example - feel free to add a test for it) and also other types like ObjectShapeType.

Instead the whole TypeTraverser::map should be replacable with some methods called on Type.

  • Type::isObject()->no() - always returns false
  • Type::isObject()->yes() - never returns false
  • Type::isObject()->maybe() - might return false

As for the actual type, you could do something like this:

new GenericClassStringType(TypeCombinator::intersect($argType, new ObjectWithoutClassType()));

It will change the result in some cases but it will still be correct.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think your idea works pretty good. one exception is

 PHPStan\Analyser\NodeScopeResolverTest::testFileAsserts with data set "C:\dvl\Workspace\phpstan-src-staabm\tests\PHPStan\Analyser/data/bug-7167.php:11" ('type', 'C:\dvl\Workspace\phpstan-src-...67.php', PHPStan\Type\Constant\ConstantStringType Object (...), PHPStan\Type\Generic\GenericClassStringType Object (...), 11)
Expected type class-string<Bug7167\Foo>, got type class-string<Bug7167\Foo::Value> in C:\dvl\Workspace\phpstan-src-staabm\tests\PHPStan\Analyser/data/bug-7167.php on line 11.
Failed asserting that two strings are identical.
--- Expected
+++ Actual
@@ @@
-'class-string<Bug7167\Foo>'
+'class-string<Bug7167\Foo::Value>'

which I am not yet sure how to handle

Comment on lines 53 to 56
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I am sure you won't like it, but I think it seems to be necessary.

without this case we get things like
class-string<object{foo: Bug4890\HelloWorld, bar: int, baz?: string}>

when intersecting ObjectShapeType and ObjectWithoutClassType.

@clxmstaab clxmstaab force-pushed the bug4890 branch 2 times, most recently from 7f8af6f to 77c061f Compare April 20, 2023 08:16
Copy link
Contributor Author

Choose a reason for hiding this comment

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

see https://phpstan.org/r/b6b95d5a-a3fb-4c29-be47-4e7832f00ddc regarding how this test fails before this PR

@staabm
Copy link
Contributor Author

staabm commented Apr 26, 2023

think I figured it out - I had to re-introduce the TypeTraverser for the EnumCaseObjectType

#2350 (comment)

if ($type instanceof ObjectWithoutClassType) {
return new GenericClassStringType($type);
$isObject = $type->isObject();
if ($isObject->yes() || $isObject->maybe()) {
Copy link
Member

Choose a reason for hiding this comment

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

For which type here it's going to be a maybe?


$objectType = TypeCombinator::intersect($type, new ObjectWithoutClassType());
if ($objectType instanceof StaticType) {
$objectType = $objectType->getStaticObjectType();
Copy link
Member

Choose a reason for hiding this comment

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

Why are you checking this after an intersection?

@staabm staabm closed this Feb 10, 2026
@staabm staabm deleted the bug4890 branch February 10, 2026 16:42
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.

false positive due to method_exists call beforehand

3 participants