Skip to content

Commit e8e58db

Browse files
Disable purity check for non-final methods
1 parent 4c36cd9 commit e8e58db

File tree

5 files changed

+107
-23
lines changed

5 files changed

+107
-23
lines changed

src/Rules/Pure/FunctionPurityCheck.php

+5
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,11 @@ public function check(
9292
count($throwPoints) === 0
9393
&& count($impurePoints) === 0
9494
&& count($functionReflection->getAsserts()->getAll()) === 0
95+
&& (
96+
!$functionReflection instanceof ExtendedMethodReflection
97+
|| $functionReflection->isFinal()->yes()
98+
|| $functionReflection->getDeclaringClass()->isFinal()
99+
)
95100
) {
96101
$errors[] = RuleErrorBuilder::message(sprintf(
97102
'%s is marked as impure but does not have any side effects.',

tests/PHPStan/Rules/Pure/PureMethodRuleTest.php

+23
Original file line numberDiff line numberDiff line change
@@ -220,4 +220,27 @@ public function testBug12224(): void
220220
]);
221221
}
222222

223+
public function testBug12382(): void
224+
{
225+
$this->treatPhpDocTypesAsCertain = true;
226+
$this->analyse([__DIR__ . '/data/bug-12382.php'], [
227+
[
228+
'Method Bug12382\FinalHelloWorld1::dummy() is marked as impure but does not have any side effects.',
229+
25,
230+
],
231+
[
232+
'Method Bug12382\FinalHelloWorld2::dummy() is marked as impure but does not have any side effects.',
233+
33,
234+
],
235+
[
236+
'Method Bug12382\FinalHelloWorld3::dummy() is marked as impure but does not have any side effects.',
237+
42,
238+
],
239+
[
240+
'Method Bug12382\FinalHelloWorld4::dummy() is marked as impure but does not have any side effects.',
241+
53,
242+
],
243+
]);
244+
}
245+
223246
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace Bug12382;
4+
5+
class HelloWorld
6+
{
7+
/** @phpstan-impure */
8+
public function dummy() : self{
9+
return $this;
10+
}
11+
}
12+
13+
class Child extends HelloWorld{
14+
private int $prop = 1;
15+
16+
public function dummy() : HelloWorld{
17+
$this->prop++;
18+
return $this;
19+
}
20+
}
21+
22+
final class FinalHelloWorld1
23+
{
24+
/** @phpstan-impure */
25+
public function dummy() : self{
26+
return $this;
27+
}
28+
}
29+
30+
class FinalHelloWorld2
31+
{
32+
/** @phpstan-impure */
33+
final public function dummy() : self{
34+
return $this;
35+
}
36+
}
37+
38+
/** @final */
39+
class FinalHelloWorld3
40+
{
41+
/** @phpstan-impure */
42+
public function dummy() : self{
43+
return $this;
44+
}
45+
}
46+
47+
class FinalHelloWorld4
48+
{
49+
/**
50+
* @final
51+
* @phpstan-impure
52+
*/
53+
public function dummy() : self{
54+
return $this;
55+
}
56+
}

tests/PHPStan/Rules/Pure/data/pure-constructor.php

+3-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
namespace PureConstructor;
44

