Report unmatched baseline ignore rules when the origin trait file was analysed#5477
Report unmatched baseline ignore rules when the origin trait file was analysed#5477sylfabre wants to merge 2 commits intophpstan:2.2.xfrom
Conversation
|
You've opened the pull request against the latest branch 2.2.x. PHPStan 2.2 is not going to be released for months. If your code is relevant on 2.1.x and you want it to be released sooner, please rebase your pull request and change its target to 2.1.x. |
580698a to
3a59aa8
Compare
…ed rules when origin is analysed When an ignore rule has a specific path and an origin (the trait file where the error actually originates), PHPStan can now determine whether the origin file was part of the analysis. If both path and origin were analysed and the rule was still unmatched, it is now reported — fixing a gap where unmatched baseline entries were silently suppressed in onlyFiles mode even when PHPStan had full information. Baseline formatters (NEON and PHP) now emit an `origin` field for errors that come from trait files, so baseline entries carry the necessary context for this check. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
3a59aa8 to
bf1517a
Compare
…atches When an error message appears multiple times in the same file (e.g. once directly and once from a trait), grouping by message+origin created separate baseline entries that both tried to match the same errors, causing 'expected N, occurred M' count overflows. Group by message only (restoring original behaviour). Track per-group origins and emit 'origin' only when all errors in the group share the same non-null trait file path. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
This does not seem right.
It doesn't have enough information. Let's say you're ignoring something in My rule of thumb: do not ever analyse only specific files when you can and should analyse the whole project: https://phpstan.org/blog/why-you-should-always-analyse-whole-project |
Problem
When
reportUnmatchedIgnoredErrors: trueand PHPStan runs inonlyFilesmode (incremental analysis), unmatched ignore rules with a specificpathare silently suppressed — even when PHPStan has enough information to know the rule is genuinely unmatched.Background
phpstan/phpstan#3099 reported false positives where unmatched path-specific ignore rules were reported even though the relevant file was never part of the analysis. This was fixed in c9df2f4 by skipping unmatched rules when the path was not in the analysed file set, and by unconditionally suppressing all path-specific unmatched rules in
onlyFilesmode.The unconditional suppression prevents a real false positive with trait errors: a trait error is attributed to the class file (
Foo.php) but only surfaces when the trait file (FooTrait.php) is part of the analysis. In partial analysis withoutFooTrait.php, the baseline rule goes unmatched for a legitimate reason and must be suppressed.However, this blanket suppression also means that when
FooTrait.phpwas analysed and the rule still didn't match, the unmatched rule is silently swallowed — even though PHPStan has full information to report it correctly.Solution
Introduce an
originfield in baseline entries for errors that originate from a trait file (Error::getTraitFilePath()). This field records which file must be present in the analysis for the error to appear.In
IgnoredErrorHelperResult::process(), when an unmatched rule has arealOrigin:For rules without
origin(user-written rules, non-trait baseline entries), the existingonlyFilessuppression is preserved unchanged.Changes
BaselineNeonErrorFormatter/BaselinePhpErrorFormatter: emitoriginfor errors with a trait file path, grouped by(message, origin)so distinct trait sources produce separate entriesIgnoredErrorHelper: includeoriginin the deduplication key; normaliseorigin→realOriginalongsidepath→realPathIgnoredErrorHelperResult: checkrealOriginagainstanalysedFilesKeysbefore deciding whether to suppress an unmatched rule inonlyFilesmodeAnalyserTest: two new test cases — withoutorigin(suppressed, existing behaviour preserved) and withoriginwhere both files are analysed (reported, new behaviour)