Skip to content

Commit d026655

Browse files
committed
Introduce LocalIgnoresProcessor
1 parent 38e2c96 commit d026655

File tree

6 files changed

+178
-63
lines changed

6 files changed

+178
-63
lines changed

conf/config.neon

+3
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,9 @@ services:
485485
parser: @defaultAnalysisParser
486486
reportUnmatchedIgnoredErrors: %reportUnmatchedIgnoredErrors%
487487

488+
-
489+
class: PHPStan\Analyser\LocalIgnoresProcessor
490+
488491
-
489492
class: PHPStan\Analyser\RuleErrorTransformer
490493

src/Analyser/FileAnalyser.php

+13-63
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,13 @@
1515
use PHPStan\Parser\Parser;
1616
use PHPStan\Parser\ParserErrorsException;
1717
use PHPStan\Rules\Registry as RuleRegistry;
18-
use function array_key_exists;
1918
use function array_keys;
2019
use function array_merge;
2120
use function array_unique;
2221
use function array_values;
2322
use function count;
2423
use function error_reporting;
2524
use function get_class;
26-
use function is_array;
2725
use function is_dir;
2826
use function is_file;
2927
use function restore_error_handler;
@@ -43,6 +41,7 @@ public function __construct(
4341
private Parser $parser,
4442
private DependencyResolver $dependencyResolver,
4543
private RuleErrorTransformer $ruleErrorTransformer,
44+
private LocalIgnoresProcessor $localIgnoresProcessor,
4645
private bool $reportUnmatchedIgnoredErrors,
4746
)
4847
{
@@ -176,69 +175,20 @@ public function analyseFile(
176175
$scope,
177176
$nodeCallback,
178177
);
179-
foreach ($temporaryFileErrors as $tmpFileError) {
180-
$line = $tmpFileError->getLine();
181-
if (
182-
$line !== null
183-
&& $tmpFileError->canBeIgnored()
184-
&& array_key_exists($tmpFileError->getFile(), $linesToIgnore)
185-
&& array_key_exists($line, $linesToIgnore[$tmpFileError->getFile()])
186-
) {
187-
$identifiers = $linesToIgnore[$tmpFileError->getFile()][$line];
188-
if ($identifiers === null) {
189-
$locallyIgnoredErrors[] = $tmpFileError;
190-
unset($unmatchedLineIgnores[$tmpFileError->getFile()][$line]);
191-
continue;
192-
}
193-
194-
if ($tmpFileError->getIdentifier() === null) {
195-
$fileErrors[] = $tmpFileError;
196-
continue;
197-
}
198-
199-
foreach ($identifiers as $i => $ignoredIdentifier) {
200-
if ($ignoredIdentifier !== $tmpFileError->getIdentifier()) {
201-
continue;
202-
}
203-
204-
unset($identifiers[$i]);
205178

206-
if (count($identifiers) > 0) {
207-
$linesToIgnore[$tmpFileError->getFile()][$line] = array_values($identifiers);
208-
} else {
209-
unset($linesToIgnore[$tmpFileError->getFile()][$line]);
210-
}
211-
212-
if (
213-
array_key_exists($tmpFileError->getFile(), $unmatchedLineIgnores)
214-
&& array_key_exists($line, $unmatchedLineIgnores[$tmpFileError->getFile()])
215-
) {
216-
$unmatchedIgnoredIdentifiers = $unmatchedLineIgnores[$tmpFileError->getFile()][$line];
217-
if (is_array($unmatchedIgnoredIdentifiers)) {
218-
foreach ($unmatchedIgnoredIdentifiers as $j => $unmatchedIgnoredIdentifier) {
219-
if ($ignoredIdentifier !== $unmatchedIgnoredIdentifier) {
220-
continue;
221-
}
222-
223-
unset($unmatchedIgnoredIdentifiers[$j]);
224-
225-
if (count($unmatchedIgnoredIdentifiers) > 0) {
226-
$unmatchedLineIgnores[$tmpFileError->getFile()][$line] = array_values($unmatchedIgnoredIdentifiers);
227-
} else {
228-
unset($unmatchedLineIgnores[$tmpFileError->getFile()][$line]);
229-
}
230-
break;
231-
}
232-
}
233-
}
234-
235-
$locallyIgnoredErrors[] = $tmpFileError;
236-
continue 2;
237-
}
238-
}
239-
240-
$fileErrors[] = $tmpFileError;
179+
$localIgnoresProcessorResult = $this->localIgnoresProcessor->process(
180+
$temporaryFileErrors,
181+
$linesToIgnore,
182+
$unmatchedLineIgnores,
183+
);
184+
foreach ($localIgnoresProcessorResult->getFileErrors() as $fileError) {
185+
$fileErrors[] = $fileError;
186+
}
187+
foreach ($localIgnoresProcessorResult->getLocallyIgnoredErrors() as $locallyIgnoredError) {
188+
$locallyIgnoredErrors[] = $locallyIgnoredError;
241189
}
190+
$linesToIgnore = $localIgnoresProcessorResult->getLinesToIgnore();
191+
$unmatchedLineIgnores = $localIgnoresProcessorResult->getUnmatchedLineIgnores();
242192

243193
if ($this->reportUnmatchedIgnoredErrors) {
244194
foreach ($unmatchedLineIgnores as $ignoredFile => $lines) {
+101
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\Analyser;
4+
5+
use function array_key_exists;
6+
use function array_values;
7+
use function count;
8+
use function is_array;
9+
10+
/**
11+
* @phpstan-import-type LinesToIgnore from FileAnalyserResult
12+
*/
13+
class LocalIgnoresProcessor
14+
{
15+
16+
/**
17+
* @param list<Error> $temporaryFileErrors
18+
* @param LinesToIgnore $linesToIgnore
19+
* @param LinesToIgnore $unmatchedLineIgnores
20+
*/
21+
public function process(
22+
array $temporaryFileErrors,
23+
array $linesToIgnore,
24+
array $unmatchedLineIgnores,
25+
): LocalIgnoresProcessorResult
26+
{
27+
$fileErrors = [];
28+
$locallyIgnoredErrors = [];
29+
foreach ($temporaryFileErrors as $tmpFileError) {
30+
$line = $tmpFileError->getLine();
31+
if (
32+
$line !== null
33+
&& $tmpFileError->canBeIgnored()
34+
&& array_key_exists($tmpFileError->getFile(), $linesToIgnore)
35+
&& array_key_exists($line, $linesToIgnore[$tmpFileError->getFile()])
36+
) {
37+
$identifiers = $linesToIgnore[$tmpFileError->getFile()][$line];
38+
if ($identifiers === null) {
39+
$locallyIgnoredErrors[] = $tmpFileError;
40+
unset($unmatchedLineIgnores[$tmpFileError->getFile()][$line]);
41+
continue;
42+
}
43+
44+
if ($tmpFileError->getIdentifier() === null) {
45+
$fileErrors[] = $tmpFileError;
46+
continue;
47+
}
48+
49+
foreach ($identifiers as $i => $ignoredIdentifier) {
50+
if ($ignoredIdentifier !== $tmpFileError->getIdentifier()) {
51+
continue;
52+
}
53+
54+
unset($identifiers[$i]);
55+
56+
if (count($identifiers) > 0) {
57+
$linesToIgnore[$tmpFileError->getFile()][$line] = array_values($identifiers);
58+
} else {
59+
unset($linesToIgnore[$tmpFileError->getFile()][$line]);
60+
}
61+
62+
if (
63+
array_key_exists($tmpFileError->getFile(), $unmatchedLineIgnores)
64+
&& array_key_exists($line, $unmatchedLineIgnores[$tmpFileError->getFile()])
65+
) {
66+
$unmatchedIgnoredIdentifiers = $unmatchedLineIgnores[$tmpFileError->getFile()][$line];
67+
if (is_array($unmatchedIgnoredIdentifiers)) {
68+
foreach ($unmatchedIgnoredIdentifiers as $j => $unmatchedIgnoredIdentifier) {
69+
if ($ignoredIdentifier !== $unmatchedIgnoredIdentifier) {
70+
continue;
71+
}
72+
73+
unset($unmatchedIgnoredIdentifiers[$j]);
74+
75+
if (count($unmatchedIgnoredIdentifiers) > 0) {
76+
$unmatchedLineIgnores[$tmpFileError->getFile()][$line] = array_values($unmatchedIgnoredIdentifiers);
77+
} else {
78+
unset($unmatchedLineIgnores[$tmpFileError->getFile()][$line]);
79+
}
80+
break;
81+
}
82+
}
83+
}
84+
85+
$locallyIgnoredErrors[] = $tmpFileError;
86+
continue 2;
87+
}
88+
}
89+
90+
$fileErrors[] = $tmpFileError;
91+
}
92+
93+
return new LocalIgnoresProcessorResult(
94+
$fileErrors,
95+
$locallyIgnoredErrors,
96+
$linesToIgnore,
97+
$unmatchedLineIgnores,
98+
);
99+
}
100+
101+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\Analyser;
4+
5+
/**
6+
* @phpstan-import-type LinesToIgnore from FileAnalyserResult
7+
*/
8+
class LocalIgnoresProcessorResult
9+
{
10+
11+
/**
12+
* @param list<Error> $fileErrors
13+
* @param list<Error> $locallyIgnoredErrors
14+
* @param LinesToIgnore $linesToIgnore
15+
* @param LinesToIgnore $unmatchedLineIgnores
16+
*/
17+
public function __construct(
18+
private array $fileErrors,
19+
private array $locallyIgnoredErrors,
20+
private array $linesToIgnore,
21+
private array $unmatchedLineIgnores,
22+
)
23+
{
24+
}
25+
26+
/**
27+
* @return list<Error>
28+
*/
29+
public function getFileErrors(): array
30+
{
31+
return $this->fileErrors;
32+
}
33+
34+
/**
35+
* @return list<Error>
36+
*/
37+
public function getLocallyIgnoredErrors(): array
38+
{
39+
return $this->locallyIgnoredErrors;
40+
}
41+
42+
/**
43+
* @return LinesToIgnore
44+
*/
45+
public function getLinesToIgnore(): array
46+
{
47+
return $this->linesToIgnore;
48+
}
49+
50+
/**
51+
* @return LinesToIgnore
52+
*/
53+
public function getUnmatchedLineIgnores(): array
54+
{
55+
return $this->unmatchedLineIgnores;
56+
}
57+
58+
}

src/Testing/RuleTestCase.php

+2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use PHPStan\Analyser\AnalyserResultFinalizer;
88
use PHPStan\Analyser\Error;
99
use PHPStan\Analyser\FileAnalyser;
10+
use PHPStan\Analyser\LocalIgnoresProcessor;
1011
use PHPStan\Analyser\NodeScopeResolver;
1112
use PHPStan\Analyser\RuleErrorTransformer;
1213
use PHPStan\Analyser\TypeSpecifier;
@@ -110,6 +111,7 @@ private function getAnalyser(): Analyser
110111
$this->getParser(),
111112
self::getContainer()->getByType(DependencyResolver::class),
112113
new RuleErrorTransformer(),
114+
new LocalIgnoresProcessor(),
113115
true,
114116
);
115117
$this->analyser = new Analyser(

tests/PHPStan/Analyser/AnalyserTest.php

+1
Original file line numberDiff line numberDiff line change
@@ -715,6 +715,7 @@ private function createAnalyser(bool $reportUnmatchedIgnoredErrors, bool $enable
715715
),
716716
new DependencyResolver($fileHelper, $reflectionProvider, new ExportedNodeResolver($fileTypeMapper, new ExprPrinter(new Printer())), $fileTypeMapper),
717717
new RuleErrorTransformer(),
718+
new LocalIgnoresProcessor(),
718719
$reportUnmatchedIgnoredErrors,
719720
);
720721

0 commit comments

Comments
 (0)