5-
class Foo
5+
final class Foo
66
{
77

88
private string $prop;
@@ -21,7 +21,7 @@ public function __construct(
2121

2222
}
2323

24-
class Bar
24+
final class Bar
2525
{
2626

2727
private string $prop;
@@ -37,7 +37,7 @@ public function __construct(
3737

3838
}
3939

40-
class AssignOtherThanThis
40+
final class AssignOtherThanThis
4141
{
4242
private int $i = 0;
4343

tests/PHPStan/Rules/Pure/data/pure-method.php

+20-20
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
namespace PureMethod;
44

5-
class Foo
5+
final class Foo
66
{
77

88
/**
@@ -92,7 +92,7 @@ public function doFoo5()
9292

9393
}
9494

95-
class PureConstructor
95+
final class PureConstructor
9696
{
9797

9898
/**
@@ -105,7 +105,7 @@ public function __construct()
105105

106106
}
107107

108-
class ImpureConstructor
108+
final class ImpureConstructor
109109
{
110110

111111
/**
@@ -118,7 +118,7 @@ public function __construct()
118118

119119
}
120120

121-
class PossiblyImpureConstructor
121+
final class PossiblyImpureConstructor
122122
{
123123

124124
public function __construct()
@@ -128,7 +128,7 @@ public function __construct()
128128

129129
}
130130

131-
class TestConstructors
131+
final class TestConstructors
132132
{
133133

134134
/**
@@ -144,7 +144,7 @@ public function doFoo(string $s)
144144

145145
}
146146

147-
class ActuallyPure
147+
final class ActuallyPure
148148
{
149149

150150
/**
@@ -175,7 +175,7 @@ public function impure(): int
175175

176176
}
177177

178-
class ExtendingClass extends ToBeExtended
178+
final class ExtendingClass extends ToBeExtended
179179
{
180180

181181
public function pure(): int
@@ -191,7 +191,7 @@ public function impure(): int
191191

192192
}
193193

194-
class ClassWithVoidMethods
194+
final class ClassWithVoidMethods
195195
{
196196

197197
public function voidFunctionThatThrows(): void
@@ -235,12 +235,12 @@ public function purePostGetAssign(array $post = [], array $get = []): int
235235

236236
}
237237

238-
class NoMagicMethods
238+
final class NoMagicMethods
239239
{
240240

241241
}
242242

243-
class PureMagicMethods
243+
final class PureMagicMethods
244244
{
245245

246246
/**
@@ -253,7 +253,7 @@ public function __toString(): string
253253

254254
}
255255

256-
class MaybePureMagicMethods
256+
final class MaybePureMagicMethods
257257
{
258258

259259
public function __toString(): string
@@ -263,7 +263,7 @@ public function __toString(): string
263263

264264
}
265265

266-
class ImpureMagicMethods
266+
final class ImpureMagicMethods
267267
{
268268

269269
/**
@@ -277,7 +277,7 @@ public function __toString(): string
277277

278278
}
279279

280-
class TestMagicMethods
280+
final class TestMagicMethods
281281
{
282282

283283
/**
@@ -298,12 +298,12 @@ public function doFoo(
298298

299299
}
300300

301-
class NoConstructor
301+
final class NoConstructor
302302
{
303303

304304
}
305305

306-
class TestNoConstructor
306+
final class TestNoConstructor
307307
{
308308

309309
/**
@@ -318,7 +318,7 @@ public function doFoo(): int
318318

319319
}
320320

321-
class MaybeCallableFromUnion
321+
final class MaybeCallableFromUnion
322322
{
323323

324324
/**
@@ -334,7 +334,7 @@ public function doFoo($p): int
334334

335335
}
336336

337-
class VoidMethods
337+
final class VoidMethods
338338
{
339339

340340
private function doFoo(): void
@@ -361,7 +361,7 @@ private function doBaz(): void
361361

362362
}
363363

364-
class AssertingImpureVoidMethod
364+
final class AssertingImpureVoidMethod
365365
{
366366

367367
/**
@@ -376,7 +376,7 @@ public function assertSth($value): void
376376

377377
}
378378

379-
class StaticMethodAccessingStaticProperty
379+
final class StaticMethodAccessingStaticProperty
380380
{
381381
/** @var int */
382382
public static $a = 0;
@@ -397,7 +397,7 @@ public static function getB(): int
397397
}
398398
}
399399

400-
class StaticMethodAssigningStaticProperty
400+
final class StaticMethodAssigningStaticProperty
401401
{
402402
/** @var int */
403403
public static $a = 0;

0 commit comments

Comments
 (0)