Skip to content

Commit 7a6a575

Browse files
authored
Correctly retrieve hasSideEffects metadata for inherited methods
1 parent 599ac2b commit 7a6a575

File tree

4 files changed

+36
-4
lines changed

4 files changed

+36
-4
lines changed

src/Reflection/Php/PhpClassReflectionExtension.php

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -839,7 +839,17 @@ public function createUserlandMethodReflection(ClassReflection $fileDeclaringCla
839839
}
840840
$isInternal = $resolvedPhpDoc->isInternal();
841841
$isFinal = $resolvedPhpDoc->isFinal();
842-
$isPure = $resolvedPhpDoc->isPure();
842+
$isPure = null;
843+
foreach ($actualDeclaringClass->getAncestors() as $className => $ancestor) {
844+
if ($this->signatureMapProvider->hasMethodMetadata($className, $methodReflection->getName())) {
845+
$hasSideEffects = $this->signatureMapProvider->getMethodMetadata($className, $methodReflection->getName())['hasSideEffects'];
846+
$isPure = !$hasSideEffects;
847+
848+
break;
849+
}
850+
}
851+
852+
$isPure ??= $resolvedPhpDoc->isPure();
843853
$asserts = Assertions::createFromResolvedPhpDocBlock($resolvedPhpDoc);
844854
$acceptsNamedArguments = $resolvedPhpDoc->acceptsNamedArguments();
845855
$selfOutType = $resolvedPhpDoc->getSelfOutTag() !== null ? $resolvedPhpDoc->getSelfOutTag()->getType() : null;

src/Reflection/SignatureMap/Php8SignatureMapProvider.php

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,6 @@ public function __construct(
6464
public function hasMethodSignature(string $className, string $methodName): bool
6565
{
6666
$lowerClassName = strtolower($className);
67-
if ($lowerClassName === 'backedenum') {
68-
return false;
69-
}
7067
if (!array_key_exists($lowerClassName, $this->map->classes)) {
7168
return $this->functionSignatureMapProvider->hasMethodSignature($className, $methodName);
7269
}

tests/PHPStan/Rules/Pure/PureFunctionRuleTest.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,4 +174,10 @@ public function testBug12224(): void
174174
]);
175175
}
176176

177+
#[RequiresPhp('>= 8.1')]
178+
public function testBug13201(): void
179+
{
180+
$this->analyse([__DIR__ . '/data/bug-13201.php'], []);
181+
}
182+
177183
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php // lint >= 8.1
2+
3+
namespace PHPStan\Rules\Pure\data\Bug13201;
4+
5+
enum Foo: string
6+
{
7+
8+
case Bar = 'bar';
9+
case Unknown = 'unknown';
10+
11+
}
12+
13+
/**
14+
* @pure
15+
*/
16+
function createWithFallback(string $type): Foo
17+
{
18+
return Foo::tryFrom($type) ?? Foo::Unknown;
19+
}

0 commit comments

Comments
 (0)