Skip to content

Commit 87b0706

Browse files
vhenzlondrejmirtes
authored andcommitted
Add missing getAttributes for all supported reflectors
1 parent 0364387 commit 87b0706

8 files changed

+139
-27
lines changed

conf/config.neon

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1494,10 +1494,41 @@ services:
14941494
- phpstan.broker.dynamicStaticMethodReturnTypeExtension
14951495

14961496
-
1497-
class: PHPStan\Type\Php\ReflectionClassGetAttributesMethodReturnTypeExtension
1497+
class: PHPStan\Type\Php\ReflectionGetAttributesMethodReturnTypeExtension
1498+
arguments:
1499+
className: ReflectionClass
1500+
tags:
1501+
- phpstan.broker.dynamicMethodReturnTypeExtension
1502+
1503+
-
1504+
class: PHPStan\Type\Php\ReflectionGetAttributesMethodReturnTypeExtension
1505+
arguments:
1506+
className: ReflectionClassConstant
1507+
tags:
1508+
- phpstan.broker.dynamicMethodReturnTypeExtension
1509+
1510+
-
1511+
class: PHPStan\Type\Php\ReflectionGetAttributesMethodReturnTypeExtension
1512+
arguments:
1513+
className: ReflectionFunctionAbstract
14981514
tags:
14991515
- phpstan.broker.dynamicMethodReturnTypeExtension
15001516

1517+
-
1518+
class: PHPStan\Type\Php\ReflectionGetAttributesMethodReturnTypeExtension
1519+
arguments:
1520+
className: ReflectionParameter
1521+
tags:
1522+
- phpstan.broker.dynamicMethodReturnTypeExtension
1523+
1524+
-
1525+
class: PHPStan\Type\Php\ReflectionGetAttributesMethodReturnTypeExtension
1526+
arguments:
1527+
className: ReflectionProperty
1528+
tags:
1529+
- phpstan.broker.dynamicMethodReturnTypeExtension
1530+
1531+
15011532
exceptionTypeResolver:
15021533
class: PHPStan\Rules\Exceptions\ExceptionTypeResolver
15031534
factory: @PHPStan\Rules\Exceptions\DefaultExceptionTypeResolver

conf/config.stubFiles.neon

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,15 @@ parameters:
22
stubFiles:
33
- ../stubs/ReflectionAttribute.stub
44
- ../stubs/ReflectionClass.stub
5+
- ../stubs/ReflectionClassConstant.stub
6+
- ../stubs/ReflectionFunctionAbstract.stub
7+
- ../stubs/ReflectionParameter.stub
8+
- ../stubs/ReflectionProperty.stub
59
- ../stubs/iterable.stub
610
- ../stubs/ArrayObject.stub
711
- ../stubs/WeakReference.stub
812
- ../stubs/ext-ds.stub
913
- ../stubs/PDOStatement.stub
10-
- ../stubs/ReflectionFunctionAbstract.stub
1114
- ../stubs/date.stub
1215
- ../stubs/zip.stub
1316
- ../stubs/dom.stub

src/Type/Php/ReflectionClassGetAttributesMethodReturnTypeExtension.php renamed to src/Type/Php/ReflectionGetAttributesMethodReturnTypeExtension.php

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,23 @@
1515
use PHPStan\Type\ObjectType;
1616
use PHPStan\Type\Type;
1717

18-
class ReflectionClassGetAttributesMethodReturnTypeExtension implements DynamicMethodReturnTypeExtension
18+
class ReflectionGetAttributesMethodReturnTypeExtension implements DynamicMethodReturnTypeExtension
1919
{
2020

21+
/** @var class-string */
22+
private string $className;
23+
24+
/**
25+
* @param class-string $className One of reflection classes: https://www.php.net/manual/en/book.reflection.php
26+
*/
27+
public function __construct(string $className)
28+
{
29+
$this->className = $className;
30+
}
31+
2132
public function getClass(): string
2233
{
23-
return \ReflectionClass::class;
34+
return $this->className;
2435
}
2536

2637
public function isMethodSupported(MethodReflection $methodReflection): bool

stubs/ReflectionClassConstant.stub

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
class ReflectionClassConstant
4+
{
5+
/**
6+
* @return array<ReflectionAttribute<object>>
7+
*/
8+
public function getAttributes(?string $name = null, int $flags = 0)
9+
{
10+
}
11+
}

stubs/ReflectionFunctionAbstract.stub

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,10 @@ abstract class ReflectionFunctionAbstract
88
*/
99
public function getFileName () {}
1010

11+
/**
12+
* @return array<ReflectionAttribute<object>>
13+
*/
14+
public function getAttributes(?string $name = null, int $flags = 0)
15+
{
16+
}
1117
}

stubs/ReflectionParameter.stub

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
class ReflectionParameter
4+
{
5+
/**
6+
* @return array<ReflectionAttribute<object>>
7+
*/
8+
public function getAttributes(?string $name = null, int $flags = 0)
9+
{
10+
}
11+
}

