|
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