diff --git a/build/gen_stub.php b/build/gen_stub.php index 2898002094040..3aae6a4bfd330 100755 --- a/build/gen_stub.php +++ b/build/gen_stub.php @@ -1226,6 +1226,8 @@ class FuncInfo { public ?string $aliasType; public ?FunctionOrMethodName $alias; public bool $isDeprecated; + public ?string $deprecatedSince; + public ?string $deprecationMessage; public bool $supportsCompileTimeEval; public bool $verify; /** @var ArgInfo[] */ @@ -1253,6 +1255,8 @@ public function __construct( ?string $aliasType, ?FunctionOrMethodName $alias, bool $isDeprecated, + ?string $deprecatedSince, + ?string $deprecationMessage, bool $supportsCompileTimeEval, bool $verify, array $args, @@ -1271,6 +1275,8 @@ public function __construct( $this->aliasType = $aliasType; $this->alias = $alias; $this->isDeprecated = $isDeprecated; + $this->deprecatedSince = $deprecatedSince; + $this->deprecationMessage = $deprecationMessage; $this->supportsCompileTimeEval = $supportsCompileTimeEval; $this->verify = $verify; $this->args = $args; @@ -1583,13 +1589,6 @@ private function getArginfoFlagsByPhpVersions(): array $flags[] = "ZEND_ACC_DEPRECATED"; } - foreach ($this->attributes as $attr) { - if ($attr->class === "Deprecated") { - $flags[] = "ZEND_ACC_DEPRECATED"; - break; - } - } - $php82AndAboveFlags = $flags; if ($this->isMethod() === false && $this->supportsCompileTimeEval) { $php82AndAboveFlags[] = "ZEND_ACC_COMPILE_TIME_EVAL"; @@ -1670,6 +1669,11 @@ public function getMethodSynopsisDocument(array $funcMap, array $aliasMap): ?str $refnamediv->appendChild(new DOMText("\n ")); $refentry->append($refnamediv, $REFSEC1_SEPERATOR); + /* Creation of */ + if ($this->deprecatedSince) { + $refentry->append($this->createDeprecationWarning($doc, $aliasMap), "\n\n "); + } + /* Creation of */ $descriptionRefSec = $this->generateRefSect1($doc, 'description'); @@ -1864,6 +1868,28 @@ private function getParameterSection(DOMDocument $doc): DOMElement { return $parametersRefSec; } + /** @param array $aliasMap */ + public function createDeprecationWarning(DOMDocument $doc, array $aliasMap): DOMElement { + /* Creation of */ + $refsynopsisDiv = $doc->createElement('refsynopsisdiv'); + $deprecationEntity = $doc->createEntityReference( + 'warn.deprecated.' . (isset($aliasMap[$this->name->__toString()]) ? 'alias' : 'function') . '-' . + str_replace(".", "-", $this->deprecatedSince) . "-0" + ); + $refsynopsisDiv->appendChild(new DOMText("\n ")); + $refsynopsisDiv->appendChild($deprecationEntity); + $refsynopsisDiv->appendChild(new DOMText("\n " . ($this->deprecationMessage ? " " : ""))); + + if ($this->deprecationMessage) { + $simparaElement = $doc->createElement('simpara'); + $simparaElement->appendChild(new DOMText("\n " . ucfirst($this->deprecationMessage) . ".\n ")); + $refsynopsisDiv->appendChild($simparaElement); + $refsynopsisDiv->appendChild(new DOMText("\n ")); + } + + return $refsynopsisDiv; + } + private function getReturnValueSection(DOMDocument $doc): DOMElement { $returnRefSec = $this->generateRefSect1($doc, 'returnvalues'); @@ -4156,6 +4182,8 @@ function parseFunctionLike( $aliasType = null; $alias = null; $isDeprecated = false; + $deprecatedSince = null; + $deprecationMessage = null; $supportsCompileTimeEval = false; $verify = true; $docReturnType = null; @@ -4309,6 +4337,21 @@ function parseFunctionLike( $refcount ); + $attributes = createAttributes($func->attrGroups); + foreach ($attributes as $attr) { + if ($attr->class === "Deprecated") { + $isDeprecated = true; + foreach ($attr->args as $attrArg) { + if ($attrArg->name->toLowerString() === "since") { + $deprecatedSince = $attrArg->value->value; + } elseif ($attrArg->name->toLowerString() === "message") { + $deprecationMessage = $attrArg->value->value; + } + } + break; + } + } + return new FuncInfo( $name, $classFlags, @@ -4316,6 +4359,8 @@ function parseFunctionLike( $aliasType, $alias, $isDeprecated, + $deprecatedSince, + $deprecationMessage, $supportsCompileTimeEval, $verify, $args, @@ -4324,7 +4369,7 @@ function parseFunctionLike( $cond, $isUndocumentable, $minimumPhpVersionIdCompatibility, - createAttributes($func->attrGroups), + $attributes, $framelessFunctionInfos, createExposedDocComment($comments) ); @@ -5808,7 +5853,31 @@ function replaceMethodSynopses( // Check if there is any change - short circuit if there is not any. - if (replaceAndCompareXmls($doc, $methodSynopsis, $newMethodSynopsis)) { + $isUnmodified = replaceAndCompareXmls($doc, $methodSynopsis, $newMethodSynopsis); + + // Update deprecation warning + + if ($funcInfo->deprecatedSince) { + foreach ($doc->getElementsByTagName("refentry") as $refentryElement) { + foreach ($refentryElement->getElementsByTagName("refnamediv") as $refnameDivElement) { + if (count($refnameDivElement->getElementsByTagName("refname")) !== 1) { + continue; + } + + if ( + $refnameDivElement->nextSibling === null || + $refnameDivElement->nextSibling->nextSibling instanceof DOMElement === false || + $refnameDivElement->nextSibling->nextSibling->localName !== "refsynopsisdiv" + ) { + $refsynopsisDiv = $funcInfo->createDeprecationWarning($doc, $aliasMap); + $refnameDivElement->after("\n\n ", $refsynopsisDiv); + $isUnmodified = false; + } + } + } + } + + if ($isUnmodified) { continue; } @@ -6054,7 +6123,6 @@ function initPhpParser() { foreach ($fileInfo->getAllFuncInfos() as $funcInfo) { $funcMap[$funcInfo->name->__toString()] = $funcInfo; - // TODO: Don't use aliasMap for methodsynopsis? if ($funcInfo->aliasType === "alias") { $aliasMap[$funcInfo->alias->__toString()] = $funcInfo; }