stubs/ReflectionProperty.stub

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
class ReflectionProperty
4+
{
5+
/**
6+
* @return array<ReflectionAttribute<object>>
7+
*/
8+
public function getAttributes(?string $name = null, int $flags = 0)
9+
{
10+
}
11+
}

tests/PHPStan/Analyser/data/reflectionclass-issue-5511-php8.php

Lines changed: 51 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -9,35 +9,63 @@ class Abc
99
{
1010
}
1111

12-
#[Abc]
13-
class X
14-
{
15-
}
16-
1712
/**
1813
* @param string $str
1914
* @param class-string $className
2015
* @param class-string<Abc> $genericClassName
2116
*/
22-
function testGetAttributes(string $str, string $className, string $genericClassName): void
17+
function testGetAttributes(
18+
\ReflectionClass $reflectionClass,
19+
\ReflectionMethod $reflectionMethod,
20+
\ReflectionParameter $reflectionParameter,
21+
\ReflectionProperty $reflectionProperty,
22+
\ReflectionClassConstant $reflectionClassConstant,
23+
\ReflectionFunction $reflectionFunction,
24+
string $str,
25+
string $className,
26+
string $genericClassName
27+
): void
2328
{
24-
$class = new \ReflectionClass(X::class);
25-
26-
$attrsAll = $class->getAttributes();
27-
$attrsAbc1 = $class->getAttributes(Abc::class);
28-
$attrsAbc2 = $class->getAttributes(Abc::class, \ReflectionAttribute::IS_INSTANCEOF);
29-
$attrsGCN = $class->getAttributes($genericClassName);
30-
$attrsCN = $class->getAttributes($className);
31-
$attrsStr = $class->getAttributes($str);
32-
$attrsNonsense = $class->getAttributes("some random string");
33-
34-
assertType('array<ReflectionAttribute<object>>', $attrsAll);
35-
assertType('array<ReflectionAttribute<Issue5511\Abc>>', $attrsAbc1);
36-
assertType('array<ReflectionAttribute<Issue5511\Abc>>', $attrsAbc2);
37-
assertType('array<ReflectionAttribute<Issue5511\Abc>>', $attrsGCN);
38-
assertType('array<ReflectionAttribute<object>>', $attrsCN);
39-
assertType('array<ReflectionAttribute<object>>', $attrsStr);
40-
assertType('array<ReflectionAttribute<some random string>>', $attrsNonsense);
29+
$classAll = $reflectionClass->getAttributes();
30+
$classAbc1 = $reflectionClass->getAttributes(Abc::class);
31+
$classAbc2 = $reflectionClass->getAttributes(Abc::class, \ReflectionAttribute::IS_INSTANCEOF);
32+
$classGCN = $reflectionClass->getAttributes($genericClassName);
33+
$classCN = $reflectionClass->getAttributes($className);
34+
$classStr = $reflectionClass->getAttributes($str);
35+
$classNonsense = $reflectionClass->getAttributes("some random string");
36+
37+
assertType('array<ReflectionAttribute<object>>', $classAll);
38+
assertType('array<ReflectionAttribute<Issue5511\Abc>>', $classAbc1);
39+
assertType('array<ReflectionAttribute<Issue5511\Abc>>', $classAbc2);
40+
assertType('array<ReflectionAttribute<Issue5511\Abc>>', $classGCN);
41+
assertType('array<ReflectionAttribute<object>>', $classCN);
42+
assertType('array<ReflectionAttribute<object>>', $classStr);
43+
assertType('array<ReflectionAttribute<some random string>>', $classNonsense);
44+
45+
$methodAll = $reflectionMethod->getAttributes();
46+
$methodAbc = $reflectionMethod->getAttributes(Abc::class);
47+
assertType('array<ReflectionAttribute<object>>', $methodAll);
48+
assertType('array<ReflectionAttribute<Issue5511\Abc>>', $methodAbc);
49+
50+
$paramAll = $reflectionParameter->getAttributes();
51+
$paramAbc = $reflectionParameter->getAttributes(Abc::class);
52+
assertType('array<ReflectionAttribute<object>>', $paramAll);
53+
assertType('array<ReflectionAttribute<Issue5511\Abc>>', $paramAbc);
54+
55+
$propAll = $reflectionProperty->getAttributes();
56+
$propAbc = $reflectionProperty->getAttributes(Abc::class);
57+
assertType('array<ReflectionAttribute<object>>', $propAll);
58+
assertType('array<ReflectionAttribute<Issue5511\Abc>>', $propAbc);
59+
60+
$constAll = $reflectionClassConstant->getAttributes();
61+
$constAbc = $reflectionClassConstant->getAttributes(Abc::class);
62+
assertType('array<ReflectionAttribute<object>>', $constAll);
63+
assertType('array<ReflectionAttribute<Issue5511\Abc>>', $constAbc);
64+
65+
$funcAll = $reflectionFunction->getAttributes();
66+
$funcAbc = $reflectionFunction->getAttributes(Abc::class);
67+
assertType('array<ReflectionAttribute<object>>', $funcAll);
68+
assertType('array<ReflectionAttribute<Issue5511\Abc>>', $funcAbc);
4169
}
4270

4371
/**

0 commit comments

Comments
 (0)