|
4 | 4 |
|
5 | 5 | use Attribute; |
6 | 6 | use PhpParser\Node; |
7 | | -use PhpParser\Node\Stmt\Class_; |
8 | | -use PHPStan\Analyser\MutatingScope; |
9 | 7 | use PHPStan\Analyser\Scope; |
10 | | -use PHPStan\Reflection\ReflectionProvider; |
| 8 | +use PHPStan\Node\InTraitNode; |
11 | 9 | use PHPStan\Rules\AttributesCheck; |
12 | 10 | use PHPStan\Rules\Rule; |
13 | 11 | use PHPStan\Rules\RuleErrorBuilder; |
14 | | -use PHPStan\ShouldNotHappenException; |
15 | 12 | use function count; |
16 | 13 |
|
17 | 14 | /** |
18 | | - * @implements Rule<Node\Stmt\Trait_> |
| 15 | + * @implements Rule<InTraitNode> |
19 | 16 | */ |
20 | 17 | final class TraitAttributesRule implements Rule |
21 | 18 | { |
22 | 19 |
|
23 | 20 | public function __construct( |
24 | 21 | private AttributesCheck $attributesCheck, |
25 | | - private ReflectionProvider $reflectionProvider, |
26 | 22 | ) |
27 | 23 | { |
28 | 24 | } |
29 | 25 |
|
30 | 26 | public function getNodeType(): string |
31 | 27 | { |
32 | | - return Node\Stmt\Trait_::class; |
| 28 | + return InTraitNode::class; |
33 | 29 | } |
34 | 30 |
|
35 | 31 | public function processNode(Node $node, Scope $scope): array |
36 | 32 | { |
37 | | - $traitName = $node->namespacedName; |
38 | | - if ($traitName === null) { |
39 | | - return []; |
40 | | - } |
41 | | - |
42 | | - if (!$this->reflectionProvider->hasClass($traitName->toString())) { |
43 | | - return []; |
44 | | - } |
45 | | - $traitClassReflection = $this->reflectionProvider->getClass($traitName->toString()); |
46 | | - |
47 | | - if (!$scope instanceof MutatingScope) { |
48 | | - throw new ShouldNotHappenException(); |
49 | | - } |
50 | | - $fakeClass = new Class_(null, [new Node\Stmt\TraitUse([$traitName])], ['startLine' => 1, 'endLine' => 1]); |
51 | | - $fakeClassReflection = $this->reflectionProvider->getAnonymousClassReflection($fakeClass, $scope); |
52 | | - $scope = $scope->enterClass($fakeClassReflection); |
53 | | - $scope = $scope->enterTrait($traitClassReflection); |
54 | | - |
| 33 | + $originalNode = $node->getOriginalNode(); |
55 | 34 | $errors = $this->attributesCheck->check( |
56 | 35 | $scope, |
57 | | - $node->attrGroups, |
| 36 | + $originalNode->attrGroups, |
58 | 37 | Attribute::TARGET_CLASS, |
59 | 38 | 'class', |
60 | 39 | ); |
61 | 40 |
|
62 | | - if (count($traitClassReflection->getNativeReflection()->getAttributes('AllowDynamicProperties')) > 0) { |
| 41 | + if (count($node->getTraitReflection()->getNativeReflection()->getAttributes('AllowDynamicProperties')) > 0) { |
63 | 42 | $errors[] = RuleErrorBuilder::message('Attribute class AllowDynamicProperties cannot be used with trait.') |
64 | 43 | ->identifier('trait.allowDynamicProperties') |
65 | 44 | ->nonIgnorable() |
|
0 commit comments