Skip to content

Commit ec2ef2a

Browse files
committed
CallStaticMethodsRule - fix case with non-object class-string
1 parent 396ee25 commit ec2ef2a

File tree

3 files changed

+65
-0
lines changed

3 files changed

+65
-0
lines changed

src/Rules/Methods/CallStaticMethodsRule.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
use PHPStan\Type\ErrorType;
2020
use PHPStan\Type\Generic\GenericClassStringType;
2121
use PHPStan\Type\ObjectType;
22+
use PHPStan\Type\ObjectWithoutClassType;
2223
use PHPStan\Type\StringType;
2324
use PHPStan\Type\ThisType;
2425
use PHPStan\Type\Type;
@@ -170,6 +171,9 @@ static function (Type $type) use ($methodName): bool {
170171

171172
if ($classType instanceof GenericClassStringType) {
172173
$classType = $classType->getGenericType();
174+
if (!(new ObjectWithoutClassType())->isSuperTypeOf($classType)->yes()) {
175+
return [];
176+
}
173177
} elseif ((new StringType())->isSuperTypeOf($classType)->yes()) {
174178
return [];
175179
}

tests/PHPStan/Rules/Methods/CallStaticMethodsRuleTest.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,4 +403,19 @@ public function testBug577(): void
403403
$this->analyse([__DIR__ . '/data/bug-577.php'], []);
404404
}
405405

406+
public function testBug4550(): void
407+
{
408+
$this->checkThisOnly = false;
409+
$this->analyse([__DIR__ . '/data/bug-4550.php'], [
410+
[
411+
'Parameter #1 $class of static method Bug4550\Test::valuesOf() expects class-string<Person>, string given.',
412+
34,
413+
],
414+
[
415+
'Parameter #1 $class of static method Bug4550\Test::valuesOf() expects class-string<Person>, string given.',
416+
44,
417+
],
418+
]);
419+
}
420+
406421
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<?php
2+
3+
namespace Bug4550;
4+
5+
class Test
6+
{
7+
/**
8+
* @template T
9+
* @param class-string<T> $class
10+
*/
11+
public static function valuesOf(string $class): void
12+
{
13+
(new $class())->values();
14+
assert(method_exists($class, 'values'));
15+
$class::values();
16+
}
17+
18+
/**
19+
* @template T
20+
* @param class-string<T> $class
21+
*/
22+
public static function doBar(string $class): void
23+
{
24+
(new $class())->values();
25+
$class::values();
26+
}
27+
28+
/**
29+
* @param class-string<self> $s
30+
*/
31+
public function doBaz(string $s): void
32+
{
33+
$s::valuesOf(\stdClass::class);
34+
$s::valuesOf('Person');
35+
}
36+
37+
/**
38+
* @template T of self
39+
* @param class-string<T> $s
40+
*/
41+
public function doLorem(string $s): void
42+
{
43+
$s::valuesOf(\stdClass::class);
44+
$s::valuesOf('Person');
45+
}
46+
}

0 commit comments

Comments
 (0)