Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 8f3cdf6

Browse files
gen_stub: Add support for attributes on constants in stubs (#18735)
Update to PHP-Parser 5.5.0 and add support for attributes on constants in stubs. For now, I have only migrated over E_STRICT, once the support is in place I'll do a larger migration of the existing deprecated constants. In the process, fix the logic in `copy_zend_constant()` for copying attributes when a constant is copied; just increase the reference count for the attributes table rather than trying to duplicate the contents.
1 parent 99d5624 commit 8f3cdf6

File tree

11 files changed

+143
-16
lines changed

11 files changed

+143
-16
lines changed

‎Zend/tests/e_strict-deprecated.phpt‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,5 @@ var_dump(E_STRICT);
1010
--EXPECTF--
1111
int(30719)
1212

13-
Deprecated: Constant E_STRICT is deprecated in %s on line %d
13+
Deprecated: Constant E_STRICT is deprecated since 8.4, the error level was removed in %s on line %d
1414
int(2048)

‎Zend/zend_attributes.h‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#define ZEND_ATTRIBUTES_H
2222

2323
#include "zend_compile.h"
24+
#include "zend_constants.h"
2425

2526
#define ZEND_ATTRIBUTE_TARGET_CLASS (1<<0)
2627
#define ZEND_ATTRIBUTE_TARGET_FUNCTION (1<<1)
@@ -126,6 +127,12 @@ static zend_always_inline zend_attribute *zend_add_class_constant_attribute(zend
126127
return zend_add_attribute(&c->attributes, name, argc, flags, 0, 0);
127128
}
128129

130+
static zend_always_inline zend_attribute *zend_add_global_constant_attribute(zend_constant *c, zend_string *name, uint32_t argc)
131+
{
132+
uint32_t flags = ZEND_CONSTANT_MODULE_NUMBER(c) == PHP_USER_CONSTANT ? 0 : ZEND_ATTRIBUTE_PERSISTENT;
133+
return zend_add_attribute(&c->attributes, name, argc, flags, 0, 0);
134+
}
135+
129136
void zend_register_attribute_ce(void);
130137
void zend_attributes_shutdown(void);
131138

‎Zend/zend_constants.c‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,8 @@ static void copy_zend_constant(zval *zv)
8585
c->filename = zend_string_copy(c->filename);
8686
}
8787
if (c->attributes != NULL) {
88-
c->attributes = zend_array_dup(c->attributes);
88+
// Use the same attributes table
89+
GC_ADDREF(c->attributes);
8990
}
9091
if (Z_TYPE(c->value) == IS_STRING) {
9192
Z_STR(c->value) = zend_string_dup(Z_STR(c->value), 1);

‎Zend/zend_constants.stub.php‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,9 @@
7171
/**
7272
* @var int
7373
* @cvalue E_STRICT
74-
* @deprecated
7574
* @todo Remove in PHP 9.0
7675
*/
76+
#[\Deprecated(since: '8.4', message: 'the error level was removed')]
7777
const E_STRICT = UNKNOWN;
7878

7979
/**

‎Zend/zend_constants_arginfo.h‎

Lines changed: 15 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎build/gen_stub.php‎

Lines changed: 58 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2622,6 +2622,13 @@ public function __construct(
26222622
?ExposedDocComment $exposedDocComment,
26232623
bool $isFileCacheAllowed
26242624
) {
2625+
foreach ($attributes as $attr) {
2626+
if ($attr->class === "Deprecated") {
2627+
$isDeprecated = true;
2628+
break;
2629+
}
2630+
}
2631+
26252632
$this->name = $name;
26262633
$this->value = $value;
26272634
$this->valueString = $valueString;
@@ -2915,17 +2922,11 @@ protected function getFlagsByPhpVersion(): array
29152922
{
29162923
$flags = parent::getFlagsByPhpVersion();
29172924

2925+
// $this->isDeprecated also accounts for any #[\Deprecated] attributes
29182926
if ($this->isDeprecated) {
29192927
$flags = $this->addFlagForVersionsAbove($flags, "ZEND_ACC_DEPRECATED", PHP_80_VERSION_ID);
29202928
}
29212929

2922-
foreach ($this->attributes as $attr) {
2923-
if ($attr->class === "Deprecated") {
2924-
$flags = $this->addFlagForVersionsAbove($flags, "ZEND_ACC_DEPRECATED", PHP_80_VERSION_ID);
2925-
break;
2926-
}
2927-
}
2928-
29292930
if ($this->flags & Modifiers::FINAL) {
29302931
$flags = $this->addFlagForVersionsAbove($flags, "ZEND_ACC_FINAL", PHP_81_VERSION_ID);
29312932
}
@@ -4340,7 +4341,7 @@ private function handleStatements(array $stmts, PrettyPrinterAbstract $prettyPri
43404341
$cond,
43414342
$this->isUndocumentable,
43424343
$this->getMinimumPhpVersionIdCompatibility(),
4343-
[]
4344+
AttributeInfo::createFromGroups($stmt->attrGroups)
43444345
);
43454346
}
43464347
continue;
@@ -5177,7 +5178,9 @@ static function (FuncInfo $funcInfo) use ($fileInfo, &$generatedFunctionDeclarat
51775178
$php80MinimumCompatibility = $fileInfo->getMinimumPhpVersionIdCompatibility() === null || $fileInfo->getMinimumPhpVersionIdCompatibility() >= PHP_80_VERSION_ID;
51785179

51795180
if ($fileInfo->generateClassEntries) {
5180-
if ($attributeInitializationCode = generateFunctionAttributeInitialization($fileInfo->funcInfos, $allConstInfos, $fileInfo->getMinimumPhpVersionIdCompatibility(), null)) {
5181+
$attributeInitializationCode = generateFunctionAttributeInitialization($fileInfo->funcInfos, $allConstInfos, $fileInfo->getMinimumPhpVersionIdCompatibility(), null);
5182+
$attributeInitializationCode .= generateGlobalConstantAttributeInitialization($fileInfo->constInfos, $allConstInfos, $fileInfo->getMinimumPhpVersionIdCompatibility(), null);
5183+
if ($attributeInitializationCode) {
51815184
if (!$php80MinimumCompatibility) {
51825185
$attributeInitializationCode = "\n#if (PHP_VERSION_ID >= " . PHP_80_VERSION_ID . ")" . $attributeInitializationCode . "#endif\n";
51835186
}
@@ -5289,6 +5292,51 @@ static function (FuncInfo $funcInfo) use ($allConstInfos, $phpVersionIdMinimumCo
52895292
);
52905293
}
52915294

5295+
/**
5296+
* @param iterable<ConstInfo> $constInfos
5297+
* @param array<string, ConstInfo> $allConstInfos
5298+
*/
5299+
function generateGlobalConstantAttributeInitialization(
5300+
iterable $constInfos,
5301+
array $allConstInfos,
5302+
?int $phpVersionIdMinimumCompatibility,
5303+
?string $parentCond = null
5304+
): string {
5305+
$isConditional = false;
5306+
if ($phpVersionIdMinimumCompatibility !== null && $phpVersionIdMinimumCompatibility < PHP_85_VERSION_ID) {
5307+
$isConditional = true;
5308+
$phpVersionIdMinimumCompatibility = PHP_85_VERSION_ID;
5309+
}
5310+
$code = generateCodeWithConditions(
5311+
$constInfos,
5312+
"",
5313+
static function (ConstInfo $constInfo) use ($allConstInfos, $phpVersionIdMinimumCompatibility) {
5314+
if ($constInfo->attributes === []) {
5315+
return null;
5316+
}
5317+
$constName = str_replace('\\', '\\\\', $constInfo->name->__toString());
5318+
$constVarName = 'const_' . $constName;
5319+
5320+
$code .= "\tzend_constant *$constVarName = zend_hash_str_find_ptr(EG(zend_constants), \"" . $constName . "\", sizeof(\"" . $constName . "\") - 1);\n";
5321+
foreach ($constInfo->attributes as $key => $attribute) {
5322+
$code .= $attribute->generateCode(
5323+
"zend_add_global_constant_attribute($constVarName",
5324+
$constVarName . "_$key",
5325+
$allConstInfos,
5326+
$phpVersionIdMinimumCompatibility
5327+
);
5328+
}
5329+
5330+
return $code;
5331+
},
5332+
$parentCond
5333+
);
5334+
if ($code && $isConditional) {
5335+
return "\n#if (PHP_VERSION_ID >= " . PHP_85_VERSION_ID . ")\n" . $code . "#endif\n";
5336+
}
5337+
return $code;
5338+
}
5339+
52925340
/**
52935341
* @param iterable<ConstInfo> $constInfos
52945342
* @param array<string, ConstInfo> $allConstInfos
@@ -6030,7 +6078,7 @@ function initPhpParser() {
60306078
}
60316079

60326080
$isInitialized = true;
6033-
$version = "5.3.1";
6081+
$version = "5.5.0";
60346082
$phpParserDir = __DIR__ . "/PHP-Parser-$version";
60356083
if (!is_dir($phpParserDir)) {
60366084
installPhpParser($version, $phpParserDir);
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
--TEST--
2+
ReflectionConstant::getAttributes() with attribute (internal constant)
3+
--FILE--
4+
<?php
5+
6+
$reflectionConstant = new ReflectionConstant('E_STRICT');
7+
var_dump($reflectionConstant->getAttributes());
8+
9+
?>
10+
--EXPECTF--
11+
array(1) {
12+
[0]=>
13+
object(ReflectionAttribute)#%d (1) {
14+
["name"]=>
15+
string(10) "Deprecated"
16+
}
17+
}

‎ext/zend_test/test.stub.php‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,12 @@
1717
/** @var string */
1818
const ZEND_CONSTANT_A = "global";
1919

20+
/**
21+
* @var int
22+
*/
23+
#[\Deprecated(message: "use something else", since: "version 1.5")]
24+
const ZEND_TEST_ATTRIBUTED_CONSTANT = 42;
25+
2026
interface _ZendTestInterface
2127
{
2228
/** @var int */

‎ext/zend_test/test_arginfo.h‎

Lines changed: 18 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎ext/zend_test/tests/attribute-deprecated.phpt‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,12 @@ $reflection = new ReflectionClassConstant('_ZendTestClass', 'ZEND_TEST_DEPRECATE
1717
var_dump($reflection->getAttributes()[0]->newInstance());
1818
var_dump($reflection->isDeprecated());
1919

20+
ZEND_TEST_ATTRIBUTED_CONSTANT;
21+
22+
$reflection = new ReflectionConstant('ZEND_TEST_ATTRIBUTED_CONSTANT');
23+
var_dump($reflection->getAttributes()[0]->newInstance());
24+
var_dump($reflection->isDeprecated());
25+
2026
?>
2127
--EXPECTF--
2228
Deprecated: Function zend_test_deprecated() is deprecated in %s on line %d
@@ -38,3 +44,12 @@ object(Deprecated)#%d (2) {
3844
NULL
3945
}
4046
bool(true)
47+
48+
Deprecated: Constant ZEND_TEST_ATTRIBUTED_CONSTANT is deprecated since version 1.5, use something else in %s on line %d
49+
object(Deprecated)#%d (2) {
50+
["message"]=>
51+
string(18) "use something else"
52+
["since"]=>
53+
string(11) "version 1.5"
54+
}
55+
bool(true)

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /