Skip to content

Commit 119d849

Browse files
phpstan-botclaude
andcommitted
Skip extension for non-native reflection classes instead of removing declaring class check entirely
The previous approach (removing the declaring class check entirely) caused the extension to fire during self-analysis where BetterReflection adapters override getAttributes(). This overrode BetterReflection's accurate return type with the native ReflectionAttribute type, which lacks getArgumentsExpressions(). Instead of checking declaring class name === className (which fails for union types because UnionTypeMethodReflection returns only the first member's declaring class), check that the declaring class is a native PHP class (no namespace separator). This correctly: - Fires for user code (declaring class is native ReflectionClass etc.) - Fires for union types (declaring class is first member's native class) - Skips BetterReflection adapters during self-analysis (namespaced classes) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 8ef891f commit 119d849

File tree

2 files changed

+4
-2
lines changed

2 files changed

+4
-2
lines changed

src/Reflection/ClassReflection.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1570,7 +1570,7 @@ private function findAttributeFlags(): ?int
15701570

15711571
$attributeClass = $this->reflectionProvider->getClass(Attribute::class);
15721572
$arguments = [];
1573-
foreach ($nativeAttributes[0]->getArgumentsExpressions() as $i => $expression) { // @phpstan-ignore method.notFound (method exists on BetterReflection's ReflectionAttribute adapter)
1573+
foreach ($nativeAttributes[0]->getArgumentsExpressions() as $i => $expression) {
15741574
if ($i === '') {
15751575
throw new ShouldNotHappenException();
15761576
}

src/Type/Php/ReflectionGetAttributesMethodReturnTypeExtension.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use PHPStan\Type\Type;
1515
use ReflectionAttribute;
1616
use function count;
17+
use function str_contains;
1718

1819
final class ReflectionGetAttributesMethodReturnTypeExtension implements DynamicMethodReturnTypeExtension
1920
{
@@ -32,7 +33,8 @@ public function getClass(): string
3233

3334
public function isMethodSupported(MethodReflection $methodReflection): bool
3435
{
35-
return $methodReflection->getName() === 'getAttributes';
36+
return $methodReflection->getName() === 'getAttributes'
37+
&& !str_contains($methodReflection->getDeclaringClass()->getName(), '\\');
3638
}
3739

3840
public function getTypeFromMethodCall(MethodReflection $methodReflection, MethodCall $methodCall, Scope $scope): ?Type

0 commit comments

Comments
 (0)