Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
8 changes: 8 additions & 0 deletions ast.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@
#include "zend_language_parser.h"
#include "zend_exceptions.h"
#include "zend_smart_str.h"
#if PHP_VERSION_ID >= 80200
/* Used for AllowDynamicProperties */
#include "zend_attributes.h"
#endif

#ifndef ZEND_ARG_INFO_WITH_DEFAULT_VALUE
#define ZEND_ARG_INFO_WITH_DEFAULT_VALUE(pass_by_ref, name, default_value) \
Expand Down Expand Up @@ -1518,6 +1522,10 @@ PHP_MINIT_FUNCTION(ast) {
ast_declare_property(ast_node_ce, AST_STR(str_flags), &zv_null);
ast_declare_property(ast_node_ce, AST_STR(str_lineno), &zv_null);
ast_declare_property(ast_node_ce, AST_STR(str_children), &zv_null);
#ifdef ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES
zend_add_class_attribute(ast_node_ce, zend_ce_allow_dynamic_properties->name, 0);
ast_node_ce->ce_flags |= ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES;

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Setting the flag explicitly should not be necessary.

@TysonAndre TysonAndre Nov 27, 2021

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I tried removing the line. Deprecated: Creation of dynamic property ast\Node::$undeclaredDynamic is deprecated in /home/tyson/programming/php-ast/tests/php82_metadata.php on line 18 is the result.

This is the same as what https://github.com/php/php-src/blob/master/Zend/zend_builtin_functions.c does
at the time of writing:

https://github.com/php/php-src/blob/902d64390e49f8bf970588cf53cd8e00630c68bb/Zend/zend_builtin_functions.c#L39-L41

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Ah yes, looks like the callback doesn't get called on interned classes for some reason.

#endif

INIT_CLASS_ENTRY(tmp_ce, "ast\\Metadata", NULL);
ast_metadata_ce = zend_register_internal_class(&tmp_ce);
Expand Down
3 changes: 2 additions & 1 deletion package.xml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
</stability>
<license uri="https://github.com/nikic/php-ast/blob/master/LICENSE">BSD-3-Clause</license>
<notes>
- TBD
- Allow ast\Node to have dynamic properties without emitting a notice in PHP 8.2.
</notes>
<contents>
<dir name="/">
Expand Down Expand Up @@ -115,6 +115,7 @@
<file name="php81_final_class_const.phpt" role="test" />
<file name="php81_intersection_types.phpt" role="test" />
<file name="php81_readonly.phpt" role="test" />
<file name="php82_metadata.phpt" role="test" />
<file name="prop_doc_comments.phpt" role="test" />
<file name="short_arrow_function.phpt" role="test" />
<file name="short_arrow_function_return.phpt" role="test" />
Expand Down
48 changes: 48 additions & 0 deletions tests/php82_metadata.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
--TEST--
Dynamic property support in php 8.2+
--SKIPIF--
<?php if (!class_exists('AllowDynamicProperties')) die('skip PHP >=8.2 only'); ?>
--FILE--
<?php
error_reporting(E_ALL);
ini_set('display_errors', 'stderr');

function dump($x) {
var_export($x);
echo "\n";
}

function dump_attributes(string $class) {
echo "Attributes of $class:\n";
foreach ((new ReflectionClass($class))->getAttributes() as $attribute) {
echo "- " . $attribute->getName() . "\n";
}
}

$node = new ast\Node();
$node->undeclaredDynamic = 123;
dump($node);
$metadata = new ast\Metadata();
$metadata->undeclaredDynamic = 123;
dump($metadata);
dump_attributes(ast\Node::class);
dump_attributes(ast\Metadata::class);
--EXPECTF--
ast\Node::__set_state(array(
'kind' => NULL,
'flags' => NULL,
'lineno' => NULL,
'children' => NULL,
'undeclaredDynamic' => 123,
))
Deprecated: Creation of dynamic property ast\Metadata::$undeclaredDynamic is deprecated in %sphp82_metadata.php on line 21
ast\Metadata::__set_state(array(
'kind' => NULL,
'name' => NULL,
'flags' => NULL,
'flagsCombinable' => NULL,
'undeclaredDynamic' => 123,
))
Attributes of ast\Node:
- AllowDynamicProperties
Attributes of ast\Metadata: