diff --git a/src/SourceLocator/SourceStubber/PhpStormStubsSourceStubber.php b/src/SourceLocator/SourceStubber/PhpStormStubsSourceStubber.php index 5de6b03ba..a59f32e8d 100644 --- a/src/SourceLocator/SourceStubber/PhpStormStubsSourceStubber.php +++ b/src/SourceLocator/SourceStubber/PhpStormStubsSourceStubber.php @@ -24,9 +24,11 @@ use PhpParser\PrettyPrinter\Standard; use RecursiveIterator; use Roave\BetterReflection\Reflection\Annotation\AnnotationHelper; +use Roave\BetterReflection\Reflection\Exception\InvalidConstantNode; use Roave\BetterReflection\SourceLocator\FileChecker; use Roave\BetterReflection\SourceLocator\SourceStubber\Exception\CouldNotFindPhpStormStubs; use Roave\BetterReflection\SourceLocator\SourceStubber\PhpStormStubs\CachingVisitor; +use Roave\BetterReflection\Util\ConstantNodeChecker; use SimpleXMLElement; use SplFixedArray; use Traversable; @@ -446,6 +448,15 @@ private function parseFile(string $filePath): void private function createStub(Node\Stmt\ClassLike|Node\Stmt\Function_|Node\Stmt\Const_|Node\Expr\FuncCall $node, Node\Stmt\Namespace_|null $namespaceNode): string { + if ($node instanceof Node\Expr\FuncCall) { + try { + ConstantNodeChecker::assertValidDefineFunctionCall($node); + $this->addDeprecatedDocComment($node); + } catch (InvalidConstantNode) { + // just keep going + } + } + if (! ($node instanceof Node\Expr\FuncCall)) { $this->addDeprecatedDocComment($node); @@ -662,9 +673,9 @@ private function getStmtType(Node\Stmt\Function_|Node\Stmt\ClassMethod|Node\Stmt : null; } - private function addDeprecatedDocComment(Node\Stmt\ClassLike|Node\Stmt\ClassConst|Node\Stmt\Property|Node\Stmt\ClassMethod|Node\Stmt\Function_|Node\Stmt\Const_ $node): void + private function addDeprecatedDocComment(Node\Stmt\ClassLike|Node\Stmt\ClassConst|Node\Stmt\Property|Node\Stmt\ClassMethod|Node\Stmt\Function_|Node\Expr\FuncCall|Node\Stmt\Const_ $node): void { - if ($node instanceof Node\Stmt\Const_) { + if ($node instanceof Node\Expr\FuncCall) { if (! $this->isDeprecatedByPhpDocInPhpVersion($node)) { $this->removeAnnotationFromDocComment($node, 'deprecated'); } @@ -672,6 +683,10 @@ private function addDeprecatedDocComment(Node\Stmt\ClassLike|Node\Stmt\ClassCons return; } + if ($node instanceof Node\Stmt\Const_) { + return; + } + if (! $this->isDeprecatedInPhpVersion($node)) { $this->removeAnnotationFromDocComment($node, 'deprecated'); @@ -697,7 +712,7 @@ private function addAnnotationToDocComment( } private function removeAnnotationFromDocComment( - Node\Stmt\ClassLike|Node\Stmt\ClassConst|Node\Stmt\Property|Node\Stmt\ClassMethod|Node\Stmt\Function_|Node\Stmt\Const_ $node, + Node\Stmt\ClassLike|Node\Stmt\ClassConst|Node\Stmt\Property|Node\Stmt\ClassMethod|Node\Stmt\Function_|Node\Expr\FuncCall|Node\Stmt\Const_ $node, string $annotationName, ): void { $docComment = $node->getDocComment(); @@ -714,14 +729,14 @@ private function isCoreExtension(string $extension): bool return in_array($extension, self::CORE_EXTENSIONS, true); } - private function isDeprecatedByPhpDocInPhpVersion(Node\Stmt\Const_ $node): bool + private function isDeprecatedByPhpDocInPhpVersion(Node\Expr\FuncCall $node): bool { $docComment = $node->getDocComment(); if ($docComment === null) { return false; } - if (preg_match('#@deprecated\s+(\d+)\.(\d+)(?:\.(\d+)?)$#m', $docComment->getText(), $matches) === 1) { + if (preg_match('#@deprecated\s+(\d+)\.(\d+)(?:\.(\d+))?$#m', $docComment->getText(), $matches) === 1) { $major = $matches[1]; $minor = $matches[2]; $patch = $matches[3] ?? 0; diff --git a/test/unit/SourceLocator/SourceStubber/PhpStormStubsSourceStubberTest.php b/test/unit/SourceLocator/SourceStubber/PhpStormStubsSourceStubberTest.php index e8c92f74b..ffcb90ba5 100644 --- a/test/unit/SourceLocator/SourceStubber/PhpStormStubsSourceStubberTest.php +++ b/test/unit/SourceLocator/SourceStubber/PhpStormStubsSourceStubberTest.php @@ -481,37 +481,26 @@ public function testStubForConstantThatExists(): void public function testStubForConstantThatIsDeprecated(): void { - // use a faked stub to make this test independent of the actual PHP version - $exampleStub = <<<'EOT' -sourceStubber->generateConstantStub('MT_RAND_PHP'); - self::assertStringMatchesFormat( - "%Adefine('FILTER_SANITIZE_STRING',%w%d);", + self::assertStringContainsString( + 'define("MT_RAND_PHP", 1);', $stubData->getStub(), ); - if (PHP_VERSION_ID >= 80100) { + if (PHP_VERSION_ID >= 80300) { self::assertStringContainsString( - '@deprecated 8.1', + '@deprecated 8.3', $stubData->getStub(), ); } else { self::assertStringNotContainsString( - '@deprecated 8.1', + '@deprecated 8.3', $stubData->getStub(), ); } - self::assertSame('filter', $stubData->getExtensionName()); + self::assertSame('standard', $stubData->getExtensionName()); } public function testNoStubForConstantThatDoesNotExist(): void