@@ -157,6 +157,31 @@ static inline zend_bool ast_is_var_name(zend_ast *ast, zend_ast *parent, uint32_
157
157
|| (parent -> kind == ZEND_AST_CATCH && i == 1 );
158
158
}
159
159
160
+ /* Whether this node may need statement list normalization */
161
+ static inline zend_bool ast_should_normalize_list (zend_ast * ast , zend_ast * parent , uint32_t i ) {
162
+ if (ast && ast -> kind == ZEND_AST_STMT_LIST ) {
163
+ return 0 ;
164
+ }
165
+
166
+ if (i == 0 ) {
167
+ return parent -> kind == ZEND_AST_DO_WHILE ;
168
+ }
169
+ if (i == 1 ) {
170
+ if (parent -> kind == ZEND_AST_DECLARE ) {
171
+ /* declare(); and declare() {} are not the same */
172
+ return ast != NULL ;
173
+ }
174
+ return parent -> kind == ZEND_AST_IF_ELEM || parent -> kind == ZEND_AST_WHILE ;
175
+ }
176
+ if (i == 2 ) {
177
+ return parent -> kind == ZEND_AST_CATCH ;
178
+ }
179
+ if (i == 3 ) {
180
+ return parent -> kind == ZEND_AST_FOR || parent -> kind == ZEND_AST_FOREACH ;
181
+ }
182
+ return 0 ;
183
+ }
184
+
160
185
/* Adopted from zend_compile.c */
161
186
typedef struct _builtin_type_info {
162
187
const char * name ;
@@ -216,7 +241,8 @@ static inline zend_ast **ast_get_children(zend_ast *ast, uint32_t *count) {
216
241
}
217
242
}
218
243
219
- /* "child" may be AST_ZVAL or NULL */
244
+ static void ast_to_zval (zval * zv , zend_ast * ast , zend_long version );
245
+
220
246
static void ast_create_virtual_node_ex (
221
247
zval * zv , zend_ast_kind kind , zend_ast_attr attr , uint32_t lineno ,
222
248
zend_ast * child , zend_long version ) {
@@ -237,9 +263,10 @@ static void ast_create_virtual_node_ex(
237
263
ast_update_property (zv , AST_STR (str_children ), & tmp_zv , AST_CACHE_SLOT_CHILDREN );
238
264
239
265
if (child ) {
240
- ZVAL_COPY (& tmp_zv2 , zend_ast_get_zval (child ));
241
- if (version >= 30 ) {
242
- zend_hash_add_new (Z_ARRVAL (tmp_zv ), ast_kind_child_name (kind , 0 ), & tmp_zv2 );
266
+ zend_string * child_name = version >= 30 ? ast_kind_child_name (kind , 0 ) : NULL ;
267
+ ast_to_zval (& tmp_zv2 , child , version );
268
+ if (child_name ) {
269
+ zend_hash_add_new (Z_ARRVAL (tmp_zv ), child_name , & tmp_zv2 );
243
270
} else {
244
271
zend_hash_next_index_insert (Z_ARRVAL (tmp_zv ), & tmp_zv2 );
245
272
}
@@ -252,8 +279,6 @@ static void ast_create_virtual_node(
252
279
zv , kind , child -> attr , zend_ast_get_lineno (child ), child , version );
253
280
}
254
281
255
- static void ast_to_zval (zval * zv , zend_ast * ast , zend_long version );
256
-
257
282
static void ast_fill_children_ht (HashTable * ht , zend_ast * ast , zend_long version ) {
258
283
uint32_t i , count ;
259
284
zend_bool is_list = zend_ast_is_list (ast );
@@ -300,6 +325,10 @@ static void ast_fill_children_ht(HashTable *ht, zend_ast *ast, zend_long version
300
325
ast_create_virtual_node (& child_zv , AST_CLOSURE_VAR , child , version );
301
326
} else if (version >= 20 && ast_is_var_name (child , ast , i )) {
302
327
ast_create_virtual_node (& child_zv , ZEND_AST_VAR , child , version );
328
+ } else if (version >= 40 && ast_should_normalize_list (child , ast , i )) {
329
+ ast_create_virtual_node_ex (
330
+ & child_zv , ZEND_AST_STMT_LIST , 0 ,
331
+ zend_ast_get_lineno (child ? child : ast ), child , version );
303
332
} else if (i == 2
304
333
&& (ast -> kind == ZEND_AST_PROP_ELEM || ast -> kind == ZEND_AST_CONST_ELEM )) {
305
334
/* Skip docComment child -- It's handled separately */
0 commit comments