Skip to content

Commit c993754

Browse files
committed
Process called methods looking for initialized properties only when called from constructor
1 parent a9057b0 commit c993754

File tree

3 files changed

+28
-11
lines changed

3 files changed

+28
-11
lines changed

src/Analyser/NodeScopeResolver.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3188,6 +3188,10 @@ function (MutatingScope $scope) use ($stmt, $expr, $nodeCallback, $context, $sto
31883188
if (
31893189
$scope->isInClass()
31903190
&& $scope->getClassReflection()->getName() === $methodReflection->getDeclaringClass()->getName()
3191+
&& (
3192+
!$this->narrowMethodScopeFromConstructor
3193+
|| ($scope->getFunctionName() !== null && strtolower($scope->getFunctionName()) === '__construct')
3194+
)
31913195
/*&& (
31923196
// should not be allowed but in practice has to be
31933197
$scope->getClassReflection()->isFinal()

tests/PHPStan/Rules/Properties/UninitializedPropertyRuleTest.php

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use PHPStan\Rules\Rule;
88
use PHPStan\Testing\RuleTestCase;
99
use PHPUnit\Framework\Attributes\RequiresPhp;
10+
use function array_merge;
1011
use function strpos;
1112

1213
/**
@@ -78,9 +79,13 @@ public function isInitialized(PropertyReflection $property, string $propertyName
7879

7980
public static function getAdditionalConfigFiles(): array
8081
{
81-
return [
82-
__DIR__ . '/uninitialized-property-rule.neon',
83-
];
82+
return array_merge(
83+
parent::getAdditionalConfigFiles(),
84+
[
85+
__DIR__ . '/uninitialized-property-rule.neon',
86+
__DIR__ . '/../../../../src/Testing/narrowMethodScopeFromConstructor.neon',
87+
],
88+
);
8489
}
8590

8691
public function testRule(): void
@@ -153,28 +158,28 @@ public function testReadOnlyPhpDoc(): void
153158
public function testBug7219(): void
154159
{
155160
$this->analyse([__DIR__ . '/data/bug-7219.php'], [
156-
[
157-
'Class Bug7219\Foo has an uninitialized property $id. Give it default value or assign it in the constructor.',
158-
8,
159-
],
160161
[
161162
'Class Bug7219\Foo has an uninitialized property $email. Give it default value or assign it in the constructor.',
162163
15,
163164
],
165+
[
166+
'Class Bug7219\Foo has an uninitialized property $id. Give it default value or assign it in the constructor.',
167+
8,
168+
],
164169
]);
165170
}
166171

167172
public function testAdditionalConstructorsExtension(): void
168173
{
169174
$this->analyse([__DIR__ . '/data/uninitialized-property-additional-constructors.php'], [
170-
[
171-
'Class TestInitializedProperty\TestAdditionalConstructor has an uninitialized property $one. Give it default value or assign it in the constructor.',
172-
07,
173-
],
174175
[
175176
'Class TestInitializedProperty\TestAdditionalConstructor has an uninitialized property $three. Give it default value or assign it in the constructor.',
176177
11,
177178
],
179+
[
180+
'Class TestInitializedProperty\TestAdditionalConstructor has an uninitialized property $one. Give it default value or assign it in the constructor.',
181+
07,
182+
],
178183
]);
179184
}
180185

tests/PHPStan/Rules/Properties/data/uninitialized-property-additional-constructors.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,21 @@ class TestAdditionalConstructor
1010

1111
protected int $three;
1212

13+
protected int $four;
14+
1315
public function setTwo(int $value): void
1416
{
1517
$this->two = $value;
18+
$this->setFour();
1619
}
1720

1821
public function setThree(int $value): void
1922
{
2023
$this->three = $value;
2124
}
25+
26+
public function setFour(): void
27+
{
28+
$this->four = 1;
29+
}
2230
}

0 commit comments

Comments
 (0)