4
4
5
5
use Attribute ;
6
6
use PhpParser \Node ;
7
+ use PhpParser \Node \Stmt \Class_ ;
7
8
use PHPStan \Analyser \MutatingScope ;
8
9
use PHPStan \Analyser \Scope ;
9
10
use PHPStan \Reflection \ReflectionProvider ;
19
20
final class TraitAttributesRule implements Rule
20
21
{
21
22
23
+ private int $ classId = 1 ;
24
+
22
25
public function __construct (
23
26
private AttributesCheck $ attributesCheck ,
24
27
private ReflectionProvider $ reflectionProvider ,
@@ -41,12 +44,18 @@ public function processNode(Node $node, Scope $scope): array
41
44
if (!$ this ->reflectionProvider ->hasClass ($ traitName ->toString ())) {
42
45
return [];
43
46
}
44
- $ classReflection = $ this ->reflectionProvider ->getClass ($ traitName ->toString ());
47
+ $ traitClassReflection = $ this ->reflectionProvider ->getClass ($ traitName ->toString ());
45
48
46
49
if (!$ scope instanceof MutatingScope) {
47
50
throw new ShouldNotHappenException ();
48
51
}
49
- $ scope = $ scope ->enterTrait ($ classReflection );
52
+
53
+ $ fakeClass = new Class_ (null , ['stmts ' => [new Node \Stmt \TraitUse ([$ traitName ])]], ['startLine ' => $ this ->classId , 'endLine ' => $ this ->classId ]);
54
+ $ this ->classId ++;
55
+
56
+ $ fakeClassReflection = $ this ->reflectionProvider ->getAnonymousClassReflection ($ fakeClass , $ scope );
57
+ $ scope = $ scope ->enterClass ($ fakeClassReflection );
58
+ $ scope = $ scope ->enterTrait ($ traitClassReflection );
50
59
51
60
$ errors = $ this ->attributesCheck ->check (
52
61
$ scope ,
@@ -55,7 +64,7 @@ public function processNode(Node $node, Scope $scope): array
55
64
'class ' ,
56
65
);
57
66
58
- if (count ($ classReflection ->getNativeReflection ()->getAttributes ('AllowDynamicProperties ' )) > 0 ) {
67
+ if (count ($ traitClassReflection ->getNativeReflection ()->getAttributes ('AllowDynamicProperties ' )) > 0 ) {
59
68
$ errors [] = RuleErrorBuilder::message ('Attribute class AllowDynamicProperties cannot be used with trait. ' )
60
69
->identifier ('trait.allowDynamicProperties ' )
61
70
->nonIgnorable ()
0 commit comments