Skip to content

Allow dynamic properties (e.g. endLineno) without deprecation notice in ast\Node #217

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

Merged
merged 1 commit into from
Nov 27, 2021
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
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.

Copy link
Collaborator Author

@TysonAndre TysonAndre Nov 27, 2021

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
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: