Skip to content

Commit d2e2fa5

Browse files
Void
1 parent 7b88911 commit d2e2fa5

File tree

4 files changed

+88
-22
lines changed

4 files changed

+88
-22
lines changed

src/Analyser/NodeScopeResolver.php

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6996,7 +6996,15 @@ public function getPhpDocs(Scope $scope, Node\FunctionLike|Node\Stmt\Property $n
69966996
if ($isPure === null && $scope->isInClass()) {
69976997
$classResolvedPhpDoc = $scope->getClassReflection()->getResolvedPhpDoc();
69986998
if ($classResolvedPhpDoc !== null && $classResolvedPhpDoc->areAllMethodsPure()) {
6999-
$isPure = true;
6999+
if (
7000+
strtolower($functionName ?? '') === '__construct'
7001+
|| (
7002+
($phpDocReturnType === null || !$phpDocReturnType->isVoid()->yes())
7003+
&& !$scope->getFunctionType($node->getReturnType(), false, false)->isVoid()->yes()
7004+
)
7005+
) {
7006+
$isPure = true;
7007+
}
70007008
} elseif ($classResolvedPhpDoc !== null && $classResolvedPhpDoc->areAllMethodsImpure()) {
70017009
$isPure = false;
70027010
}

src/Reflection/Php/PhpClassReflectionExtension.php

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -897,7 +897,15 @@ public function createUserlandMethodReflection(ClassReflection $fileDeclaringCla
897897
if ($isPure === null) {
898898
$classResolvedPhpDoc = $phpDocBlockClassReflection->getResolvedPhpDoc();
899899
if ($classResolvedPhpDoc !== null && $classResolvedPhpDoc->areAllMethodsPure()) {
900-
$isPure = true;
900+
if (
901+
strtolower($methodReflection->getName()) === '__construct'
902+
|| (
903+
($phpDocReturnType === null || !$phpDocReturnType->isVoid()->yes())
904+
&& !$nativeReturnType->isVoid()->yes()
905+
)
906+
) {
907+
$isPure = true;
908+
}
901909
} elseif ($classResolvedPhpDoc !== null && $classResolvedPhpDoc->areAllMethodsImpure()) {
902910
$isPure = false;
903911
}

tests/PHPStan/Rules/Pure/PureMethodRuleTest.php

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -221,44 +221,52 @@ public function testAllMethodsArePure(): void
221221
$this->treatPhpDocTypesAsCertain = true;
222222
$this->analyse([__DIR__ . '/data/all-methods-are-pure.php'], [
223223
[
224-
'Method AllMethodsArePure\Foo::test() is marked as pure but returns void.',
225-
10,
224+
'Method AllMethodsArePure\Foo::pureVoid() is marked as pure but returns void.',
225+
30,
226226
],
227227
[
228-
'Method AllMethodsArePure\Foo::pure() is marked as pure but returns void.',
229-
17,
228+
'Method AllMethodsArePure\Foo::impure() is marked as impure but does not have any side effects.',
229+
37,
230230
],
231231
[
232-
'Method AllMethodsArePure\Foo::impure() is marked as impure but does not have any side effects.',
233-
24,
232+
'Method AllMethodsArePure\Foo::impureVoid() is marked as impure but does not have any side effects.',
233+
45,
234234
],
235235
[
236236
'Method AllMethodsArePure\Bar::test() is marked as impure but does not have any side effects.',
237-
34,
237+
55,
238238
],
239239
[
240-
'Method AllMethodsArePure\Bar::pure() is marked as pure but returns void.',
241-
41,
240+
'Method AllMethodsArePure\Bar::testVoid() is marked as impure but does not have any side effects.',
241+
60,
242+
],
243+
[
244+
'Method AllMethodsArePure\Bar::pureVoid() is marked as pure but returns void.',
245+
75,
242246
],
243247
[
244248
'Method AllMethodsArePure\Bar::impure() is marked as impure but does not have any side effects.',
245-
48,
249+
82,
250+
],
251+
[
252+
'Method AllMethodsArePure\Bar::impureVoid() is marked as impure but does not have any side effects.',
253+
90,
246254
],
247255
[
248256
'Impure call to method AllMethodsArePure\Test::impure() in pure method AllMethodsArePure\SideEffectPure::nothingWithImpure().',
249-
78,
257+
120,
250258
],
251259
[
252260
'Method AllMethodsArePure\SideEffectPure::impureWithPure() is marked as impure but does not have any side effects.',
253-
88,
261+
130,
254262
],
255263
[
256264
'Method AllMethodsArePure\SideEffectImpure::nothingWithPure() is marked as impure but does not have any side effects.',
257-
101,
265+
143,
258266
],
259267
[
260268
'Impure call to method AllMethodsArePure\Test::impure() in pure method AllMethodsArePure\SideEffectImpure::pureWithImpure().',
261-
106,
269+
148,
262270
],
263271
]);
264272
}

tests/PHPStan/Rules/Pure/data/all-methods-are-pure.php

Lines changed: 48 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,42 @@
77
*/
88
final class Foo
99
{
10-
function test(): void
10+
function test(): int
1111
{
12+
return 1;
13+
}
14+
15+
function testVoid(): void
16+
{
17+
}
18+
19+
/**
20+
* @phpstan-pure
21+
*/
22+
function pure(): int
23+
{
24+
return 1;
1225
}
1326

1427
/**
1528
* @phpstan-pure
1629
*/
17-
function pure(): void
30+
function pureVoid(): void
1831
{
1932
}
2033

2134
/**
2235
* @phpstan-impure
2336
*/
24-
function impure(): void
37+
function impure(): int
38+
{
39+
return 1;
40+
}
41+
42+
/**
43+
* @phpstan-impure
44+
*/
45+
function impureVoid(): void
2546
{
2647
}
2748
}
@@ -31,21 +52,42 @@ function impure(): void
3152
*/
3253
final class Bar
3354
{
34-
function test(): void
55+
function test(): int
3556
{
57+
return 1;
58+
}
59+
60+
function testVoid(): void
61+
{
62+
}
63+
64+
/**
65+
* @phpstan-pure
66+
*/
67+
function pure(): int
68+
{
69+
return 1;
3670
}
3771

3872
/**
3973
* @phpstan-pure
4074
*/
41-
function pure(): void
75+
function pureVoid(): void
4276
{
4377
}
4478

4579
/**
4680
* @phpstan-impure
4781
*/
48-
function impure(): void
82+
function impure(): int
83+
{
84+
return 1;
85+
}
86+
87+
/**
88+
* @phpstan-impure
89+
*/
90+
function impureVoid(): void
4991
{
5092
}
5193
}

0 commit comments

Comments
 (0)