diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml index f5989b740b8..cc795e63757 100644 --- a/.github/workflows/e2e-tests.yml +++ b/.github/workflows/e2e-tests.yml @@ -297,6 +297,22 @@ jobs: ../bashunit -a contains 'FooTrait.php:10:Strict comparison using === between int<0, max> and false will always evaluate to false.' "$OUTPUT" ../bashunit -a contains 'FooTrait.php (in context of class E2EInTrait\Bar):18:Strict comparison using === between E2EInTrait\Bar and null will always evaluate to false.' "$OUTPUT" ../bashunit -a contains 'FooTrait.php (in context of class E2EInTrait\Foo):18:Strict comparison using === between E2EInTrait\Foo and null will always evaluate to false.' "$OUTPUT" + - script: | + cd e2e/bug-14718 + # https://github.com/phpstan/phpstan/issues/14718 + # an inline @phpstan-ignore on an error deduplicated into the trait must suppress it, + # consistently with both an empty and a primed result cache + ../../bin/phpstan clear-result-cache + ../bashunit -a exit_code "0" "../../bin/phpstan --error-format=raw" + ../bashunit -a exit_code "0" "../../bin/phpstan --error-format=raw" + # with the ignore removed, the error is reported in the trait file and a generated + # baseline records the trait file path, not the using-class file + sed -i 's# // @phpstan-ignore identical.alwaysFalse##' src/FooTrait.php + ../../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" + ../../bin/phpstan --generate-baseline=baseline.neon + ../bashunit -a contains 'path: src/FooTrait.php' "$(cat baseline.neon)" - script: | cd e2e/result-cache-meta-extension composer install diff --git a/build/baseline-8.0.neon b/build/baseline-8.0.neon index e249b3ce3e6..29b3aedabd3 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/e2e/bug-14718/phpstan.neon b/e2e/bug-14718/phpstan.neon new file mode 100644 index 00000000000..c308dcf5421 --- /dev/null +++ b/e2e/bug-14718/phpstan.neon @@ -0,0 +1,4 @@ +parameters: + level: 8 + paths: + - src diff --git a/e2e/bug-14718/src/Bar.php b/e2e/bug-14718/src/Bar.php new file mode 100644 index 00000000000..11a8023e727 --- /dev/null +++ b/e2e/bug-14718/src/Bar.php @@ -0,0 +1,10 @@ +traitFilePath, $this->line, $this->canBeIgnored, - $this->filePath, + $this->traitFilePath, null, $this->tip, $this->nodeLine, diff --git a/tests/PHPStan/Analyser/ErrorTest.php b/tests/PHPStan/Analyser/ErrorTest.php index e59abafff36..6f88d692f59 100644 --- a/tests/PHPStan/Analyser/ErrorTest.php +++ b/tests/PHPStan/Analyser/ErrorTest.php @@ -16,6 +16,20 @@ public function testError(): void $this->assertSame(10, $error->getLine()); } + public function testRemoveTraitContextUsesTraitFileAsFilePath(): void + { + $error = new Error('Message', 'trait.php (in context of class C)', 11, true, 'user.php', 'trait.php'); + $this->assertSame('user.php', $error->getFilePath()); + $this->assertSame('trait.php', $error->getTraitFilePath()); + + $withoutTraitContext = $error->removeTraitContext(); + $this->assertSame('trait.php', $withoutTraitContext->getFile()); + // filePath must follow the file onto the trait, otherwise editor URLs and + // inline ignore-comment lookups point at the using-class file (#14718). + $this->assertSame('trait.php', $withoutTraitContext->getFilePath()); + $this->assertNull($withoutTraitContext->getTraitFilePath()); + } + public static function dataValidIdentifier(): iterable { yield ['a'];