2
2
3
3
namespace PHPStan \Reflection \Php ;
4
4
5
- use PhpParser \Node ;
6
- use PhpParser \Node \Stmt \ClassMethod ;
7
- use PhpParser \Node \Stmt \Declare_ ;
8
- use PhpParser \Node \Stmt \Function_ ;
9
- use PhpParser \Node \Stmt \Namespace_ ;
10
5
use PHPStan \BetterReflection \Reflection \Adapter \ReflectionMethod ;
11
6
use PHPStan \BetterReflection \Reflection \Adapter \ReflectionParameter ;
12
- use PHPStan \Cache \Cache ;
13
- use PHPStan \Parser \FunctionCallStatementFinder ;
14
7
use PHPStan \Parser \Parser ;
8
+ use PHPStan \Parser \VariadicMethodsVisitor ;
15
9
use PHPStan \Reflection \Assertions ;
16
10
use PHPStan \Reflection \ClassMemberReflection ;
17
11
use PHPStan \Reflection \ClassReflection ;
21
15
use PHPStan \Reflection \ExtendedParametersAcceptor ;
22
16
use PHPStan \Reflection \InitializerExprTypeResolver ;
23
17
use PHPStan \Reflection \MethodPrototypeReflection ;
24
- use PHPStan \Reflection \ParametersAcceptor ;
25
18
use PHPStan \Reflection \ReflectionProvider ;
26
19
use PHPStan \TrinaryLogic ;
27
20
use PHPStan \Type \ArrayType ;
36
29
use PHPStan \Type \TypehintHelper ;
37
30
use PHPStan \Type \VoidType ;
38
31
use ReflectionException ;
32
+ use function array_key_exists ;
39
33
use function array_map ;
34
+ use function count ;
40
35
use function explode ;
41
- use function filemtime ;
42
36
use function in_array ;
43
- use function is_bool ;
44
- use function sprintf ;
37
+ use function is_array ;
45
38
use function strtolower ;
46
- use function time ;
47
39
use const PHP_VERSION_ID ;
48
40
49
41
/**
@@ -62,6 +54,8 @@ final class PhpMethodReflection implements ExtendedMethodReflection
62
54
/** @var list<ExtendedFunctionVariant>|null */
63
55
private ?array $ variants = null ;
64
56
57
+ private ?bool $ containsVariadicCalls = null ;
58
+
65
59
/**
66
60
* @param Type[] $phpDocParameterTypes
67
61
* @param Type[] $phpDocParameterOutTypes
@@ -75,8 +69,6 @@ public function __construct(
75
69
private ReflectionMethod $ reflection ,
76
70
private ReflectionProvider $ reflectionProvider ,
77
71
private Parser $ parser ,
78
- private FunctionCallStatementFinder $ functionCallStatementFinder ,
79
- private Cache $ cache ,
80
72
private TemplateTypeMap $ templateTypeMap ,
81
73
private array $ phpDocParameterTypes ,
82
74
private ?Type $ phpDocReturnType ,
@@ -253,81 +245,27 @@ private function isVariadic(): bool
253
245
}
254
246
255
247
if (!$ isNativelyVariadic && $ filename !== null ) {
256
- $ modifiedTime = @filemtime ($ filename );
257
- if ($ modifiedTime === false ) {
258
- $ modifiedTime = time ();
259
- }
260
- $ key = sprintf ('variadic-method-%s-%s-%s ' , $ declaringClass ->getName (), $ this ->reflection ->getName (), $ filename );
261
- $ variableCacheKey = sprintf ('%d-v4 ' , $ modifiedTime );
262
- $ cachedResult = $ this ->cache ->load ($ key , $ variableCacheKey );
263
- if ($ cachedResult === null || !is_bool ($ cachedResult )) {
264
- $ nodes = $ this ->parser ->parseFile ($ filename );
265
- $ result = $ this ->callsFuncGetArgs ($ declaringClass , $ nodes );
266
- $ this ->cache ->save ($ key , $ variableCacheKey , $ result );
267
- return $ result ;
268
- }
269
-
270
- return $ cachedResult ;
271
- }
272
-
273
- return $ isNativelyVariadic ;
274
- }
275
-
276
- /**
277
- * @param Node[] $nodes
278
- */
279
- private function callsFuncGetArgs (ClassReflection $ declaringClass , array $ nodes ): bool
280
- {
281
- foreach ($ nodes as $ node ) {
282
- if (
283
- $ node instanceof Node \Stmt \ClassLike
284
- ) {
285
- if (!isset ($ node ->namespacedName )) {
286
- continue ;
287
- }
288
- if ($ declaringClass ->getName () !== (string ) $ node ->namespacedName ) {
289
- continue ;
290
- }
291
- if ($ this ->callsFuncGetArgs ($ declaringClass , $ node ->stmts )) {
292
- return true ;
293
- }
294
- continue ;
248
+ if ($ this ->containsVariadicCalls !== null ) {
249
+ return $ this ->containsVariadicCalls ;
295
250
}
296
251
297
- if ($ node instanceof ClassMethod) {
298
- if ($ node ->getStmts () === null ) {
299
- continue ; // interface
300
- }
252
+ $ nodes = $ this ->parser ->parseFile ($ filename );
253
+ if (count ($ nodes ) > 0 ) {
254
+ $ variadicMethods = $ nodes [0 ]->getAttribute (VariadicMethodsVisitor::ATTRIBUTE_NAME );
301
255
302
- $ methodName = $ node ->name ->name ;
303
- if ($ methodName === $ this ->reflection ->getName ()) {
304
- return $ this ->functionCallStatementFinder ->findFunctionCallInStatements (ParametersAcceptor::VARIADIC_FUNCTIONS , $ node ->getStmts ()) !== null ;
256
+ if (
257
+ is_array ($ variadicMethods )
258
+ && array_key_exists ($ declaringClass ->getName (), $ variadicMethods )
259
+ && in_array ($ this ->reflection ->getName (), $ variadicMethods [$ declaringClass ->getName ()], true )
260
+ ) {
261
+ return $ this ->containsVariadicCalls = true ;
305
262
}
306
-
307
- continue ;
308
263
}
309
264
310
- if ($ node instanceof Function_) {
311
- continue ;
312
- }
313
-
314
- if ($ node instanceof Namespace_) {
315
- if ($ this ->callsFuncGetArgs ($ declaringClass , $ node ->stmts )) {
316
- return true ;
317
- }
318
- continue ;
319
- }
320
-
321
- if (!$ node instanceof Declare_ || $ node ->stmts === null ) {
322
- continue ;
323
- }
324
-
325
- if ($ this ->callsFuncGetArgs ($ declaringClass , $ node ->stmts )) {
326
- return true ;
327
- }
265
+ return $ this ->containsVariadicCalls = false ;
328
266
}
329
267
330
- return false ;
268
+ return $ isNativelyVariadic ;
331
269
}
332
270
333
271
public function isPrivate (): bool
0 commit comments