Skip to content

Commit

Permalink
CallStaticMethodsRule - fix case with non-object class-string
Browse files Browse the repository at this point in the history
  • Loading branch information
ondrejmirtes committed Feb 17, 2021
1 parent 396ee25 commit ec2ef2a
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 0 deletions.
4 changes: 4 additions & 0 deletions src/Rules/Methods/CallStaticMethodsRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
use PHPStan\Type\ErrorType;
use PHPStan\Type\Generic\GenericClassStringType;
use PHPStan\Type\ObjectType;
use PHPStan\Type\ObjectWithoutClassType;
use PHPStan\Type\StringType;
use PHPStan\Type\ThisType;
use PHPStan\Type\Type;
Expand Down Expand Up @@ -170,6 +171,9 @@ static function (Type $type) use ($methodName): bool {

if ($classType instanceof GenericClassStringType) {
$classType = $classType->getGenericType();
if (!(new ObjectWithoutClassType())->isSuperTypeOf($classType)->yes()) {
return [];
}
} elseif ((new StringType())->isSuperTypeOf($classType)->yes()) {
return [];
}
Expand Down
15 changes: 15 additions & 0 deletions tests/PHPStan/Rules/Methods/CallStaticMethodsRuleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -403,4 +403,19 @@ public function testBug577(): void
$this->analyse([__DIR__ . '/data/bug-577.php'], []);
}

public function testBug4550(): void
{
$this->checkThisOnly = false;
$this->analyse([__DIR__ . '/data/bug-4550.php'], [
[
'Parameter #1 $class of static method Bug4550\Test::valuesOf() expects class-string<Person>, string given.',
34,
],
[
'Parameter #1 $class of static method Bug4550\Test::valuesOf() expects class-string<Person>, string given.',
44,
],
]);
}

}
46 changes: 46 additions & 0 deletions tests/PHPStan/Rules/Methods/data/bug-4550.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php

namespace Bug4550;

class Test
{
/**
* @template T
* @param class-string<T> $class
*/
public static function valuesOf(string $class): void
{
(new $class())->values();
assert(method_exists($class, 'values'));
$class::values();
}

/**
* @template T
* @param class-string<T> $class
*/
public static function doBar(string $class): void
{
(new $class())->values();
$class::values();
}

/**
* @param class-string<self> $s
*/
public function doBaz(string $s): void
{
$s::valuesOf(\stdClass::class);
$s::valuesOf('Person');
}

/**
* @template T of self
* @param class-string<T> $s
*/
public function doLorem(string $s): void
{
$s::valuesOf(\stdClass::class);
$s::valuesOf('Person');
}
}

0 comments on commit ec2ef2a

Please sign in to comment.