99use PHPStan \Dependency \ExportedNodeFetcher ;
1010use PHPStan \File \FileReader ;
1111use PHPStan \File \FileWriter ;
12+ use Symfony \Component \Finder \Finder ;
1213use function array_fill_keys ;
1314use function array_key_exists ;
1415
@@ -21,6 +22,8 @@ class ResultCacheManager
2122
2223 private string $ cacheFilePath ;
2324
25+ private string $ tempResultCachePath ;
26+
2427 /** @var string[] */
2528 private array $ allCustomConfigFiles ;
2629
@@ -40,9 +43,13 @@ class ResultCacheManager
4043 /** @var array<string, string> */
4144 private array $ fileHashes = [];
4245
46+ /** @var array<string, string> */
47+ private array $ fileReplacements = [];
48+
4349 /**
4450 * @param ExportedNodeFetcher $exportedNodeFetcher
4551 * @param string $cacheFilePath
52+ * @param string $tempResultCachePath
4653 * @param string[] $allCustomConfigFiles
4754 * @param string[] $analysedPaths
4855 * @param string[] $composerAutoloaderProjectPaths
@@ -53,6 +60,7 @@ class ResultCacheManager
5360 public function __construct (
5461 ExportedNodeFetcher $ exportedNodeFetcher ,
5562 string $ cacheFilePath ,
63+ string $ tempResultCachePath ,
5664 array $ allCustomConfigFiles ,
5765 array $ analysedPaths ,
5866 array $ composerAutoloaderProjectPaths ,
@@ -63,6 +71,7 @@ public function __construct(
6371 {
6472 $ this ->exportedNodeFetcher = $ exportedNodeFetcher ;
6573 $ this ->cacheFilePath = $ cacheFilePath ;
74+ $ this ->tempResultCachePath = $ tempResultCachePath ;
6675 $ this ->allCustomConfigFiles = $ allCustomConfigFiles ;
6776 $ this ->analysedPaths = $ analysedPaths ;
6877 $ this ->composerAutoloaderProjectPaths = $ composerAutoloaderProjectPaths ;
@@ -71,12 +80,17 @@ public function __construct(
7180 $ this ->cliAutoloadFile = $ cliAutoloadFile ;
7281 }
7382
83+ public function setFileReplacement (string $ insteadOfFile , string $ tmpFile ): void
84+ {
85+ $ this ->fileReplacements [$ insteadOfFile ] = $ tmpFile ;
86+ }
87+
7488 /**
7589 * @param string[] $allAnalysedFiles
7690 * @param bool $debug
7791 * @return ResultCache
7892 */
79- public function restore (array $ allAnalysedFiles , bool $ debug , Output $ output ): ResultCache
93+ public function restore (array $ allAnalysedFiles , bool $ debug , Output $ output, ? string $ resultCacheName = null ): ResultCache
8094 {
8195 if ($ debug ) {
8296 if ($ output ->isDebug ()) {
@@ -85,15 +99,20 @@ public function restore(array $allAnalysedFiles, bool $debug, Output $output): R
8599 return new ResultCache ($ allAnalysedFiles , true , time (), [], [], []);
86100 }
87101
88- if (!is_file ($ this ->cacheFilePath )) {
102+ $ cacheFilePath = $ this ->cacheFilePath ;
103+ if ($ resultCacheName !== null ) {
104+ $ cacheFilePath = $ this ->tempResultCachePath . '/ ' . $ resultCacheName . '.php ' ;
105+ }
106+
107+ if (!is_file ($ cacheFilePath )) {
89108 if ($ output ->isDebug ()) {
90109 $ output ->writeLineFormatted ('Result cache not used because the cache file does not exist. ' );
91110 }
92111 return new ResultCache ($ allAnalysedFiles , true , time (), [], [], []);
93112 }
94113
95114 try {
96- $ data = require $ this -> cacheFilePath ;
115+ $ data = require $ cacheFilePath ;
97116 } catch (\Throwable $ e ) {
98117 if ($ output ->isDebug ()) {
99118 $ output ->writeLineFormatted (sprintf ('Result cache not used because an error occurred while loading the cache file: %s ' , $ e ->getMessage ()));
@@ -102,7 +121,7 @@ public function restore(array $allAnalysedFiles, bool $debug, Output $output): R
102121 }
103122
104123 if (!is_array ($ data )) {
105- @unlink ($ this -> cacheFilePath );
124+ @unlink ($ cacheFilePath );
106125 if ($ output ->isDebug ()) {
107126 $ output ->writeLineFormatted ('Result cache not used because the cache file is corrupted. ' );
108127 }
@@ -208,6 +227,9 @@ public function restore(array $allAnalysedFiles, bool $debug, Output $output): R
208227 */
209228 private function exportedNodesChanged (string $ analysedFile , array $ cachedFileExportedNodes ): bool
210229 {
230+ if (array_key_exists ($ analysedFile , $ this ->fileReplacements )) {
231+ $ analysedFile = $ this ->fileReplacements [$ analysedFile ];
232+ }
211233 $ fileExportedNodes = $ this ->exportedNodeFetcher ->fetchNodes ($ analysedFile );
212234 if (count ($ fileExportedNodes ) !== count ($ cachedFileExportedNodes )) {
213235 return true ;
@@ -223,15 +245,22 @@ private function exportedNodesChanged(string $analysedFile, array $cachedFileExp
223245 return false ;
224246 }
225247
226- public function process (AnalyserResult $ analyserResult , ResultCache $ resultCache , bool $ save ): ResultCacheProcessResult
248+ /**
249+ * @param AnalyserResult $analyserResult
250+ * @param ResultCache $resultCache
251+ * @param bool|string $save
252+ * @return ResultCacheProcessResult
253+ * @throws \PHPStan\ShouldNotHappenException
254+ */
255+ public function process (AnalyserResult $ analyserResult , ResultCache $ resultCache , $ save ): ResultCacheProcessResult
227256 {
228257 $ internalErrors = $ analyserResult ->getInternalErrors ();
229258 $ freshErrorsByFile = [];
230259 foreach ($ analyserResult ->getErrors () as $ error ) {
231260 $ freshErrorsByFile [$ error ->getFilePath ()][] = $ error ;
232261 }
233262
234- $ doSave = function (array $ errorsByFile , ?array $ dependencies , array $ exportedNodes ) use ($ internalErrors , $ resultCache ): bool {
263+ $ doSave = function (array $ errorsByFile , ?array $ dependencies , array $ exportedNodes, ? string $ resultCacheName ) use ($ internalErrors , $ resultCache ): bool {
235264 if ($ dependencies === null ) {
236265 return false ;
237266 }
@@ -250,14 +279,14 @@ public function process(AnalyserResult $analyserResult, ResultCache $resultCache
250279 }
251280 }
252281
253- $ this ->save ($ resultCache ->getLastFullAnalysisTime (), $ errorsByFile , $ dependencies , $ exportedNodes );
282+ $ this ->save ($ resultCache ->getLastFullAnalysisTime (), $ resultCacheName , $ errorsByFile , $ dependencies , $ exportedNodes );
254283 return true ;
255284 };
256285
257286 if ($ resultCache ->isFullAnalysis ()) {
258287 $ saved = false ;
259- if ($ save ) {
260- $ saved = $ doSave ($ freshErrorsByFile , $ analyserResult ->getDependencies (), $ analyserResult ->getExportedNodes ());
288+ if ($ save !== false ) {
289+ $ saved = $ doSave ($ freshErrorsByFile , $ analyserResult ->getDependencies (), $ analyserResult ->getExportedNodes (), is_string ( $ save ) ? $ save : null );
261290 }
262291
263292 return new ResultCacheProcessResult ($ analyserResult , $ saved );
@@ -268,8 +297,8 @@ public function process(AnalyserResult $analyserResult, ResultCache $resultCache
268297 $ exportedNodes = $ this ->mergeExportedNodes ($ resultCache , $ analyserResult ->getExportedNodes ());
269298
270299 $ saved = false ;
271- if ($ save ) {
272- $ saved = $ doSave ($ errorsByFile , $ dependencies , $ exportedNodes );
300+ if ($ save !== false ) {
301+ $ saved = $ doSave ($ errorsByFile , $ dependencies , $ exportedNodes, is_string ( $ save ) ? $ save : null );
273302 }
274303
275304 $ flatErrors = [];
@@ -371,12 +400,14 @@ private function mergeExportedNodes(ResultCache $resultCache, array $freshExport
371400
372401 /**
373402 * @param int $lastFullAnalysisTime
403+ * @param string|null $resultCacheName
374404 * @param array<string, array<Error>> $errors
375405 * @param array<string, array<string>> $dependencies
376406 * @param array<string, array<ExportedNode>> $exportedNodes
377407 */
378408 private function save (
379409 int $ lastFullAnalysisTime ,
410+ ?string $ resultCacheName ,
380411 array $ errors ,
381412 array $ dependencies ,
382413 array $ exportedNodes
@@ -435,8 +466,13 @@ private function save(
435466
436467 ksort ($ exportedNodes );
437468
469+ $ file = $ this ->cacheFilePath ;
470+ if ($ resultCacheName !== null ) {
471+ $ file = $ this ->tempResultCachePath . '/ ' . $ resultCacheName . '.php ' ;
472+ }
473+
438474 FileWriter::write (
439- $ this -> cacheFilePath ,
475+ $ file ,
440476 sprintf (
441477 $ template ,
442478 var_export ($ lastFullAnalysisTime , true ),
@@ -487,6 +523,9 @@ private function getConfigFiles(): array
487523
488524 private function getFileHash (string $ path ): string
489525 {
526+ if (array_key_exists ($ path , $ this ->fileReplacements )) {
527+ $ path = $ this ->fileReplacements [$ path ];
528+ }
490529 if (array_key_exists ($ path , $ this ->fileHashes )) {
491530 return $ this ->fileHashes [$ path ];
492531 }
@@ -552,4 +591,12 @@ public function clear(): string
552591 return $ dir ;
553592 }
554593
594+ public function clearTemporaryCaches (): void
595+ {
596+ $ finder = new Finder ();
597+ foreach ($ finder ->files ()->name ('*.php ' )->in ($ this ->tempResultCachePath ) as $ tmpResultCacheFile ) {
598+ @unlink ($ tmpResultCacheFile ->getPathname ());
599+ }
600+ }
601+
555602}
0 commit comments