Skip to content

Commit f827021

Browse files
committed
Improve InstantiationRule
1 parent be3c27a commit f827021

File tree

3 files changed

+44
-1
lines changed

3 files changed

+44
-1
lines changed

src/Rules/Classes/InstantiationRule.php

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
use PHPStan\DependencyInjection\RegisteredRule;
1111
use PHPStan\Internal\SprintfHelper;
1212
use PHPStan\Reflection\ClassReflection;
13+
use PHPStan\Reflection\Dummy\DummyConstructorReflection;
14+
use PHPStan\Reflection\ExtendedMethodReflection;
1315
use PHPStan\Reflection\ParametersAcceptorSelector;
1416
use PHPStan\Reflection\Php\PhpMethodReflection;
1517
use PHPStan\Reflection\ReflectionProvider;
@@ -94,7 +96,7 @@ private function checkClassName(string $class, bool $isName, Node $node, Scope $
9496
&& $constructor instanceof PhpMethodReflection
9597
&& !$constructor->isFinal()->yes()
9698
&& !$constructor->getPrototype()->isAbstract()
97-
&& !$constructor->getDeclaringClass()->hasConsistentConstructor()
99+
&& $this->findConsistentParentConstructor($classReflection) === null
98100
) {
99101
return [];
100102
}
@@ -310,4 +312,22 @@ private function getClassNames(Node $node, Scope $scope): array
310312
);
311313
}
312314

315+
private function findConsistentParentConstructor(ClassReflection $classReflection): ?ExtendedMethodReflection
316+
{
317+
if ($classReflection->hasConsistentConstructor()) {
318+
if ($classReflection->hasConstructor()) {
319+
return $classReflection->getConstructor();
320+
}
321+
322+
return new DummyConstructorReflection($classReflection);
323+
}
324+
325+
$parent = $classReflection->getParentClass();
326+
if ($parent === null) {
327+
return null;
328+
}
329+
330+
return $this->findConsistentParentConstructor($parent);
331+
}
332+
313333
}

tests/PHPStan/Rules/Classes/InstantiationRuleTest.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -569,6 +569,10 @@ public function testNewStaticWithConsistentConstructor(): void
569569
'Parameter #1 $i of class InstantiationNewStaticConsistentConstructor\Foo constructor expects int, string given.',
570570
18,
571571
],
572+
[
573+
'Parameter #1 $value of class InstantiationNewStaticConsistentConstructor\ChildClass3 constructor expects string, int given.',
574+
38,
575+
],
572576
]);
573577
}
574578

tests/PHPStan/Rules/Classes/data/instantiation-new-static-consistent-constructor.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,22 @@ public function doFoo(): void
1919
}
2020

2121
}
22+
23+
class BaseClass {
24+
public function __construct(protected string $value) {
25+
}
26+
}
27+
28+
/**
29+
* @phpstan-consistent-constructor
30+
*/
31+
class ChildClass2 extends BaseClass
32+
{
33+
34+
}
35+
36+
class ChildClass3 extends ChildClass2 {
37+
public function fromInt(int $value): static {
38+
return new static($value);
39+
}
40+
}

0 commit comments

Comments
 (0)