Repository navigation
Fix ignoreErrors entries in NEON config files, remove ignores made stale by --fix-ignored - #6909
Merged
Merged
Conversation
… files PHPStan\Neon\Printer is a format-preserving printer of nette/neon syntax trees, inspired by the printers of nikic/php-parser and phpstan/phpdoc-parser. A tree is changed by replacing nodes with clones that keep the token positions of the original nodes; unchanged code is printed as it was written, with its comments and whitespace. Items of lists are compared with phpdoc-parser's Differ. The comment at the end of an item's line and the comment lines above an item belong to the item. nette/neon 3 marks its parser and syntax tree @internal, the composer.json pins it to one version, so the internalClass errors are ignored in the printer and the fixer. nette/neon 4, which made the API public, requires PHP 8.4. printChanges() returns only the changed ranges, unchanged code is referred to by token ranges and not copied, so a fix in the 6 MB NEON baseline of WordPress level 10 (31k entries) takes about 2 ms after a 1.9 s parse. 1,870 broken entries are fixed in one round. Removals of neighbouring items touch the same line and go in separate rounds, so a list is never left empty. Amp-Thread-ID: https://ampcode.com/threads/T-01a19bac-7181-7568-be9c-c7ec28db8ebc
Fixing an ignored error leaves behind the ignore that matched it: an unmatched ignoreErrors entry, a count that is too high, or an unmatched @PHPStan-Ignore comment. Those are reported errors, so --fix-ignored on its own did not fix them and the next run failed. The following rounds of --fix-ignored now also fix the fixable ignore.* errors in the files that the previous rounds changed. Stale ignores in other files were there before and are left alone. Amp-Thread-ID: https://ampcode.com/threads/T-01a19bac-7181-7568-be9c-c7ec28db8ebc
…and 8.1 The PHP 7.4 downgrade does not rewrite the nullsafe operator, and WeakMap does not exist there; the printer caches are arrays by spl_object_id() that keep the object, so its ID is not reused. PCRE of PHP < 8.2 does not accept a NUL byte in a pattern, only its escape. Amp-Thread-ID: https://ampcode.com/threads/T-01a19bac-7181-7568-be9c-c7ec28db8ebc
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Continues #6906.
--fixnow also fixesignore.unmatchedand too highignore.countin NEON config files, likephpstan-baseline.neon, and--fix-ignoredcleans up the ignores it makes stale.PHPStan\Neon\PrinterA format-preserving printer for nette/neon syntax trees, modelled on the printers of nikic/php-parser and phpstan/phpdoc-parser:
neware printed fresh.Differ, so items can be removed, added and reordered. The comment at the end of an item's line and the comment lines right above an item belong to the item. Inline arrays and entity attributes keep their separators. Removing every entry printsignoreErrors: [].printChanges()returns only the changed byte ranges. Unchanged code is referred to by token ranges and is not copied, so the cost depends on the size of the change, not of the file.\r. The fixer puts CRLF back when every line break had it, and does not fix files with mixed line endings.nette/neon stays at 3.3.4. Its parser and syntax tree are
@internal, so one scopedignoreErrorsentry inbuild/phpstan.neoncoverssrc/Neon, the fixer and the printer tests. nette/neon 4.0, which made the API public (nette/neon#52), requires PHP 8.4.Performance
Measured on the WordPress level 10 NEON baseline (30,989 entries, 6.2 MB), with 1,240 entries that no longer match and 620 counts that are too high. Printing the whole file for each fix took 53.9 s in total. With
printChanges()it takes 8.4 s, including a one-time 1.9 s parse, about 2 ms per fix. All 1,870 errors are fixed in one round, and the result equals the expected baseline byte for byte.Removing neighbouring items
A removal edit starts at the end of the previous item, so the edits for two neighbouring items touch the same line and
Patcherputs the second one into the next round. A list likemessages:is therefore never left empty, like with the PHP fixer.--fix-ignoredFixing an ignored error leaves behind the ignore that matched it: an unmatched
ignoreErrorsentry, a count that is too high, or an unmatched@phpstan-ignorecomment. These are reported errors, so--fix-ignoredon its own left them in place and the next run failed. Later rounds now also fix fixableignore.*errors in the files that earlier rounds changed. Stale ignores in other files were already there and are left alone. The main process passes the changed files to each round worker with an internal--fixed-ignored-inoption.Tests
tests/PHPStan/Neon/PrinterTest.php: each case checks the exact output, that it decodes to the same value, and thatprintChanges()gives the same result.IgnoreErrorsConfigFixerTest: NEON cases for entries with comments, list items, lowering a count,%%, CRLF, duplicate entries that aren't fixed, and neighbouring removals.e2e/fix-baselinenow also fixes a NEON baseline.e2e/fix-ignored-entriescovers a PHP baseline entry, a NEON count and an inline comment, plus a stale entry in an untouched file that must stay.e2e/fix: itsignoreErrorsentry moved into a copiedignore.neon, because--fix-ignorednow removes it.