From f857c5079b66dd4914b25cf8f6b41dc3b93f5122 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20D=C3=BCsterhus?= Date: Mon, 13 Jun 2022 23:57:05 +0200 Subject: [PATCH 1/3] Support the `#[\AllowDynamicProperties]` attribute in stubs --- build/gen_stub.php | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/build/gen_stub.php b/build/gen_stub.php index 18763844280f..b59820f507fc 100755 --- a/build/gen_stub.php +++ b/build/gen_stub.php @@ -2273,6 +2273,8 @@ class ClassInfo { /** @var bool */ public $isStrictProperties; /** @var bool */ + public $allowsDynamicProperties; + /** @var bool */ public $isNotSerializable; /** @var Name[] */ public $extends; @@ -2305,6 +2307,7 @@ public function __construct( ?SimpleType $enumBackingType, bool $isDeprecated, bool $isStrictProperties, + bool $allowsDynamicProperties, bool $isNotSerializable, array $extends, array $implements, @@ -2321,6 +2324,7 @@ public function __construct( $this->enumBackingType = $enumBackingType; $this->isDeprecated = $isDeprecated; $this->isStrictProperties = $isStrictProperties; + $this->allowsDynamicProperties = $allowsDynamicProperties; $this->isNotSerializable = $isNotSerializable; $this->extends = $extends; $this->implements = $implements; @@ -2409,6 +2413,10 @@ function (Name $item) { $code .= $property->getDeclaration($allConstInfos); } + if ($this->allowsDynamicProperties) { + $code .= "\tzend_add_class_attribute(class_entry, zend_ce_allow_dynamic_properties->name, 0);\n"; + } + if ($attributeInitializationCode = generateAttributeInitialization($this->funcInfos, $this->cond)) { $code .= "\n" . $attributeInitializationCode; } @@ -2452,6 +2460,10 @@ private function getFlagsAsString(): string $flags[] = "ZEND_ACC_NO_DYNAMIC_PROPERTIES"; } + if ($this->allowsDynamicProperties) { + $flags[] = "ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES"; + } + if ($this->isNotSerializable) { $flags[] = "ZEND_ACC_NOT_SERIALIZABLE"; } @@ -3273,6 +3285,7 @@ function parseClass( $isDeprecated = false; $isStrictProperties = false; $isNotSerializable = false; + $allowsDynamicProperties = false; if ($comment) { $tags = parseDocComment($comment); @@ -3289,6 +3302,18 @@ function parseClass( } } + foreach ($class->attrGroups as $attrGroup) { + foreach ($attrGroup->attrs as $attr) { + switch ($attr->name->toCodeString()) { + case '\\AllowDynamicProperties': + $allowsDynamicProperties = true; + break; + default: + throw new Exception("Unhandled attribute {$attr->name->toCodeString()}."); + } + } + } + $extends = []; $implements = []; @@ -3319,6 +3344,7 @@ function parseClass( ? SimpleType::fromNode($class->scalarType) : null, $isDeprecated, $isStrictProperties, + $allowsDynamicProperties, $isNotSerializable, $extends, $implements, From 754f2ad3d883a5f71e1da6f8152c732b1318a0c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20D=C3=BCsterhus?= Date: Mon, 13 Jun 2022 23:58:38 +0200 Subject: [PATCH 2/3] Use `#[\AllowDynamicProperties]` attribute in stubs --- Zend/zend_builtin_functions.c | 2 -- Zend/zend_builtin_functions.stub.php | 1 + Zend/zend_builtin_functions_arginfo.h | 4 +++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index 963332e0f7ed..8813fa9788a9 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -38,8 +38,6 @@ ZEND_MINIT_FUNCTION(core) { /* {{{ */ zend_register_default_classes(); zend_standard_class_def = register_class_stdClass(); - zend_add_class_attribute(zend_standard_class_def, zend_ce_allow_dynamic_properties->name, 0); - zend_standard_class_def->ce_flags |= ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES; return SUCCESS; } diff --git a/Zend/zend_builtin_functions.stub.php b/Zend/zend_builtin_functions.stub.php index bf6b8242c5a8..ca04719742c5 100644 --- a/Zend/zend_builtin_functions.stub.php +++ b/Zend/zend_builtin_functions.stub.php @@ -2,6 +2,7 @@ /** @generate-class-entries */ +#[\AllowDynamicProperties] class stdClass { } diff --git a/Zend/zend_builtin_functions_arginfo.h b/Zend/zend_builtin_functions_arginfo.h index c4bfc3c48b03..1dbc4255945a 100644 --- a/Zend/zend_builtin_functions_arginfo.h +++ b/Zend/zend_builtin_functions_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 33a976db268b72cee985011198125f652bc6c86d */ + * Stub hash: 80355bb52d643177e3a661a515d9ea915bd1e2fc */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_zend_version, 0, 0, IS_STRING, 0) ZEND_END_ARG_INFO() @@ -353,6 +353,8 @@ static zend_class_entry *register_class_stdClass(void) INIT_CLASS_ENTRY(ce, "stdClass", class_stdClass_methods); class_entry = zend_register_internal_class_ex(&ce, NULL); + class_entry->ce_flags |= ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES; + zend_add_class_attribute(class_entry, zend_ce_allow_dynamic_properties->name, 0); return class_entry; } From b3b67a0b422478aefe0caf93fdef60fd9bc5fc56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20D=C3=BCsterhus?= Date: Tue, 14 Jun 2022 12:02:26 +0200 Subject: [PATCH 3/3] Disallow applying both `@strict-properties` and `#[\AllowDynamicProperties]` --- build/gen_stub.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/build/gen_stub.php b/build/gen_stub.php index b59820f507fc..19c34faafe24 100755 --- a/build/gen_stub.php +++ b/build/gen_stub.php @@ -3314,6 +3314,10 @@ function parseClass( } } + if ($isStrictProperties && $allowsDynamicProperties) { + throw new Exception("A class may not have '@strict-properties' and '#[\\AllowDynamicProperties]' at the same time."); + } + $extends = []; $implements = [];