Skip to content

Commit 842777b

Browse files
authored
Merge branch refs/heads/2.1.x into 2.2.x
2 parents fe05703 + f1e8852 commit 842777b

File tree

12 files changed

+58
-177
lines changed

12 files changed

+58
-177
lines changed

conf/config.neon

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,6 @@ parameters:
118118
resolvedPhpDocBlockCacheCountMax: 2048
119119
nameScopeMapMemoryCacheCountMax: 2048
120120
reportUnmatchedIgnoredErrors: true
121-
reportIgnoresWithoutComments: false
122121
typeAliases: []
123122
universalObjectCratesClasses:
124123
- stdClass
@@ -227,7 +226,6 @@ parameters:
227226
- [parameters, errorFormat]
228227
- [parameters, ignoreErrors]
229228
- [parameters, reportUnmatchedIgnoredErrors]
230-
- [parameters, reportIgnoresWithoutComments]
231229
- [parameters, tipsOfTheDay]
232230
- [parameters, parallel]
233231
- [parameters, internalErrorsCountLimit]

conf/parametersSchema.neon

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,6 @@ parametersSchema:
143143
nameScopeMapMemoryCacheCountMax: int()
144144
])
145145
reportUnmatchedIgnoredErrors: bool()
146-
reportIgnoresWithoutComments: bool()
147146
typeAliases: arrayOf(string())
148147
universalObjectCratesClasses: listOf(string())
149148
stubFiles: listOf(string())

src/Analyser/AnalyserResultFinalizer.php

Lines changed: 9 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -28,18 +28,19 @@ public function __construct(
2828
private LocalIgnoresProcessor $localIgnoresProcessor,
2929
#[AutowiredParameter]
3030
private bool $reportUnmatchedIgnoredErrors,
31-
#[AutowiredParameter]
32-
private bool $reportIgnoresWithoutComments,
3331
)
3432
{
3533
}
3634

