Skip to content

Commit 0a03125

Browse files
committed
ResultCacheManager - capabilities from the future
1 parent 21969ad commit 0a03125

2 files changed

Lines changed: 62 additions & 12 deletions

File tree

conf/config.neon

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ parameters:
9191
earlyTerminatingMethodCalls: []
9292
earlyTerminatingFunctionCalls: []
9393
memoryLimitFile: %tmpDir%/.memory_limit
94+
tempResultCachePath: %tmpDir%/resultCaches
9495
staticReflectionClassNamePatterns:
9596
- '#^PhpParser\\#'
9697
- '#^PHPStan\\#'
@@ -237,6 +238,7 @@ parametersSchema:
237238
earlyTerminatingMethodCalls: arrayOf(listOf(string()))
238239
earlyTerminatingFunctionCalls: listOf(string())
239240
memoryLimitFile: string()
241+
tempResultCachePath: string()
240242
staticReflectionClassNamePatterns: listOf(string())
241243
dynamicConstantNames: listOf(string())
242244
customRulesetUsed: bool()
@@ -394,6 +396,7 @@ services:
394396
class: PHPStan\Analyser\ResultCache\ResultCacheManager
395397
arguments:
396398
cacheFilePath: %tmpDir%/resultCache.php
399+
tempResultCachePath: %tempResultCachePath%
397400
allCustomConfigFiles: %allCustomConfigFiles%
398401
analysedPaths: %analysedPaths%
399402
composerAutoloaderProjectPaths: %composerAutoloaderProjectPaths%

src/Analyser/ResultCache/ResultCacheManager.php

Lines changed: 59 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use PHPStan\Dependency\ExportedNodeFetcher;
1010
use PHPStan\File\FileReader;
1111
use PHPStan\File\FileWriter;
12+
use Symfony\Component\Finder\Finder;
1213
use function array_fill_keys;
1314
use 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

Comments
 (0)