Skip to content

Commit f5f0b37

Browse files
committed
Fix reported file path for --tmp-file and ignoring errors
1 parent 80b40f2 commit f5f0b37

File tree

2 files changed

+143
-2
lines changed

2 files changed

+143
-2
lines changed

.github/workflows/e2e-tests.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,8 +206,9 @@ jobs:
206206
207207
OUTPUT=$(../bashunit -a exit_code "1" "../../bin/phpstan analyse -vv --error-format raw --tmp-file differentFoo.php --instead-of src/Foo.php")
208208
echo "$OUTPUT"
209-
../bashunit -a contains 'differentFoo.php:10:Method EditorModeE2E\Foo::doFoo() should return float but returns string. [identifier=return.type]' "$OUTPUT"
209+
../bashunit -a contains 'Foo.php:10:Method EditorModeE2E\Foo::doFoo() should return float but returns string. [identifier=return.type]' "$OUTPUT"
210210
../bashunit -a not_contains 'Foo.php:10:Method EditorModeE2E\Foo::doFoo() should return int but returns string. [identifier=return.type]' "$OUTPUT"
211+
../bashunit -a not_contains 'differentFoo.php' "$OUTPUT"
211212
../bashunit -a contains 'Bar.php:10:Parameter #1 $s of method EditorModeE2E\Bar::requireString() expects string, float given. [identifier=argument.type]' "$OUTPUT"
212213
../bashunit -a contains 'Result cache restored. 2 files will be reanalysed.' "$OUTPUT"
213214
../bashunit -a contains 'Result cache was not saved because of --tmp-file and --instead-of CLI options passed (editor mode).' "$OUTPUT"

src/Command/AnalyseApplication.php

Lines changed: 141 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
use PHPStan\Analyser\AnalyserResult;
66
use PHPStan\Analyser\AnalyserResultFinalizer;
7+
use PHPStan\Analyser\Error;
8+
use PHPStan\Analyser\FileAnalyserResult;
79
use PHPStan\Analyser\Ignore\IgnoredErrorHelper;
810
use PHPStan\Analyser\ResultCache\ResultCacheManagerFactory;
911
use PHPStan\Internal\BytesHelper;
@@ -19,6 +21,9 @@
1921
use function sha1_file;
2022
use function sprintf;
2123

