Skip to content

Commit 1050592

Browse files
committed
Merge remote-tracking branch 'origin/1.12.x' into 2.1.x
2 parents 1f64c15 + 8b27943 commit 1050592

10 files changed

+53
-18
lines changed

src/Analyser/MutatingScope.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2953,6 +2953,7 @@ public function enterClassMethod(
29532953
array $parameterOutTypes = [],
29542954
array $immediatelyInvokedCallableParameters = [],
29552955
array $phpDocClosureThisTypeParameters = [],
2956+
bool $isConstructor = false,
29562957
): self
29572958
{
29582959
if (!$this->isInClass()) {
@@ -2984,6 +2985,7 @@ public function enterClassMethod(
29842985
array_map(fn (Type $type): Type => $this->transformStaticType(TemplateTypeHelper::toArgument($type)), $parameterOutTypes),
29852986
$immediatelyInvokedCallableParameters,
29862987
array_map(fn (Type $type): Type => $this->transformStaticType(TemplateTypeHelper::toArgument($type)), $phpDocClosureThisTypeParameters),
2988+
$isConstructor,
29872989
),
29882990
!$classMethod->isStatic(),
29892991
);
@@ -3068,6 +3070,7 @@ public function enterPropertyHook(
30683070
[],
30693071
[],
30703072
[],
3073+
false,
30713074
),
30723075
true,
30733076
);

src/Analyser/NodeScopeResolver.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -648,6 +648,9 @@ private function processStmtNode(
648648
[$isDeprecated, $deprecatedDescription] = $this->getDeprecatedAttribute($scope, $stmt);
649649
}
650650

651+
$isFromTrait = $stmt->getAttribute('originalTraitMethodName') === '__construct';
652+
$isConstructor = $isFromTrait || $stmt->name->toLowerString() === '__construct';
653+
651654
$methodScope = $scope->enterClassMethod(
652655
$stmt,
653656
$templateTypeMap,
@@ -666,6 +669,7 @@ private function processStmtNode(
666669
$phpDocParameterOutTypes,
667670
$phpDocImmediatelyInvokedCallableParameters,
668671
$phpDocClosureThisTypeParameters,
672+
$isConstructor,
669673
);
670674

671675
if (!$scope->isInClass()) {
@@ -674,8 +678,7 @@ private function processStmtNode(
674678

675679
$classReflection = $scope->getClassReflection();
676680

677-
$isFromTrait = $stmt->getAttribute('originalTraitMethodName') === '__construct';
678-
if ($isFromTrait || $stmt->name->toLowerString() === '__construct') {
681+
if ($isConstructor) {
679682
foreach ($stmt->params as $param) {
680683
if ($param->flags === 0 && $param->hooks === []) {
681684
continue;

src/Reflection/Php/PhpMethodFromParserNodeReflection.php

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ public function __construct(
6262
array $parameterOutTypes,
6363
array $immediatelyInvokedCallableParameters,
6464
array $phpDocClosureThisTypeParameters,
65+
private bool $isConstructor,
6566
)
6667
{
6768
if ($this->classMethod instanceof Node\PropertyHook) {
@@ -73,7 +74,10 @@ public function __construct(
7374
}
7475

7576
$name = strtolower($classMethod->name->name);
76-
if (in_array($name, ['__construct', '__destruct', '__unset', '__wakeup', '__clone'], true)) {
77+
if ($this->isConstructor) {
78+
$realReturnType = new VoidType();
79+
}
80+
if (in_array($name, ['__destruct', '__unset', '__wakeup', '__clone'], true)) {
7781
$realReturnType = new VoidType();
7882
}
7983
if ($name === '__tostring') {
@@ -265,6 +269,11 @@ public function isAbstract(): TrinaryLogic
265269
return TrinaryLogic::createFromBoolean($method->isAbstract());
266270
}
267271

272+
public function isConstructor(): bool
273+
{
274+
return $this->isConstructor;
275+
}
276+
268277
public function hasSideEffects(): TrinaryLogic
269278
{
270279
if (

src/Rules/DeadCode/ConstructorWithoutImpurePointsCollector.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
use PHPStan\Collectors\Collector;
88
use PHPStan\Node\MethodReturnStatementsNode;
99
use function count;
10-
use function strtolower;
1110

1211
/**
1312
* @implements Collector<MethodReturnStatementsNode, string>
@@ -23,7 +22,7 @@ public function getNodeType(): string
2322
public function processNode(Node $node, Scope $scope)
2423
{
2524
$method = $node->getMethodReflection();
26-
if (strtolower($method->getName()) !== '__construct') {
25+
if (!$method->isConstructor()) {
2726
return null;
2827
}
2928

src/Rules/DeadCode/MethodWithoutImpurePointsCollector.php

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,7 @@ public function processNode(Node $node, Scope $scope)
4949
return null;
5050
}
5151

52-
$declaringClass = $method->getDeclaringClass();
53-
if (
54-
$declaringClass->hasConstructor()
55-
&& $declaringClass->getConstructor()->getName() === $method->getName()
56-
) {
52+
if ($method->isConstructor()) {
5753
return null;
5854
}
5955

src/Rules/Pure/FunctionPurityCheck.php

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,18 +40,11 @@ public function check(
4040
array $impurePoints,
4141
array $throwPoints,
4242
array $statements,
43+
bool $isConstructor,
4344
): array
4445
{
4546
$errors = [];
4647
$isPure = $functionReflection->isPure();
47-
$isConstructor = false;
48-
if (
49-
$functionReflection instanceof ExtendedMethodReflection
50-
&& $functionReflection->getDeclaringClass()->hasConstructor()
51-
&& $functionReflection->getDeclaringClass()->getConstructor()->getName() === $functionReflection->getName()
52-
) {
53-
$isConstructor = true;
54-
}
5548

5649
if ($isPure->yes()) {
5750
foreach ($parameters as $parameter) {

src/Rules/Pure/PureFunctionRule.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ public function processNode(Node $node, Scope $scope): array
3636
$node->getImpurePoints(),
3737
$node->getStatementResult()->getThrowPoints(),
3838
$node->getStatements(),
39+
false,
3940
);
4041
}
4142

src/Rules/Pure/PureMethodRule.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ public function processNode(Node $node, Scope $scope): array
3636
$node->getImpurePoints(),
3737
$node->getStatementResult()->getThrowPoints(),
3838
$node->getStatements(),
39+
$method->isConstructor(),
3940
);
4041
}
4142

tests/PHPStan/Rules/DeadCode/CallToMethodStatementWithoutImpurePointsRuleTest.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,14 @@ public function testBug11011(): void
7272
]);
7373
}
7474

75+
public function testBug12379(): void
76+
{
77+
if (PHP_VERSION_ID < 80000) {
78+
$this->markTestSkipped('Test requires PHP 8.1.');
79+
}
80+
$this->analyse([__DIR__ . '/data/bug-12379.php'], []);
81+
}
82+
7583
protected function getCollectors(): array
7684
{
7785
return [
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php // lint >= 8.1
2+
3+
namespace Bug12379;
4+
5+
class HelloWorld
6+
{
7+
use myTrait{
8+
myTrait::__construct as private __myTraitConstruct;
9+
}
10+
11+
public function __construct(
12+
int $entityManager
13+
){
14+
$this->__myTraitConstruct($entityManager);
15+
}
16+
}
17+
18+
trait myTrait{
19+
public function __construct(
20+
private readonly int $entityManager
21+
){}
22+
}

0 commit comments

Comments
 (0)