10
10
use PHPStan \PhpDocParser \Lexer \Lexer ;
11
11
use PHPStan \PhpDocParser \Parser \PhpDocParser ;
12
12
use PHPStan \PhpDocParser \Parser \TokenIterator ;
13
- use PHPStan \Reflection \ExtendedMethodReflection ;
14
13
use PHPUnit \Framework \TestCase ;
15
14
use ShipMonk \PHPStan \DeadCode \Graph \ClassMethodRef ;
16
15
use ShipMonk \PHPStan \DeadCode \Graph \ClassMethodUsage ;
@@ -48,21 +47,27 @@ public function getUsages(Node $node, Scope $scope): array
48
47
}
49
48
50
49
$ usages = [];
50
+ $ className = $ classReflection ->getName ();
51
51
52
52
foreach ($ classReflection ->getNativeReflection ()->getMethods () as $ method ) {
53
- $ dataProviders = array_merge (
53
+ $ methodName = $ method ->getName ();
54
+
55
+ $ externalDataProviderMethods = $ this ->getExternalDataProvidersFromAttributes ($ method );
56
+ $ localDataProviderMethods = array_merge (
54
57
$ this ->getDataProvidersFromAnnotations ($ method ->getDocComment ()),
55
58
$ this ->getDataProvidersFromAttributes ($ method ),
56
59
);
57
60
58
- foreach ($ dataProviders as $ dataProvider ) {
59
- if ($ classReflection ->hasNativeMethod ($ dataProvider )) {
60
- $ usages [] = $ this ->createUsage ($ classReflection ->getNativeMethod ($ dataProvider ), 'Data provider method ' );
61
- }
61
+ foreach ($ externalDataProviderMethods as [$ externalClassName , $ externalMethodName ]) {
62
+ $ usages [] = $ this ->createUsage ($ externalClassName , $ externalMethodName , "External data provider method, used by $ className:: $ methodName " );
63
+ }
64
+
65
+ foreach ($ localDataProviderMethods as $ dataProvider ) {
66
+ $ usages [] = $ this ->createUsage ($ className , $ dataProvider , "Data provider method, used by $ methodName " );
62
67
}
63
68
64
69
if ($ this ->isTestCaseMethod ($ method )) {
65
- $ usages [] = $ this ->createUsage ($ classReflection -> getNativeMethod ( $ method -> getName ()) , 'Test method ' );
70
+ $ usages [] = $ this ->createUsage ($ className , $ methodName , 'Test method ' );
66
71
}
67
72
}
68
73
@@ -128,6 +133,25 @@ private function getDataProvidersFromAttributes(ReflectionMethod $method): array
128
133
return $ result ;
129
134
}
130
135
136
+ /**
137
+ * @return list<array{string, string}>
138
+ */
139
+ private function getExternalDataProvidersFromAttributes (ReflectionMethod $ method ): array
140
+ {
141
+ $ result = [];
142
+
143
+ foreach ($ method ->getAttributes ('PHPUnit\Framework\Attributes\DataProviderExternal ' ) as $ providerAttributeReflection ) {
144
+ $ className = $ providerAttributeReflection ->getArguments ()[0 ] ?? $ providerAttributeReflection ->getArguments ()['className ' ] ?? null ;
145
+ $ methodName = $ providerAttributeReflection ->getArguments ()[1 ] ?? $ providerAttributeReflection ->getArguments ()['methodName ' ] ?? null ;
146
+
147
+ if (is_string ($ className ) && is_string ($ methodName )) {
148
+ $ result [] = [$ className , $ methodName ];
149
+ }
150
+ }
151
+
152
+ return $ result ;
153
+ }
154
+
131
155
private function hasAttribute (ReflectionMethod $ method , string $ attributeClass ): bool
132
156
{
133
157
return $ method ->getAttributes ($ attributeClass ) !== [];
@@ -142,13 +166,13 @@ private function hasAnnotation(ReflectionMethod $method, string $string): bool
142
166
return strpos ($ method ->getDocComment (), $ string ) !== false ;
143
167
}
144
168
145
- private function createUsage (ExtendedMethodReflection $ getNativeMethod , string $ reason ): ClassMethodUsage
169
+ private function createUsage (string $ className , string $ methodName , string $ reason ): ClassMethodUsage
146
170
{
147
171
return new ClassMethodUsage (
148
172
UsageOrigin::createVirtual ($ this , VirtualUsageData::withNote ($ reason )),
149
173
new ClassMethodRef (
150
- $ getNativeMethod -> getDeclaringClass ()-> getName () ,
151
- $ getNativeMethod -> getName () ,
174
+ $ className ,
175
+ $ methodName ,
152
176
false ,
153
177
),
154
178
);
0 commit comments