Skip to content

Commit 5ed5931

Browse files
TysonAndrenikic
authored andcommitted
Add DIM_ALTERNATIVE_SYNTAX flag for 7.4's $x{$i}
Fixes nikic#128 Fix ast\kind_uses_flags(ast\AST_ARROW_FUNC) in php < 7.4
1 parent 7bf72a8 commit 5ed5931

File tree

6 files changed

+57
-4
lines changed

6 files changed

+57
-4
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,9 @@ ast\flags\ARRAY_SYNTAX_LIST
342342
343343
// Used by ast\AST_ARRAY_ELEM (exclusive)
344344
ast\flags\ARRAY_ELEM_REF
345+
346+
// Used by ast\AST_DIM (combinable), since PHP 7.4
347+
ast\flags\DIM_ALTERNATIVE_SYNTAX
345348
```
346349

347350
AST node kinds

ast.c

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,10 @@
5656
# define ZEND_BIND_REF 1
5757
#endif
5858

59+
#if PHP_VERSION_ID < 70400
60+
# define ZEND_DIM_ALTERNATIVE_SYNTAX (1<<1)
61+
#endif
62+
5963
/* This contains state of the ast Node creator. */
6064
typedef struct ast_state_info {
6165
zend_long version;
@@ -232,6 +236,12 @@ static const char *func_flags[] = {
232236
NULL
233237
};
234238

239+
// Flags of AST_DIM are marked as combinable in case any other flags get added in the future.
240+
static const char *dim_flags[] = {
241+
AST_FLAG(DIM_ALTERNATIVE_SYNTAX),
242+
NULL
243+
};
244+
235245
static const ast_flag_info flag_info[] = {
236246
{ AST_NAME, 0, name_flags },
237247
{ ZEND_AST_CLASS, 0, class_flags },
@@ -257,6 +267,7 @@ static const ast_flag_info flag_info[] = {
257267
{ ZEND_AST_PROP_GROUP, 1, modifier_flags },
258268
{ ZEND_AST_CLASS_CONST_DECL, 1, visibility_flags },
259269
{ ZEND_AST_TRAIT_ALIAS, 1, modifier_flags },
270+
{ ZEND_AST_DIM, 1, dim_flags },
260271
};
261272

262273
static inline void ast_update_property(zval *object, zend_string *name, zval *value, void **cache_slot) {
@@ -319,14 +330,12 @@ static inline zend_bool ast_kind_uses_attr(zend_ast_kind kind) {
319330
|| kind == ZEND_AST_PROP_GROUP
320331
|| kind == ZEND_AST_GROUP_USE || kind == ZEND_AST_USE_ELEM
321332
|| kind == AST_NAME || kind == AST_CLOSURE_VAR || kind == ZEND_AST_CLASS_CONST_DECL
322-
|| kind == ZEND_AST_ARRAY;
333+
|| kind == ZEND_AST_ARRAY || kind == ZEND_AST_DIM;
323334
}
324335

325336
static inline zend_bool ast_kind_is_decl(zend_ast_kind kind) {
326337
return kind == ZEND_AST_FUNC_DECL || kind == ZEND_AST_CLOSURE
327-
#if PHP_VERSION_ID >= 70400
328338
|| kind == ZEND_AST_ARROW_FUNC
329-
#endif
330339
|| kind == ZEND_AST_METHOD || kind == ZEND_AST_CLASS;
331340
}
332341

@@ -1327,6 +1336,8 @@ PHP_MINIT_FUNCTION(ast) {
13271336
ast_register_flag_constant("ARRAY_SYNTAX_LONG", ZEND_ARRAY_SYNTAX_LONG);
13281337
ast_register_flag_constant("ARRAY_SYNTAX_SHORT", ZEND_ARRAY_SYNTAX_SHORT);
13291338

1339+
ast_register_flag_constant("DIM_ALTERNATIVE_SYNTAX", ZEND_DIM_ALTERNATIVE_SYNTAX);
1340+
13301341
INIT_CLASS_ENTRY(tmp_ce, "ast\\Node", ast_node_functions);
13311342
ast_node_ce = zend_register_internal_class(&tmp_ce);
13321343
ast_declare_property(ast_node_ce, AST_STR(str_kind), &zv_null);

package.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
<license uri="https://github.com/nikic/php-ast/blob/master/LICENSE">BSD-3-Clause</license>
2525
<notes>
2626
- Fix build error in php 7.4.0alpha3.
27+
- Add `DIM_ALTERNATIVE_SYNTAX` as a flag of `AST_DIM` for `$x{'offset'}` (for php 7.4+)
28+
- Bugfix: Make `ast\kind_uses_flags(ast\AST_ARROW_FUNC)` true in php 7.3 and lower.
2729
</notes>
2830
<contents>
2931
<dir name="/">
@@ -81,6 +83,7 @@
8183
<file name="parse_file_parse_error.phpt" role="test" />
8284
<file name="parse_file.phpt" role="test" />
8385
<file name="php74_ast_assign_coalesce.phpt" role="test" />
86+
<file name="php74_dim_alternative_syntax.phpt" role="test" />
8487
<file name="php74_ordinary_class.phpt" role="test" />
8588
<file name="php74_type_hints.phpt" role="test" />
8689
<file name="prop_doc_comments.phpt" role="test" />

tests/metadata.phpt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@ foreach ($metadata as $data) {
99
foreach ($data->flags as $flag) {
1010
$flags[] = substr($flag, strrpos($flag, '\\') + 1);
1111
}
12+
$metadataHasFlags = count($flags) > 0;
13+
$kindUsesFlags = ast\kind_uses_flags($data->kind);
14+
if ($metadataHasFlags != $kindUsesFlags) {
15+
echo "kind_uses_flags for $data->name is unexpectedly " . var_export($kindUsesFlags, true) . "\n";
16+
}
17+
1218
echo "$data->name: ";
1319
if ($data->flagsCombinable) {
1420
echo "(combinable) ";
@@ -74,7 +80,7 @@ AST_GOTO: []
7480
AST_BREAK: []
7581
AST_CONTINUE: []
7682
AST_CLASS_NAME: []
77-
AST_DIM: []
83+
AST_DIM: (combinable) [DIM_ALTERNATIVE_SYNTAX]
7884
AST_PROP: []
7985
AST_STATIC_PROP: []
8086
AST_CALL: []

tests/php74_ast_assign_coalesce.phpt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ AST_STMT_LIST
2626
1: AST_ASSIGN_OP
2727
flags: BINARY_COALESCE (%d)
2828
var: AST_DIM
29+
flags: 0
2930
expr: AST_STATIC_PROP
3031
class: AST_NAME
3132
flags: NAME_NOT_FQ (%d)
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
--TEST--
2+
'$x{"offset"}' flag in PHP 7.4
3+
--SKIPIF--
4+
<?php if (PHP_VERSION_ID < 70400) die('skip PHP >= 7.4 only'); ?>
5+
--FILE--
6+
<?php
7+
8+
require __DIR__ . '/../util.php';
9+
10+
$code = <<<'PHP'
11+
<?php
12+
var_export($x{'offset'});
13+
PHP;
14+
15+
$node = ast\parse_code($code, $version=70);
16+
echo ast_dump($node), "\n";
17+
?>
18+
--EXPECTF--
19+
AST_STMT_LIST
20+
0: AST_CALL
21+
expr: AST_NAME
22+
flags: NAME_NOT_FQ (1)
23+
name: "var_export"
24+
args: AST_ARG_LIST
25+
0: AST_DIM
26+
flags: DIM_ALTERNATIVE_SYNTAX (2)
27+
expr: AST_VAR
28+
name: "x"
29+
dim: "offset"

0 commit comments

Comments
 (0)