3735
public function finalize(AnalyserResult $analyserResult, bool $onlyFiles, bool $debug): FinalizerResult
3836
{
39-
$hasCollectedData = count($analyserResult->getCollectedData()) > 0;
37+
if (count($analyserResult->getCollectedData()) === 0) {
38+
return $this->addUnmatchedIgnoredErrors($this->mergeFilteredPhpErrors($analyserResult), [], []);
39+
}
40+
4041
$hasInternalErrors = count($analyserResult->getInternalErrors()) > 0 || $analyserResult->hasReachedInternalErrorsCountLimit();
41-
if (! $hasCollectedData || $hasInternalErrors) {
42-
return $this->addUnmatchedIgnoredErrors($this->addIgnoresWithoutCommentErrors($this->mergeFilteredPhpErrors($analyserResult)), [], []);
42+
if ($hasInternalErrors) {
43+
return $this->addUnmatchedIgnoredErrors($this->mergeFilteredPhpErrors($analyserResult), [], []);
4344
}
4445

4546
$nodeType = CollectedDataNode::class;
@@ -133,7 +134,7 @@ public function finalize(AnalyserResult $analyserResult, bool $onlyFiles, bool $
133134
$allUnmatchedLineIgnores[$file] = $localIgnoresProcessorResult->getUnmatchedLineIgnores();
134135
}
135136

136-
return $this->addUnmatchedIgnoredErrors($this->addIgnoresWithoutCommentErrors(new AnalyserResult(
137+
return $this->addUnmatchedIgnoredErrors(new AnalyserResult(
137138
unorderedErrors: array_merge($errors, $analyserResult->getFilteredPhpErrors()),
138139
filteredPhpErrors: [],
139140
allPhpErrors: $analyserResult->getAllPhpErrors(),
@@ -147,7 +148,7 @@ public function finalize(AnalyserResult $analyserResult, bool $onlyFiles, bool $
147148
exportedNodes: $analyserResult->getExportedNodes(),
148149
reachedInternalErrorsCountLimit: $analyserResult->hasReachedInternalErrorsCountLimit(),
149150
peakMemoryUsageBytes: $analyserResult->getPeakMemoryUsageBytes(),
150-
)), $collectorErrors, $locallyIgnoredCollectorErrors);
151+
), $collectorErrors, $locallyIgnoredCollectorErrors);
151152
}
152153

153154
private function mergeFilteredPhpErrors(AnalyserResult $analyserResult): AnalyserResult
@@ -204,7 +205,7 @@ private function addUnmatchedIgnoredErrors(
204205

205206
foreach ($identifiers as $identifier) {
206207
$errors[] = (new Error(
207-
sprintf('No error with identifier %s is reported on line %d.', $identifier['name'], $line),
208+
sprintf('No error with identifier %s is reported on line %d.', $identifier, $line),
208209
$file,
209210
$line,
210211
false,
@@ -236,59 +237,4 @@ private function addUnmatchedIgnoredErrors(
236237
);
237238
}
238239

239-
private function addIgnoresWithoutCommentErrors(AnalyserResult $analyserResult): AnalyserResult
240-
{
241-
if (!$this->reportIgnoresWithoutComments) {
242-
return $analyserResult;
243-
}
244-
245-
$errors = $analyserResult->getUnorderedErrors();
246-
foreach ($analyserResult->getLinesToIgnore() as $file => $data) {
247-
foreach ($data as $ignoredFile => $lines) {
248-
if ($ignoredFile !== $file) {
249-
continue;
250-
}
251-
252-
foreach ($lines as $line => $identifiers) {
253-
if ($identifiers === null) {
254-
continue;
255-
}
256-
257-
foreach ($identifiers as $identifier) {
258-
['name' => $name, 'comment' => $comment] = $identifier;
259-
if ($comment !== null) {
260-
continue;
261-
}
262-
263-
$errors[] = (new Error(
264-
sprintf('Ignore with identifier %s has no comment.', $name),
265-
$file,
266-
$line,
267-
false,
268-
$file,
269-
null,
270-
'Explain why this ignore is necessary in parentheses after the identifier.',
271-
))->withIdentifier('ignore.noComment');
272-
}
273-
}
274-
}
275-
}
276-
277-
return new AnalyserResult(
278-
$errors,
279-
$analyserResult->getFilteredPhpErrors(),
280-
$analyserResult->getAllPhpErrors(),
281-
$analyserResult->getLocallyIgnoredErrors(),
282-
$analyserResult->getLinesToIgnore(),
283-
$analyserResult->getUnmatchedLineIgnores(),
284-
$analyserResult->getInternalErrors(),
285-
$analyserResult->getCollectedData(),
286-
$analyserResult->getDependencies(),
287-
$analyserResult->getUsedTraitDependencies(),
288-
$analyserResult->getExportedNodes(),
289-
$analyserResult->hasReachedInternalErrorsCountLimit(),
290-
$analyserResult->getPeakMemoryUsageBytes(),
291-
);
292-
}
293-
294240
}

src/Analyser/FileAnalyserCallback.php

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121

2222
/**
2323
* @phpstan-import-type CollectorData from CollectedData
24-
* @phpstan-import-type Identifier from FileAnalyserResult
2524
* @phpstan-import-type LinesToIgnore from FileAnalyserResult
2625
*/
2726
final class FileAnalyserCallback
@@ -232,15 +231,15 @@ public function __invoke(Node $node, Scope $scope): void
232231

233232
/**
234233
* @param Node[] $nodes
235-
* @return array<int, non-empty-list<Identifier>|null>
234+
* @return array<int, non-empty-list<string>|null>
236235
*/
237236
private function getLinesToIgnoreFromTokens(array $nodes): array
238237
{
239238
if (!isset($nodes[0])) {
240239
return [];
241240
}
242241

243-
/** @var array<int, non-empty-list<Identifier>|null> */
242+
/** @var array<int, non-empty-list<string>|null> */
244243
return $nodes[0]->getAttribute('linesToIgnore', []);
245244
}
246245

src/Analyser/FileAnalyserResult.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@
66
use PHPStan\Dependency\RootExportedNode;
77

88
/**
9-
* @phpstan-type Identifier = array{name: string, comment: string|null}
10-
* @phpstan-type LinesToIgnore = array<string, array<int, non-empty-list<Identifier>|null>>
9+
* @phpstan-type LinesToIgnore = array<string, array<int, non-empty-list<string>|null>>
1110
* @phpstan-import-type CollectorData from CollectedData
1211
*/
1312
final class FileAnalyserResult

src/Analyser/LocalIgnoresProcessor.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ public function process(
4949
}
5050

5151
foreach ($identifiers as $i => $ignoredIdentifier) {
52-
if ($ignoredIdentifier['name'] !== $tmpFileError->getIdentifier()) {
52+
if ($ignoredIdentifier !== $tmpFileError->getIdentifier()) {
5353
continue;
5454
}
5555

@@ -68,7 +68,7 @@ public function process(
6868
$unmatchedIgnoredIdentifiers = $unmatchedLineIgnores[$tmpFileError->getFile()][$line];
6969
if (is_array($unmatchedIgnoredIdentifiers)) {
7070
foreach ($unmatchedIgnoredIdentifiers as $j => $unmatchedIgnoredIdentifier) {
71-
if ($ignoredIdentifier['name'] !== $unmatchedIgnoredIdentifier['name']) {
71+
if ($ignoredIdentifier !== $unmatchedIgnoredIdentifier) {
7272
continue;
7373
}
7474

src/Command/FixerWorkerCommand.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,7 @@ function (array $errors, array $locallyIgnoredErrors, array $analysedFiles) use
313313
if ($error->getIdentifier() === null) {
314314
continue;
315315
}
316-
if (!in_array($error->getIdentifier(), ['ignore.count', 'ignore.unmatched', 'ignore.unmatchedLine', 'ignore.unmatchedIdentifier', 'ignore.noComment'], true)) {
316+
if (!in_array($error->getIdentifier(), ['ignore.count', 'ignore.unmatched', 'ignore.unmatchedLine', 'ignore.unmatchedIdentifier'], true)) {
317317
continue;
318318
}
319319
$ignoreFileErrors[] = $error;

src/Parser/RichParser.php

Lines changed: 14 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,12 @@
77
use PhpParser\NodeTraverser;
88
use PhpParser\NodeVisitor\NameResolver;
99
use PhpParser\Token;
10-
use PHPStan\Analyser\FileAnalyserResult;
1110
use PHPStan\Analyser\Ignore\IgnoreLexer;
1211
use PHPStan\Analyser\Ignore\IgnoreParseException;
1312
use PHPStan\DependencyInjection\Container;
1413
use PHPStan\File\FileReader;
1514
use PHPStan\ShouldNotHappenException;
1615
use function array_filter;
17-
use function array_key_last;
1816
use function array_map;
1917
use function count;
2018
use function implode;
@@ -32,9 +30,6 @@
3230
use const T_DOC_COMMENT;
3331
use const T_WHITESPACE;
3432

35-
/**
36-
* @phpstan-import-type Identifier from FileAnalyserResult
37-
*/
3833
final class RichParser implements Parser
3934
{
4035

@@ -125,7 +120,7 @@ public function parseString(string $sourceCode): array
125120

126121
/**
127122
* @param Token[] $tokens
128-
* @return array{lines: array<int, non-empty-list<Identifier>|null>, errors: array<int, non-empty-list<string>>}
123+
* @return array{lines: array<int, non-empty-list<string>|null>, errors: array<int, non-empty-list<string>>}
129124
*/
130125
private function getLinesToIgnore(array $tokens): array
131126
{
@@ -282,29 +277,33 @@ private function getLinesToIgnoreForTokenByIgnoreComment(
282277
}
283278

284279
/**
285-
* @return non-empty-list<Identifier>
280+
* @return non-empty-list<string>
286281
* @throws IgnoreParseException
287282
*/
288283
private function parseIdentifiers(string $text, int $ignorePos): array
289284
{
290285
$text = substr($text, $ignorePos + strlen('@phpstan-ignore'));
291-
$tokens = $this->ignoreLexer->tokenize($text);
286+
$originalTokens = $this->ignoreLexer->tokenize($text);
287+
$tokens = [];
288+
289+
foreach ($originalTokens as $originalToken) {
290+
if ($originalToken[IgnoreLexer::TYPE_OFFSET] === IgnoreLexer::TOKEN_WHITESPACE) {
291+
continue;
292+
}
293+
$tokens[] = $originalToken;
294+
}
292295

293296
$c = count($tokens);
294297

295298
$identifiers = [];
296-
$comment = null;
297299
$openParenthesisCount = 0;
298300
$expected = [IgnoreLexer::TOKEN_IDENTIFIER];
299-
$lastTokenTypeLabel = '@phpstan-ignore';
300301

301302
for ($i = 0; $i < $c; $i++) {
302-
if (isset($tokenType) && $tokenType !== IgnoreLexer::TOKEN_WHITESPACE) {
303-
$lastTokenTypeLabel = $this->ignoreLexer->getLabel($tokenType);
304-
}
303+
$lastTokenTypeLabel = isset($tokenType) ? $this->ignoreLexer->getLabel($tokenType) : '@phpstan-ignore';
305304
[IgnoreLexer::VALUE_OFFSET => $content, IgnoreLexer::TYPE_OFFSET => $tokenType, IgnoreLexer::LINE_OFFSET => $tokenLine] = $tokens[$i];
306305

307-
if ($expected !== null && !in_array($tokenType, [...$expected, IgnoreLexer::TOKEN_WHITESPACE], true)) {
306+
if ($expected !== null && !in_array($tokenType, $expected, true)) {
308307
$tokenTypeLabel = $this->ignoreLexer->getLabel($tokenType);
309308
$otherTokenContent = $tokenType === IgnoreLexer::TOKEN_OTHER ? sprintf(" '%s'", $content) : '';
310309
$expectedLabels = implode(' or ', array_map(fn ($token) => $this->ignoreLexer->getLabel($token), $expected));
@@ -313,9 +312,6 @@ private function parseIdentifiers(string $text, int $ignorePos): array
313312
}
314313

315314
if ($tokenType === IgnoreLexer::TOKEN_OPEN_PARENTHESIS) {
316-
if ($openParenthesisCount > 0) {
317-
$comment .= $content;
318-
}
319315
$openParenthesisCount++;
320316
$expected = null;
321317
continue;
@@ -324,25 +320,17 @@ private function parseIdentifiers(string $text, int $ignorePos): array
324320
if ($tokenType === IgnoreLexer::TOKEN_CLOSE_PARENTHESIS) {
325321
$openParenthesisCount--;
326322
if ($openParenthesisCount === 0) {
327-
$key = array_key_last($identifiers);
328-
if ($key !== null) {
329-
$identifiers[$key]['comment'] = $comment;
330-
$comment = null;
331-
}
332323
$expected = [IgnoreLexer::TOKEN_COMMA, IgnoreLexer::TOKEN_END];
333-
} else {
334-
$comment .= $content;
335324
}
336325
continue;
337326
}
338327

339328
if ($openParenthesisCount > 0) {
340-
$comment .= $content;
341329
continue; // waiting for comment end
342330
}
343331

344332
if ($tokenType === IgnoreLexer::TOKEN_IDENTIFIER) {
345-
$identifiers[] = ['name' => $content, 'comment' => null];
333+
$identifiers[] = $content;
346334
$expected = [IgnoreLexer::TOKEN_COMMA, IgnoreLexer::TOKEN_END, IgnoreLexer::TOKEN_OPEN_PARENTHESIS];
347335
continue;
348336
}
@@ -361,7 +349,6 @@ private function parseIdentifiers(string $text, int $ignorePos): array
361349
throw new IgnoreParseException('Missing identifier', 1);
362350
}
363351

364-
/** @phpstan-ignore return.type (return type is correct, not sure why it's being changed from array shape to key-value shape) */
365352
return $identifiers;
366353
}
367354

src/Testing/RuleTestCase.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,6 @@ private function gatherAnalyserErrorsWithDelayedErrors(array $files): array
327327
self::createScopeFactory($reflectionProvider, self::getContainer()->getService('typeSpecifier')),
328328
new LocalIgnoresProcessor(),
329329
true,
330-
false,
331330
);
332331

333332
return [

tests/PHPStan/Analyser/AnalyserTest.php

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -638,28 +638,6 @@ public function testIgnoreNextLineUnmatched(): void
638638
}
639639
}
640640

641-
#[DataProvider('dataTrueAndFalse')]
642-
public function testIgnoresWithoutCommentsReported(): void
643-
{
644-
$expects = [
645-
[9, 'variable.undefined'],
646-
[12, 'variable.undefined'],
647-
[12, 'wrong.id'],
648-
[13, 'wrong.id'],
649-
[14, 'variable.undefined'],
650-
];
651-
$result = $this->runAnalyser([], false, [
652-
__DIR__ . '/data/ignore-no-comments.php',
653-
], true, true);
654-
$this->assertCount(5, $result);
655-
foreach ($expects as $i => $expect) {
656-
$this->assertArrayHasKey($i, $result);
657-
$this->assertInstanceOf(Error::class, $result[$i]);
658-
$this->assertStringContainsString(sprintf('Ignore with identifier %s has no comment.', $expect[1]), $result[$i]->getMessage());
659-
$this->assertSame($expect[0], $result[$i]->getLine());
660-
}
661-
}
662-
663641
#[DataProvider('dataTrueAndFalse')]
664642
public function testIgnoreLine(bool $reportUnmatchedIgnoredErrors): void
665643
{
@@ -769,7 +747,6 @@ private function runAnalyser(
769747
bool $reportUnmatchedIgnoredErrors,
770748
$filePaths,
771749
bool $onlyFiles,
772-
bool $reportIgnoresWithoutComments = false,
773750
): array
774751
{
775752
$analyser = $this->createAnalyser();
@@ -802,7 +779,6 @@ private function runAnalyser(
802779
),
803780
new LocalIgnoresProcessor(),
804781
$reportUnmatchedIgnoredErrors,
805-
$reportIgnoresWithoutComments,
806782
);
807783
$analyserResult = $finalizer->finalize($analyserResult, $onlyFiles, false)->getAnalyserResult();
808784

0 commit comments

Comments
 (0)