diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml index 6a8715514d..dd5d3ba5d1 100644 --- a/.github/workflows/e2e-tests.yml +++ b/.github/workflows/e2e-tests.yml @@ -321,12 +321,17 @@ jobs: ../../bin/phpstan clear-result-cache OUTPUT=$(../bashunit -a exit_code "1" "../../bin/phpstan --error-format=raw") ../bashunit -a contains 'FooTrait.php:10:Strict comparison using === between int<0, max> and false will always evaluate to false.' "$OUTPUT" - # An ignoreErrors path may target the error by the trait file or by the using-class - # file - both keep working (no BC break). + # The deduplicated error is attributed to the trait file: an ignoreErrors path + # targeting the trait file matches, a using-class path does not - consistently + # with both an empty and a primed result cache. ../../bin/phpstan clear-result-cache ../bashunit -a exit_code "0" "../../bin/phpstan analyse --error-format=raw -c ignore-trait-path.neon" + ../bashunit -a exit_code "0" "../../bin/phpstan analyse --error-format=raw -c ignore-trait-path.neon" ../../bin/phpstan clear-result-cache - ../bashunit -a exit_code "0" "../../bin/phpstan analyse --error-format=raw -c ignore-class-path.neon" + OUTPUT=$(../bashunit -a exit_code "1" "../../bin/phpstan analyse --error-format=raw -c ignore-class-path.neon") + ../bashunit -a contains 'FooTrait.php:10:Strict comparison using === between int<0, max> and false will always evaluate to false.' "$OUTPUT" + OUTPUT=$(../bashunit -a exit_code "1" "../../bin/phpstan analyse --error-format=raw -c ignore-class-path.neon") + ../bashunit -a contains 'FooTrait.php:10:Strict comparison using === between int<0, max> and false will always evaluate to false.' "$OUTPUT" # A generated baseline suppresses the error on re-run, with both an empty and a # primed result cache (the issue reported baseline generation as impossible). ../../bin/phpstan --generate-baseline=baseline.neon diff --git a/build/baseline-8.0.neon b/build/baseline-8.0.neon index e249b3ce3e..29b3aedabd 100644 --- a/build/baseline-8.0.neon +++ b/build/baseline-8.0.neon @@ -22,4 +22,4 @@ parameters: message: '#^Strict comparison using \=\=\= between list\ and false will always evaluate to false\.$#' identifier: identical.alwaysFalse count: 1 - path: ../src/Type/Php/StrSplitFunctionReturnTypeExtension.php + path: ../src/Type/Php/MbFunctionsReturnTypeExtensionTrait.php diff --git a/src/Analyser/AnalyserResultFinalizer.php b/src/Analyser/AnalyserResultFinalizer.php index cc06cb3eee..dd7c560163 100644 --- a/src/Analyser/AnalyserResultFinalizer.php +++ b/src/Analyser/AnalyserResultFinalizer.php @@ -14,6 +14,7 @@ use function array_merge; use function count; use function get_class; +use function ksort; use function sprintf; #[AutowiredService] @@ -44,7 +45,9 @@ public function finalize(AnalyserResult $analyserResult, bool $onlyFiles, bool $ } $nodeType = CollectedDataNode::class; - $node = new CollectedDataNode($analyserResult->getCollectedData(), $onlyFiles); + $collectedData = $analyserResult->getCollectedData(); + ksort($collectedData); + $node = new CollectedDataNode($collectedData, $onlyFiles); $file = 'N/A'; $scope = $this->scopeFactory->create(ScopeContext::create($file)); diff --git a/src/Analyser/Error.php b/src/Analyser/Error.php index 526594ed2f..9ce4e26402 100644 --- a/src/Analyser/Error.php +++ b/src/Analyser/Error.php @@ -117,7 +117,7 @@ public function removeTraitContext(): self $this->traitFilePath, $this->line, $this->canBeIgnored, - $this->filePath, + $this->traitFilePath, $this->traitFilePath, $this->tip, $this->nodeLine, diff --git a/tests/PHPStan/Analyser/ErrorTest.php b/tests/PHPStan/Analyser/ErrorTest.php index d4408a741d..bf577ade9a 100644 --- a/tests/PHPStan/Analyser/ErrorTest.php +++ b/tests/PHPStan/Analyser/ErrorTest.php @@ -25,14 +25,19 @@ public function testRemoveTraitContextKeepsTraitFilePath(): void $withoutTraitContext = $error->removeTraitContext(); // The error is now reported directly in the trait: the displayed file is // the trait, and traitFilePath is kept so the editor URL and the - // trait-file ignore lookups resolve to the trait (#14718). filePath stays - // the using-class file, so an ignoreErrors path keyed on either the trait - // or the using-class file keeps matching (no BC break). + // trait-file ignore lookups resolve to the trait (#14718). $this->assertSame('trait.php', $withoutTraitContext->getFile()); - $this->assertSame('user.php', $withoutTraitContext->getFilePath()); $this->assertSame('trait.php', $withoutTraitContext->getTraitFilePath()); } + public function testRemoveTraitContextAttributesErrorToTraitFile(): void + { + $error = new Error('Message', 'trait.php (in context of class C)', 11, true, 'user.php', 'trait.php'); + + $withoutTraitContext = $error->removeTraitContext(); + $this->assertSame('trait.php', $withoutTraitContext->getFilePath()); + } + public static function dataValidIdentifier(): iterable { yield ['a'];