Skip to content

Commit b7b8221

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

File tree

2 files changed

+139
-2
lines changed

2 files changed

+139
-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: 137 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,131 @@ 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+
private function switchTmpFileInDependencies(array $dependencies, string $insteadOfFile, string $tmpFile): array
299+
{
300+
$newDependencies = [];
301+
foreach ($dependencies as $dependencyFile => $dependentFiles) {
302+
$new = [];
303+
foreach ($dependentFiles as $file) {
304+
if ($file === $tmpFile) {
305+
$new[] = $insteadOfFile;
306+
continue;
307+
}
308+
309+
$new[] = $file;
310+
}
311+
312+
$key = $dependencyFile;
313+
if ($key === $tmpFile) {
314+
$key = $insteadOfFile;
315+
}
316+
317+
$newDependencies[$key] = $new;
318+
}
319+
320+
return $newDependencies;
321+
}
322+
323+
/**
324+
* @param list<Error> $errors
325+
* @return list<Error>
326+
*/
327+
private function switchTmpFileInErrors(array $errors, string $insteadOfFile, string $tmpFile): array
328+
{
329+
$newErrors = [];
330+
foreach ($errors as $error) {
331+
if ($error->getFilePath() === $tmpFile) {
332+
$error = $error->changeFilePath($insteadOfFile);
333+
}
334+
if ($error->getTraitFilePath() === $tmpFile) {
335+
$error = $error->changeTraitFilePath($insteadOfFile);
336+
}
337+
338+
$newErrors[] = $error;
339+
}
340+
341+
return $newErrors;
342+
}
343+
344+
/**
345+
* @param array<string, LinesToIgnore> $linesToIgnore
346+
* @return array<string, LinesToIgnore>
347+
*/
348+
private function swittchTmpFileInLinesToIgnore(array $linesToIgnore, string $insteadOfFile, string $tmpFile): array
349+
{
350+
$newLinesToIgnore = [];
351+
foreach ($linesToIgnore as $file => $lines) {
352+
if ($file === $tmpFile) {
353+
$file = $insteadOfFile;
354+
}
355+
356+
$newLines = [];
357+
foreach ($lines as $f => $line) {
358+
if ($f === $tmpFile) {
359+
$f = $insteadOfFile;
360+
}
361+
362+
$newLines[$f] = $line;
363+
}
364+
365+
$newLinesToIgnore[$file] = $newLines;
366+
}
367+
368+
return $newLinesToIgnore;
369+
}
370+
235371
}

0 commit comments

Comments
 (0)