Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generate deprecation warning box for the manual #14938

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 78 additions & 10 deletions build/gen_stub.php
Original file line number Diff line number Diff line change
Expand Up @@ -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[] */
Expand Down Expand Up @@ -1253,6 +1255,8 @@ public function __construct(
?string $aliasType,
?FunctionOrMethodName $alias,
bool $isDeprecated,
?string $deprecatedSince,
?string $deprecationMessage,
bool $supportsCompileTimeEval,
bool $verify,
array $args,
Expand All @@ -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;
Expand Down Expand Up @@ -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";
Expand Down Expand Up @@ -1670,6 +1669,11 @@ public function getMethodSynopsisDocument(array $funcMap, array $aliasMap): ?str
$refnamediv->appendChild(new DOMText("\n "));
$refentry->append($refnamediv, $REFSEC1_SEPERATOR);

/* Creation of <refsynopsisdiv> */
if ($this->deprecatedSince) {
$refentry->append($this->createDeprecationWarning($doc, $aliasMap), "\n\n ");
}

/* Creation of <refsect1 role="description"> */
$descriptionRefSec = $this->generateRefSect1($doc, 'description');

Expand Down Expand Up @@ -1864,6 +1868,28 @@ private function getParameterSection(DOMDocument $doc): DOMElement {
return $parametersRefSec;
}

/** @param array<string, FuncInfo> $aliasMap */
public function createDeprecationWarning(DOMDocument $doc, array $aliasMap): DOMElement {
/* Creation of <refsynopsisdiv> */
$refsynopsisDiv = $doc->createElement('refsynopsisdiv');
$deprecationEntity = $doc->createEntityReference(
'warn.deprecated.' . (isset($aliasMap[$this->name->__toString()]) ? 'alias' : 'function-') .
kocsismate marked this conversation as resolved.
Show resolved Hide resolved
str_replace(".", "-", $this->deprecatedSince) . "-0"
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@TimWolla The since property currently doesn't contain the patch version. However, theoretically it's possible to deprecate symbols in patch versions as well... So I'm wondering whether the .0 suffix could be added to the property value?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, currently, 3rd party extensions shouldn't really use Deprecated attributes... because currently I have to assume that the value of the since property relates to PHP versions, and not the version of the extension itself.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

However, theoretically it's possible to deprecate symbols in patch versions as well... So I'm wondering whether the .0 suffix could be added to the property value?

I don't see a value-add in that. Deprecations in patch version should be very rare. As an example, if folks convert deprecations to Exceptions this would cause a break. Yes, folks should not do that, but they do.

Pretending that the deprecation was there in the .0 version is a good enough approximation, because only the latest patch version of a branch is supported anyways.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, currently, 3rd party extensions shouldn't really use Deprecated attributes... because currently I have to assume that the value of the since property relates to PHP versions, and not the version of the extension itself.

see: https://externals.io/message/123397#124367

);
$refsynopsisDiv->appendChild(new DOMText("\n "));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can actually simplify DOMText insertions as follows:

Suggested change
$refsynopsisDiv->appendChild(new DOMText("\n "));
$refsynopsisDiv->append("\n ");

or even combine the 3 appendChilds into one, but I guess you didn't do it because it would be a long line or would have to be multilined anyway.

$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');

Expand Down Expand Up @@ -4156,6 +4182,8 @@ function parseFunctionLike(
$aliasType = null;
$alias = null;
$isDeprecated = false;
$deprecatedSince = null;
$deprecationMessage = null;
$supportsCompileTimeEval = false;
$verify = true;
$docReturnType = null;
Expand Down Expand Up @@ -4309,13 +4337,30 @@ 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,
$flags,
$aliasType,
$alias,
$isDeprecated,
$deprecatedSince,
$deprecationMessage,
$supportsCompileTimeEval,
$verify,
$args,
Expand All @@ -4324,7 +4369,7 @@ function parseFunctionLike(
$cond,
$isUndocumentable,
$minimumPhpVersionIdCompatibility,
createAttributes($func->attrGroups),
$attributes,
$framelessFunctionInfos,
createExposedDocComment($comments)
);
Expand Down Expand Up @@ -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) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The warning saying This function has been DEPRECATED as of ... doesn't make sense on pages where multiple functions/methods are documented, so I skip the automatic addition of the box in such cases.

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;
}

Expand Down Expand Up @@ -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;
}
Expand Down
Loading