12
12
use PHPStan \BetterReflection \SourceLocator \Type \MemoizingSourceLocator ;
13
13
use PHPStan \BetterReflection \SourceLocator \Type \PhpInternalSourceLocator ;
14
14
use PHPStan \BetterReflection \SourceLocator \Type \SourceLocator ;
15
+ use PHPStan \Php \PhpVersion ;
15
16
use PHPStan \Reflection \BetterReflection \SourceLocator \AutoloadSourceLocator ;
16
17
use PHPStan \Reflection \BetterReflection \SourceLocator \ComposerJsonAndInstalledJsonSourceLocatorMaker ;
17
18
use PHPStan \Reflection \BetterReflection \SourceLocator \FileNodesFetcher ;
18
19
use PHPStan \Reflection \BetterReflection \SourceLocator \PhpVersionBlacklistSourceLocator ;
19
20
use ReflectionClass ;
20
21
use function dirname ;
21
22
use function is_file ;
23
+ use function serialize ;
24
+ use function sha1 ;
22
25
23
26
class TestCaseSourceLocatorFactory
24
27
{
25
28
29
+ /** @var array<string, list<SourceLocator>> */
30
+ private static array $ composerSourceLocatorsCache = [];
31
+
32
+ /**
33
+ * @param string[] $fileExtensions
34
+ * @param string[] $obsoleteExcludesAnalyse
35
+ * @param array{analyse?: array<int, string>, analyseAndScan?: array<int, string>}|null $excludePaths
36
+ */
26
37
public function __construct (
27
38
private ComposerJsonAndInstalledJsonSourceLocatorMaker $ composerJsonAndInstalledJsonSourceLocatorMaker ,
28
39
private Parser $ phpParser ,
29
40
private Parser $ php8Parser ,
30
41
private FileNodesFetcher $ fileNodesFetcher ,
31
42
private PhpStormStubsSourceStubber $ phpstormStubsSourceStubber ,
32
43
private ReflectionSourceStubber $ reflectionSourceStubber ,
44
+ private PhpVersion $ phpVersion ,
45
+ private array $ fileExtensions ,
46
+ private array $ obsoleteExcludesAnalyse ,
47
+ private ?array $ excludePaths ,
33
48
)
34
49
{
35
50
}
@@ -38,8 +53,14 @@ public function create(): SourceLocator
38
53
{
39
54
$ classLoaders = ClassLoader::getRegisteredLoaders ();
40
55
$ classLoaderReflection = new ReflectionClass (ClassLoader::class);
41
- $ locators = [];
42
- if ($ classLoaderReflection ->hasProperty ('vendorDir ' )) {
56
+ $ cacheKey = sha1 (serialize ([
57
+ $ this ->phpVersion ->getVersionId (),
58
+ $ this ->fileExtensions ,
59
+ $ this ->obsoleteExcludesAnalyse ,
60
+ $ this ->excludePaths ,
61
+ ]));
62
+ if ($ classLoaderReflection ->hasProperty ('vendorDir ' ) && ! isset (self ::$ composerSourceLocatorsCache [$ cacheKey ])) {
63
+ $ composerLocators = [];
43
64
$ vendorDirProperty = $ classLoaderReflection ->getProperty ('vendorDir ' );
44
65
$ vendorDirProperty ->setAccessible (true );
45
66
foreach ($ classLoaders as $ classLoader ) {
@@ -52,10 +73,13 @@ public function create(): SourceLocator
52
73
if ($ composerSourceLocator === null ) {
53
74
continue ;
54
75
}
55
- $ locators [] = $ composerSourceLocator ;
76
+ $ composerLocators [] = $ composerSourceLocator ;
56
77
}
78
+
79
+ self ::$ composerSourceLocatorsCache [$ cacheKey ] = $ composerLocators ;
57
80
}
58
81
82
+ $ locators = self ::$ composerSourceLocatorsCache [$ cacheKey ] ?? [];
59
83
$ astLocator = new Locator ($ this ->phpParser );
60
84
$ astPhp8Locator = new Locator ($ this ->php8Parser );
61
85
0 commit comments