From 92ad9d2026d940cf57f23607d26f4be7714128ac Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Mon, 25 Nov 2024 13:22:10 +0100 Subject: [PATCH 1/4] Scope: fix getPhpVersion() in non-namespaced files --- src/Analyser/MutatingScope.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Analyser/MutatingScope.php b/src/Analyser/MutatingScope.php index 832c73b1c0..b7a2bacd93 100644 --- a/src/Analyser/MutatingScope.php +++ b/src/Analyser/MutatingScope.php @@ -5728,15 +5728,15 @@ public function getIterableValueType(Type $iteratee): Type public function getPhpVersion(): PhpVersions { - $versionExpr = new ConstFetch(new Name('PHP_VERSION_ID')); - if (!$this->hasExpressionType($versionExpr)->yes()) { + $name = new Name('PHP_VERSION_ID'); + if (!$this->hasConstant($name)) { if (is_array($this->configPhpVersion)) { return new PhpVersions(IntegerRangeType::fromInterval($this->configPhpVersion['min'], $this->configPhpVersion['max'])); } return new PhpVersions(new ConstantIntegerType($this->phpVersion->getVersionId())); } - return new PhpVersions($this->getType($versionExpr)); + return new PhpVersions($this->getType(new ConstFetch($name))); } } From a2aeea1654146a8ea711b8996ad3b9d7916ae005 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Mon, 25 Nov 2024 14:20:56 +0100 Subject: [PATCH 2/4] fix --- src/Analyser/MutatingScope.php | 40 +++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/src/Analyser/MutatingScope.php b/src/Analyser/MutatingScope.php index b7a2bacd93..cadd4761f4 100644 --- a/src/Analyser/MutatingScope.php +++ b/src/Analyser/MutatingScope.php @@ -610,12 +610,7 @@ public function hasConstant(Name $name): bool return $this->fileHasCompilerHaltStatementCalls(); } - if (!$name->isFullyQualified() && $this->getNamespace() !== null) { - if ($this->hasExpressionType(new ConstFetch(new FullyQualified([$this->getNamespace(), $name->toString()])))->yes()) { - return true; - } - } - if ($this->hasExpressionType(new ConstFetch(new FullyQualified($name->toString())))->yes()) { + if ($this->getGlobalConstantType($name) !== null) { return true; } @@ -5686,6 +5681,25 @@ private function getConstantTypes(): array return $constantTypes; } + private function getGlobalConstantType(Name $name): ?Type + { + $fetches = []; + if (!$name->isFullyQualified() && $this->getNamespace() !== null) { + $fetches[] = new ConstFetch(new FullyQualified([$this->getNamespace(), $name->toString()])); + } + + $fetches[] = new ConstFetch(new FullyQualified($name->toString())); + $fetches[] = new ConstFetch($name); + + foreach($fetches as $constFetch) { + if ($this->hasExpressionType($constFetch)->yes()) { + return $this->getType($constFetch); + } + } + + return null; + } + /** * @return array */ @@ -5728,15 +5742,15 @@ public function getIterableValueType(Type $iteratee): Type public function getPhpVersion(): PhpVersions { - $name = new Name('PHP_VERSION_ID'); - if (!$this->hasConstant($name)) { - if (is_array($this->configPhpVersion)) { - return new PhpVersions(IntegerRangeType::fromInterval($this->configPhpVersion['min'], $this->configPhpVersion['max'])); - } - return new PhpVersions(new ConstantIntegerType($this->phpVersion->getVersionId())); + $constType = $this->getGlobalConstantType(new Name('PHP_VERSION_ID')); + if ($constType !== null) { + return new PhpVersions($constType); } - return new PhpVersions($this->getType(new ConstFetch($name))); + if (is_array($this->configPhpVersion)) { + return new PhpVersions(IntegerRangeType::fromInterval($this->configPhpVersion['min'], $this->configPhpVersion['max'])); + } + return new PhpVersions(new ConstantIntegerType($this->phpVersion->getVersionId())); } } From 631145a326530c3d689fc7762650d750a66cd807 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Mon, 25 Nov 2024 19:50:19 +0100 Subject: [PATCH 3/4] test --- src/Analyser/MutatingScope.php | 2 +- src/Php/PhpVersions.php | 5 +++ .../PHPStan/Analyser/ScopePhpVersionTest.php | 39 +++++++++++++++++++ .../Analyser/data/global-scope-constants.php | 9 +++++ 4 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 tests/PHPStan/Analyser/ScopePhpVersionTest.php create mode 100644 tests/PHPStan/Analyser/data/global-scope-constants.php diff --git a/src/Analyser/MutatingScope.php b/src/Analyser/MutatingScope.php index cadd4761f4..f883c95578 100644 --- a/src/Analyser/MutatingScope.php +++ b/src/Analyser/MutatingScope.php @@ -5691,7 +5691,7 @@ private function getGlobalConstantType(Name $name): ?Type $fetches[] = new ConstFetch(new FullyQualified($name->toString())); $fetches[] = new ConstFetch($name); - foreach($fetches as $constFetch) { + foreach ($fetches as $constFetch) { if ($this->hasExpressionType($constFetch)->yes()) { return $this->getType($constFetch); } diff --git a/src/Php/PhpVersions.php b/src/Php/PhpVersions.php index 74474b28b0..229dccb72d 100644 --- a/src/Php/PhpVersions.php +++ b/src/Php/PhpVersions.php @@ -18,6 +18,11 @@ public function __construct( { } + public function getType(): Type + { + return $this->phpVersions; + } + public function supportsNoncapturingCatches(): TrinaryLogic { return IntegerRangeType::fromInterval(80000, null)->isSuperTypeOf($this->phpVersions)->result; diff --git a/tests/PHPStan/Analyser/ScopePhpVersionTest.php b/tests/PHPStan/Analyser/ScopePhpVersionTest.php new file mode 100644 index 0000000000..8f4fc492b2 --- /dev/null +++ b/tests/PHPStan/Analyser/ScopePhpVersionTest.php @@ -0,0 +1,39 @@ +', + __DIR__ . '/data/global-scope-constants.php', + ], + ]; + } + + /** + * @dataProvider dataTestPhpVersion + */ + public function testPhpVersion(string $expected, string $file): void + { + self::processFile($file, function (Node $node, Scope $scope) use ($expected): void { + if (!($node instanceof Exit_)) { + return; + } + $this->assertSame( + $expected, + $scope->getPhpVersion()->getType()->describe(VerbosityLevel::precise()), + ); + }); + } + +} diff --git a/tests/PHPStan/Analyser/data/global-scope-constants.php b/tests/PHPStan/Analyser/data/global-scope-constants.php new file mode 100644 index 0000000000..56eba41c9a --- /dev/null +++ b/tests/PHPStan/Analyser/data/global-scope-constants.php @@ -0,0 +1,9 @@ + Date: Tue, 26 Nov 2024 14:49:30 +0100 Subject: [PATCH 4/4] added namespaced test --- tests/PHPStan/Analyser/ScopePhpVersionTest.php | 6 +++++- ...al-scope-constants.php => scope-constants-global.php} | 0 .../PHPStan/Analyser/data/scope-constants-namespace.php | 9 +++++++++ 3 files changed, 14 insertions(+), 1 deletion(-) rename tests/PHPStan/Analyser/data/{global-scope-constants.php => scope-constants-global.php} (100%) create mode 100644 tests/PHPStan/Analyser/data/scope-constants-namespace.php diff --git a/tests/PHPStan/Analyser/ScopePhpVersionTest.php b/tests/PHPStan/Analyser/ScopePhpVersionTest.php index 8f4fc492b2..fac3b8a066 100644 --- a/tests/PHPStan/Analyser/ScopePhpVersionTest.php +++ b/tests/PHPStan/Analyser/ScopePhpVersionTest.php @@ -15,7 +15,11 @@ public function dataTestPhpVersion(): array return [ [ 'int<80000, 80499>', - __DIR__ . '/data/global-scope-constants.php', + __DIR__ . '/data/scope-constants-global.php', + ], + [ + 'int<80000, 80499>', + __DIR__ . '/data/scope-constants-namespace.php', ], ]; } diff --git a/tests/PHPStan/Analyser/data/global-scope-constants.php b/tests/PHPStan/Analyser/data/scope-constants-global.php similarity index 100% rename from tests/PHPStan/Analyser/data/global-scope-constants.php rename to tests/PHPStan/Analyser/data/scope-constants-global.php diff --git a/tests/PHPStan/Analyser/data/scope-constants-namespace.php b/tests/PHPStan/Analyser/data/scope-constants-namespace.php new file mode 100644 index 0000000000..185fc3ee0b --- /dev/null +++ b/tests/PHPStan/Analyser/data/scope-constants-namespace.php @@ -0,0 +1,9 @@ +