diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml index 329be6ea74a..252f9f1d792 100644 --- a/.github/workflows/e2e-tests.yml +++ b/.github/workflows/e2e-tests.yml @@ -246,6 +246,9 @@ jobs: - script: | cd e2e/bug-15231 ../../bin/phpstan analyze + - script: | + cd e2e/bug-15482 + ../../bin/phpstan analyse - script: | cd e2e/bug-15102 composer install diff --git a/e2e/bug-15482/phpstan.neon b/e2e/bug-15482/phpstan.neon new file mode 100644 index 00000000000..309bd4f85b3 --- /dev/null +++ b/e2e/bug-15482/phpstan.neon @@ -0,0 +1,4 @@ +parameters: + level: max + paths: + - src diff --git a/e2e/bug-15482/src/a_usage.php b/e2e/bug-15482/src/a_usage.php new file mode 100644 index 00000000000..4e09d378683 --- /dev/null +++ b/e2e/bug-15482/src/a_usage.php @@ -0,0 +1,3 @@ +typeConfig[$char])) { $type = $this->typeConfig[$char]; - if (substr($this->contents, $this->index, $type['length']) === $type['name']) { + if ( + substr($this->contents, $this->index, $type['length']) === $type['name'] + && $this->match('~.\\b(?])' . $type['name'] . '\\b~Ais', $match, $this->index - 1) + ) { if ($maxMatches === 1 && $this->match($type['pattern'], $match, $this->index - 1)) { return $clean . $match[0]; } diff --git a/tests/PHPStan/Reflection/BetterReflection/SourceLocator/SymbolFinderInFilesTest.php b/tests/PHPStan/Reflection/BetterReflection/SourceLocator/SymbolFinderInFilesTest.php index 7667289b78b..9183c3573b1 100644 --- a/tests/PHPStan/Reflection/BetterReflection/SourceLocator/SymbolFinderInFilesTest.php +++ b/tests/PHPStan/Reflection/BetterReflection/SourceLocator/SymbolFinderInFilesTest.php @@ -13,6 +13,15 @@ final class SymbolFinderInFilesTest extends PHPStanTestCase */ public static function dataFindSymbols(): iterable { + yield 'class name expressions do not hide later global constants' => [ + __DIR__ . '/data/symbol-finder/class-name-before-global-constant.php', + [ + [], + ['symbolfinderclassname', 'classname', 'symbolfinderanonymousclass', 'symbolfindernamedargument', 'symbolfindernamedargumentcall', 'symbolfinderspacedclassconstant'], + ['AFTER_CLASS_NAME', 'AFTER_CLASS_PREFIX', 'AFTER_ANONYMOUS_CLASS', 'AFTER_NAMED_CLASS_ARGUMENT', 'AFTER_SPACED_CLASS_CONSTANT'], + ], + ]; + yield 'namespaced constants do not leak a class entry' => [ __DIR__ . '/data/symbol-finder/namespaced-constants.php', [ diff --git a/tests/PHPStan/Reflection/BetterReflection/SourceLocator/data/symbol-finder/class-name-before-global-constant.php b/tests/PHPStan/Reflection/BetterReflection/SourceLocator/data/symbol-finder/class-name-before-global-constant.php new file mode 100644 index 00000000000..9f1435d10c4 --- /dev/null +++ b/tests/PHPStan/Reflection/BetterReflection/SourceLocator/data/symbol-finder/class-name-before-global-constant.php @@ -0,0 +1,43 @@ + "\n\n " "class;\n", + 'class name before global constant' => " " " "just text, no php at all\n", diff --git a/turbo-ext/tests/symbol-finder-corpus.php b/turbo-ext/tests/symbol-finder-corpus.php index 22a356a3f28..4b2895e6c0f 100644 --- a/turbo-ext/tests/symbol-finder-corpus.php +++ b/turbo-ext/tests/symbol-finder-corpus.php @@ -64,6 +64,7 @@ 'interface const' => " " " " " " "