24+
/**
25+
* @phpstan-import-type LinesToIgnore from FileAnalyserResult
26+
*/
2227
final class AnalyseApplication
2328
{
2429

@@ -111,7 +116,11 @@ public function analyse(
111116
}
112117

113118
$resultCacheResult = $resultCacheManager->process($intermediateAnalyserResult, $resultCache, $errorOutput, $onlyFiles, true);
114-
$analyserResult = $this->analyserResultFinalizer->finalize($resultCacheResult->getAnalyserResult(), $onlyFiles, $debug)->getAnalyserResult();
119+
$analyserResult = $this->analyserResultFinalizer->finalize(
120+
$this->switchTmpFileInAnalyserResult($resultCacheResult->getAnalyserResult(), $insteadOfFile, $tmpFile),
121+
$onlyFiles,
122+
$debug,
123+
)->getAnalyserResult();
115124
$internalErrors = $analyserResult->getInternalErrors();
116125
$errors = array_merge(
117126
$analyserResult->getErrors(),
@@ -232,4 +241,135 @@ private function runAnalyser(
232241
return $analyserResult;
233242
}
234243

244+
private function switchTmpFileInAnalyserResult(
245+
AnalyserResult $analyserResult,
246+
?string $insteadOfFile,
247+
?string $tmpFile,
248+
): AnalyserResult
249+
{
250+
if ($insteadOfFile === null || $tmpFile === null) {
251+
return $analyserResult;
252+
}
253+
254+
$collectedData = [];
255+
foreach ($analyserResult->getCollectedData() as $data) {
256+
if ($data->getFilePath() === $tmpFile) {
257+
$data = $data->changeFilePath($insteadOfFile);
258+
}
259+
260+
$collectedData[] = $data;
261+
}
262+
263+
$dependencies = null;
264+
if ($analyserResult->getDependencies() !== null) {
265+
$dependencies = $this->switchTmpFileInDependencies($analyserResult->getDependencies(), $insteadOfFile, $tmpFile);
266+
}
267+
$usedTraitDependencies = null;
268+
if ($analyserResult->getUsedTraitDependencies() !== null) {
269+
$usedTraitDependencies = $this->switchTmpFileInDependencies($analyserResult->getUsedTraitDependencies(), $insteadOfFile, $tmpFile);
270+
}
271+
272+
$exportedNodes = [];
273+
foreach ($analyserResult->getExportedNodes() as $file => $fileExportedNodes) {
274+
if ($file === $tmpFile) {
275+
$file = $insteadOfFile;
276+
}
277+
278+
$exportedNodes[$file] = $fileExportedNodes;
279+
}
280+
281+
return new AnalyserResult(
282+
$this->switchTmpFileInErrors($analyserResult->getUnorderedErrors(), $insteadOfFile, $tmpFile),
283+
$this->switchTmpFileInErrors($analyserResult->getFilteredPhpErrors(), $insteadOfFile, $tmpFile),
284+
$this->switchTmpFileInErrors($analyserResult->getAllPhpErrors(), $insteadOfFile, $tmpFile),
285+
$this->switchTmpFileInErrors($analyserResult->getLocallyIgnoredErrors(), $insteadOfFile, $tmpFile),
286+
$this->swittchTmpFileInLinesToIgnore($analyserResult->getLinesToIgnore(), $insteadOfFile, $tmpFile),
287+
$this->swittchTmpFileInLinesToIgnore($analyserResult->getUnmatchedLineIgnores(), $insteadOfFile, $tmpFile),
288+
$analyserResult->getInternalErrors(),
289+
$collectedData,
290+
$dependencies,
291+
$usedTraitDependencies,
292+
$exportedNodes,
293+
$analyserResult->hasReachedInternalErrorsCountLimit(),
294+
$analyserResult->getPeakMemoryUsageBytes(),
295+
);
296+
}
297+
298+
/**
299+
* @param array<string, array<string>> $dependencies
300+
* @return array<string, array<string>>
301+
*/
302+
private function switchTmpFileInDependencies(array $dependencies, string $insteadOfFile, string $tmpFile): array
303+
{
304+
$newDependencies = [];
305+
foreach ($dependencies as $dependencyFile => $dependentFiles) {
306+
$new = [];
307+
foreach ($dependentFiles as $file) {
308+
if ($file === $tmpFile) {
309+
$new[] = $insteadOfFile;
310+
continue;
311+
}
312+
313+
$new[] = $file;
314+
}
315+
316+
$key = $dependencyFile;
317+
if ($key === $tmpFile) {
318+
$key = $insteadOfFile;
319+
}
320+
321+
$newDependencies[$key] = $new;
322+
}
323+
324+
return $newDependencies;
325+
}
326+
327+
/**
328+
* @param list<Error> $errors
329+
* @return list<Error>
330+
*/
331+
private function switchTmpFileInErrors(array $errors, string $insteadOfFile, string $tmpFile): array
332+
{
333+
$newErrors = [];
334+
foreach ($errors as $error) {
335+
if ($error->getFilePath() === $tmpFile) {
336+
$error = $error->changeFilePath($insteadOfFile);
337+
}
338+
if ($error->getTraitFilePath() === $tmpFile) {
339+
$error = $error->changeTraitFilePath($insteadOfFile);
340+
}
341+
342+
$newErrors[] = $error;
343+
}
344+
345+
return $newErrors;
346+
}
347+
348+
/**
349+
* @param array<string, LinesToIgnore> $linesToIgnore
350+
* @return array<string, LinesToIgnore>
351+
*/
352+
private function swittchTmpFileInLinesToIgnore(array $linesToIgnore, string $insteadOfFile, string $tmpFile): array
353+
{
354+
$newLinesToIgnore = [];
355+
foreach ($linesToIgnore as $file => $lines) {
356+
if ($file === $tmpFile) {
357+
$file = $insteadOfFile;
358+
}
359+
360+
$newLines = [];
361+
foreach ($lines as $f => $line) {
362+
if ($f === $tmpFile) {
363+
$f = $insteadOfFile;
364+
}
365+
366+
$newLines[$f] = $line;
367+
}
368+
369+
$newLinesToIgnore[$file] = $newLines;
370+
}
371+
372+
return $newLinesToIgnore;
373+
}
374+
235375
}

0 commit comments

Comments
 (0)