-
Notifications
You must be signed in to change notification settings - Fork 506
/
Copy pathBaselineIgnoredErrorHelper.php
104 lines (84 loc) · 3.01 KB
/
BaselineIgnoredErrorHelper.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
<?php declare(strict_types = 1);
namespace PHPStan\Analyser\Ignore;
use PHPStan\Analyser\Error;
use PHPStan\File\FileHelper;
use PHPStan\File\ParentDirectoryRelativePathHelper;
use PHPStan\File\RelativePathHelper;
final class BaselineIgnoredErrorHelper
{
public function __construct(
private FileHelper $fileHelper,
)
{
}
/**
* @param mixed[][] $baselinedErrors errors currently present in the baseline
* @param list<Error> $currentAnalysisErrors errors from the current analysis
* @return list<Error> errors from the current analysis which already exit in the baseline
*/
public function removeUnusedIgnoredErrors(array $baselinedErrors, array $currentAnalysisErrors, ParentDirectoryRelativePathHelper $baselinePathHelper): array
{
$ignoreErrorsByFile = $this->mapIgnoredErrorsByFile($baselinedErrors);
$ignoreUseCount = [];
$nextBaselinedErrors = [];
foreach ($currentAnalysisErrors as $error) {
$hasMatchingIgnore = $this->checkIgnoreErrorByPath($error->getFilePath(), $ignoreErrorsByFile, $error, $ignoreUseCount, $baselinePathHelper);
if ($hasMatchingIgnore) {
$nextBaselinedErrors[] = $error;
continue;
}
$traitFilePath = $error->getTraitFilePath();
if ($traitFilePath === null) {
continue;
}
$hasMatchingIgnore = $this->checkIgnoreErrorByPath($traitFilePath, $ignoreErrorsByFile, $error, $ignoreUseCount, $baselinePathHelper);
if (!$hasMatchingIgnore) {
continue;
}
$nextBaselinedErrors[] = $error;
}
return $nextBaselinedErrors;
}
/**
* @param mixed[][] $ignoreErrorsByFile
* @param int[] $ignoreUseCount map of indexes of ignores and how often they have been "used" to ignore an error
*/
private function checkIgnoreErrorByPath(string $filePath, array $ignoreErrorsByFile, Error $error, array &$ignoreUseCount, RelativePathHelper $baselinePathHelper): bool
{
$relativePath = $baselinePathHelper->getRelativePath($filePath);
if (!isset($ignoreErrorsByFile[$relativePath])) {
return false;
}
foreach ($ignoreErrorsByFile[$relativePath] as $ignoreError) {
$ignore = $ignoreError['ignoreError'];
$shouldIgnore = IgnoredError::shouldIgnore($this->fileHelper, $error, $ignore['message'] ?? null, $ignore['identifier'] ?? null, null);
if (!$shouldIgnore) {
continue;
}
$realCount = $ignoreUseCount[$ignoreError['index']] ?? 0;
$realCount++;
$ignoreUseCount[$ignoreError['index']] = $realCount;
if ($realCount <= $ignore['count']) {
return true;
}
}
return false;
}
/**
* @param mixed[][] $baselineIgnoreErrors
* @return mixed[][] ignored errors from baseline mapped and grouped by files
*/
private function mapIgnoredErrorsByFile(array $baselineIgnoreErrors): array
{
$ignoreErrorsByFile = [];
foreach ($baselineIgnoreErrors as $i => $ignoreError) {
$ignoreErrorEntry = [
'index' => $i,
'ignoreError' => $ignoreError,
];
$normalizedPath = $this->fileHelper->normalizePath($ignoreError['path']);
$ignoreErrorsByFile[$normalizedPath][] = $ignoreErrorEntry;
}
return $ignoreErrorsByFile;
}
}