Skip to content

Commit 8e2df34

Browse files
committed
Use the new getAttributes() API to get attributes
The API is available starting with PHPStan 2.1.3 https://github.com/phpstan/phpstan/releases/tag/2.1.3 so I'll need to decide when to merge this and when or how to remove support for earlier versions. Also require nikic/php-parser 5.0+ because first PHPStan 2.x requires and uses it and second, Function_::namespacedName is not available in earlier versions.
1 parent 4007202 commit 8e2df34

File tree

6 files changed

+45
-52
lines changed

6 files changed

+45
-52
lines changed

composer.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,11 @@
2222
},
2323
"require": {
2424
"php": "^7.4 || ^8.0",
25-
"phpstan/phpstan": "^1.12.6 || ^2.0"
25+
"phpstan/phpstan": "^2.1.3"
2626
},
2727
"require-dev": {
2828
"nette/neon": "^3.3.1",
29-
"nikic/php-parser": "^4.13.2 || ^5.0",
29+
"nikic/php-parser": "^5.0",
3030
"phpunit/phpunit": "^8.5.14 || ^10.1 || ^11.0 || ^12.0",
3131
"php-parallel-lint/php-parallel-lint": "^1.2",
3232
"php-parallel-lint/php-console-highlighter": "^1.0",

src/Allowed/Allowed.php

Lines changed: 20 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,10 @@
88
use PhpParser\Node\Stmt\ClassMethod;
99
use PhpParser\Node\Stmt\Function_;
1010
use PHPStan\Analyser\Scope;
11-
use PHPStan\BetterReflection\Reflection\Adapter\FakeReflectionAttribute;
12-
use PHPStan\BetterReflection\Reflection\Adapter\ReflectionAttribute;
13-
use PHPStan\BetterReflection\Reflection\ReflectionAttribute as BetterReflectionAttribute;
14-
use PHPStan\BetterReflection\Reflector\Reflector;
11+
use PHPStan\Reflection\AttributeReflection;
1512
use PHPStan\Reflection\FunctionReflection;
1613
use PHPStan\Reflection\MethodReflection;
14+
use PHPStan\Reflection\ReflectionProvider;
1715
use PHPStan\Type\Type;
1816
use PHPStan\Type\UnionType;
1917
use Spaze\PHPStan\Rules\Disallowed\Disallowed;
@@ -28,7 +26,7 @@ class Allowed
2826

2927
private Formatter $formatter;
3028

31-
private Reflector $reflector;
29+
private ReflectionProvider $reflectionProvider;
3230

3331
private Identifier $identifier;
3432

@@ -39,13 +37,13 @@ class Allowed
3937

4038
public function __construct(
4139
Formatter $formatter,
42-
Reflector $reflector,
40+
ReflectionProvider $reflectionProvider,
4341
Identifier $identifier,
4442
GetAttributesWhenInSignature $attributesWhenInSignature,
4543
AllowedPath $allowedPath
4644
) {
4745
$this->formatter = $formatter;
48-
$this->reflector = $reflector;
46+
$this->reflectionProvider = $reflectionProvider;
4947
$this->identifier = $identifier;
5048
$this->attributesWhenInSignature = $attributesWhenInSignature;
5149
$this->allowedPath = $allowedPath;
@@ -203,7 +201,7 @@ private function hasAllowedParamsInAllowed(Scope $scope, ?array $args, Disallowe
203201

204202

205203
/**
206-
* @param list<FakeReflectionAttribute|ReflectionAttribute|BetterReflectionAttribute> $attributes
204+
* @param list<AttributeReflection> $attributes
207205
* @param list<string> $allowConfig
208206
* @return bool
209207
*/
@@ -247,32 +245,29 @@ private function getArgType(array $args, Scope $scope, Param $param): ?Type
247245

248246
/**
249247
* @param Scope $scope
250-
* @return list<FakeReflectionAttribute>|list<ReflectionAttribute>
248+
* @return list<AttributeReflection>
251249
*/
252250
private function getAttributes(Scope $scope): array
253251
{
254-
return $scope->isInClass() ? $scope->getClassReflection()->getNativeReflection()->getAttributes() : [];
252+
return $scope->isInClass() ? $scope->getClassReflection()->getAttributes() : [];
255253
}
256254

257255

258256
/**
259257
* @param Node|null $node
260258
* @param Scope $scope
261-
* @return list<FakeReflectionAttribute|ReflectionAttribute|BetterReflectionAttribute>
259+
* @return list<AttributeReflection>
262260
*/
263261
private function getCallAttributes(?Node $node, Scope $scope): array
264262
{
265263
$function = $scope->getFunction();
266-
if ($function instanceof MethodReflection) {
267-
return $scope->isInClass() ? $scope->getClassReflection()->getNativeReflection()->getMethod($function->getName())->getAttributes() : [];
268-
} elseif ($function instanceof FunctionReflection) {
269-
return $this->reflector->reflectFunction($function->getName())->getAttributes();
270-
} elseif ($function === null) {
271-
if ($node instanceof ClassMethod && $scope->isInClass()) {
272-
return $scope->getClassReflection()->getNativeReflection()->getMethod($node->name->name)->getAttributes();
273-
} elseif ($node instanceof Function_) {
274-
return $this->reflector->reflectFunction($node->name->name)->getAttributes();
275-
}
264+
if ($function !== null) {
265+
return $function->getAttributes();
266+
} elseif ($node instanceof ClassMethod && $scope->isInClass()) {
267+
return $scope->getClassReflection()->getNativeMethod($node->name->name)->getAttributes();
268+
} elseif ($node instanceof Function_ && $node->namespacedName !== null) {
269+
return $this->reflectionProvider->getFunction($node->namespacedName, $scope)->getAttributes();
270+
} else {
276271
$attributes = $this->attributesWhenInSignature->get($scope);
277272
if ($attributes !== null) {
278273
return $attributes;
@@ -284,16 +279,17 @@ private function getCallAttributes(?Node $node, Scope $scope): array
284279

285280
/**
286281
* @param Scope $scope
287-
* @return list<FakeReflectionAttribute>|list<ReflectionAttribute>
282+
* @return list<AttributeReflection>
288283
*/
289284
private function getAllMethodAttributes(Scope $scope): array
290285
{
291286
if (!$scope->isInClass()) {
292287
return [];
293288
}
294289
$attributes = [];
295-
foreach ($scope->getClassReflection()->getNativeReflection()->getMethods() as $method) {
296-
$methodAttributes = $method->getAttributes();
290+
$classReflection = $scope->getClassReflection();
291+
foreach ($classReflection->getNativeReflection()->getMethods() as $method) {
292+
$methodAttributes = $classReflection->getNativeMethod($method->getName())->getAttributes();
297293
if ($methodAttributes !== []) {
298294
$attributes = array_merge($attributes, $methodAttributes);
299295
}

src/Allowed/GetAttributesWhenInSignature.php

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,29 +3,28 @@
33

44
namespace Spaze\PHPStan\Rules\Disallowed\Allowed;
55

6+
use PhpParser\Node\Name;
67
use PHPStan\Analyser\Scope;
7-
use PHPStan\BetterReflection\Reflection\Adapter\FakeReflectionAttribute;
8-
use PHPStan\BetterReflection\Reflection\Adapter\ReflectionAttribute;
9-
use PHPStan\BetterReflection\Reflection\ReflectionAttribute as BetterReflectionAttribute;
10-
use PHPStan\BetterReflection\Reflector\Reflector;
8+
use PHPStan\Reflection\AttributeReflection;
9+
use PHPStan\Reflection\ReflectionProvider;
1110

1211
class GetAttributesWhenInSignature
1312
{
1413

15-
private Reflector $reflector;
14+
private ReflectionProvider $reflectionProvider;
1615

1716
/** @var class-string|null */
1817
private ?string $currentClass = null;
1918

2019
private ?string $currentMethod = null;
2120

22-
/** @var string|null */
23-
private ?string $currentFunction = null;
21+
/** @var Name|null */
22+
private ?Name $currentFunction = null;
2423

2524

26-
public function __construct(Reflector $reflector)
25+
public function __construct(ReflectionProvider $reflectionProvider)
2726
{
28-
$this->reflector = $reflector;
27+
$this->reflectionProvider = $reflectionProvider;
2928
}
3029

3130

@@ -38,7 +37,7 @@ public function __construct(Reflector $reflector)
3837
* or the function name in a Function_ and a InFunctionNode rules.
3938
*
4039
* @param Scope $scope
41-
* @return list<FakeReflectionAttribute|ReflectionAttribute|BetterReflectionAttribute>|null
40+
* @return list<AttributeReflection>|null
4241
*/
4342
public function get(Scope $scope): ?array
4443
{
@@ -48,9 +47,9 @@ public function get(Scope $scope): ?array
4847
&& $scope->isInClass()
4948
&& $scope->getClassReflection()->getName() === $this->currentClass
5049
) {
51-
return $scope->getClassReflection()->getNativeReflection()->getMethod($this->currentMethod)->getAttributes();
50+
return $scope->getClassReflection()->getNativeMethod($this->currentMethod)->getAttributes();
5251
} elseif ($this->currentFunction !== null) {
53-
return $this->reflector->reflectFunction($this->currentFunction)->getAttributes();
52+
return $this->reflectionProvider->getFunction($this->currentFunction, $scope)->getAttributes();
5453
}
5554
return null;
5655
}
@@ -75,10 +74,10 @@ public function unsetCurrentClassMethodName(): void
7574

7675

7776
/**
78-
* @param string $functionName
77+
* @param Name $functionName
7978
* @return void
8079
*/
81-
public function setCurrentFunctionName(string $functionName): void
80+
public function setCurrentFunctionName(Name $functionName): void
8281
{
8382
$this->currentFunction = $functionName;
8483
}

src/HelperRules/SetCurrentFunctionNameHelperRule.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public function getNodeType(): string
3838
public function processNode(Node $node, Scope $scope): array
3939
{
4040
if ($node->namespacedName !== null) {
41-
$this->attributesWhenInSignature->setCurrentFunctionName($node->namespacedName->toString());
41+
$this->attributesWhenInSignature->setCurrentFunctionName($node->namespacedName);
4242
}
4343
return [];
4444
}

src/Identifier/Identifier.php

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,17 @@
33

44
namespace Spaze\PHPStan\Rules\Disallowed\Identifier;
55

6-
use PHPStan\BetterReflection\Reflector\Exception\IdentifierNotFound;
7-
use PHPStan\BetterReflection\Reflector\Reflector;
6+
use PHPStan\Reflection\ReflectionProvider;
87

98
class Identifier
109
{
11-
private Reflector $reflector;
1210

11+
private ReflectionProvider $reflectionProvider;
1312

14-
public function __construct(Reflector $reflector)
13+
14+
public function __construct(ReflectionProvider $reflectionProvider)
1515
{
16-
$this->reflector = $reflector;
16+
$this->reflectionProvider = $reflectionProvider;
1717
}
1818

1919

@@ -40,12 +40,10 @@ public function matches(string $pattern, string $value, array $excludes = [], ar
4040
}
4141
}
4242
if ($matches && $excludeWithAttributes) {
43-
try {
44-
$attributes = array_map(fn($a) => $a->getName(), $this->reflector->reflectClass($value)->getAttributes());
45-
} catch (IdentifierNotFound $e) {
46-
$attributes = [];
43+
if (!$this->reflectionProvider->hasClass($value)) {
44+
return true;
4745
}
48-
46+
$attributes = array_map(fn($a) => $a->getName(), $this->reflectionProvider->getClass($value)->getAttributes());
4947
foreach ($attributes as $attribute) {
5048
foreach ($excludeWithAttributes as $excludeWithAttribute) {
5149
if (fnmatch($excludeWithAttribute, $attribute, FNM_NOESCAPE | FNM_CASEFOLD)) {

tests/Usages/NamespaceUsagesAllowInClassWithAttributesTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ private function emulateHelperRules(Node $node): void
111111
} elseif ($node instanceof InClassMethodNode) { /** @phpstan-ignore phpstanApi.instanceofAssumption (🤞) */
112112
$this->container->getByType(GetAttributesWhenInSignature::class)->unsetCurrentClassMethodName();
113113
} elseif ($node instanceof Function_ && $node->namespacedName !== null) {
114-
$this->container->getByType(GetAttributesWhenInSignature::class)->setCurrentFunctionName($node->namespacedName->toString());
114+
$this->container->getByType(GetAttributesWhenInSignature::class)->setCurrentFunctionName($node->namespacedName);
115115
} elseif ($node instanceof InFunctionNode) { /** @phpstan-ignore phpstanApi.instanceofAssumption (🤞) */
116116
$this->container->getByType(GetAttributesWhenInSignature::class)->unsetCurrentFunctionName();
117117
}

0 commit comments

Comments
 (0)