-
Notifications
You must be signed in to change notification settings - Fork 78
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
Allow extending the Node class #223
base: master
Are you sure you want to change the base?
Conversation
- Declare ast\Node::parseCode method - Pass through class for subclassing - Update stubs
return; | ||
} | ||
|
||
node_class = zend_get_called_scope(execute_data); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is copied nearly verbatim from https://github.com/php/php-src/blob/59d257d1aea70e370da5937cc019ca5bdcbb8d46/ext/tokenizer/tokenizer.c#L103
I tried using legacy arginfo to prevent the |
@TysonAndre Thoughts on this functionality? The idea looks reasonable to me. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried using legacy arginfo to prevent the static return type from causing an error but that appears to be breaking a 'constructor throws' test. Not sure what the correct solution is here. I will try building on PHP 7.0 locally so I can see what the issue is. Seems to work fine on PHP 7.4 for me locally.
The ast_legacy_arginfo.h is using ZEND_ARG_INFO with no types, so the result is a warning, and stops being the expected TypeError.
return 123; | ||
PHP; | ||
|
||
echo get_class(MyNode::parseCode($code, $version=50)), "\n"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- it'd be more useful to test properties are correctly set, e.g. with the node dumper
- could check that additional properties on the MyNode can be declared and that when read, they have the expected value. Same for properties inherited from traits (to have the unit test in case the property slot order ever changes and affects ast_node_set_prop_kind)
@@ -34,6 +34,17 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_ast_Node___construct, 0, 0, 0) | |||
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, lineno, IS_LONG, 1, "null") | |||
ZEND_END_ARG_INFO() | |||
|
|||
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_ast_Node_parseCode, 0, 2, IS_STATIC, 0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think one possible solution is to redefine IS_STATIC to ast\NODE in ast.c above the include - I forget if that would actually work
And continue using ast_arginfo.h instead of ast_legacy_arginfo.h
#ifndef IS_STATIC
// Workaround for `parse*` methods on Node with static return types in php < 8.0
#define IS_STATIC ast\\Node
#endif
The change itself seems reasonable once tests pass as long as the impact on the overall performance of parsing is small. Aside: also see #180 regarding build issues if 7.1 is an obstacle with this PR using the regular arg info |
Thanks for the detailed review! I will follow up soon, I've been a bit busy starting a new job. |
This PR adds the ability to extend the
Node
class and parse code into your own classes. The idea is to offer a similar API to the tokenizer extension:Example output
This solves a similar problem as #217 but in a different way. Compared to dynamic properties this approach lets you add methods, constants, interfaces, etc. as well and everything can be statically analyzed properly.
This is my first major contribution to a PHP extension so please let me know if anything looks off! I based the changes on the tokenizer extension's source code.