Skip to content

Commit 2d3812a

Browse files
committed
Version 35: Forward/backward emulation of AST_CATCH format
1 parent c81fe78 commit 2d3812a

File tree

3 files changed

+51
-1
lines changed

3 files changed

+51
-1
lines changed

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -435,6 +435,12 @@ Version changelog
435435
These will now be normalized to always use an `AST_STMT_LIST`. A `null` is only allowed if it is
436436
semantically meaningful, e.g. in the case of `declare(ticks=1);` vs `declare(ticks=1) {}`.
437437

438+
### 35 (in development)
439+
440+
* The `class` node of `AST_CATCH` is now always represented as an `AST_NAME_LIST`. In lower
441+
versions: On PHP 7.0 it will always be an `AST_NAME`. In PHP 7.1 it will be an `AST_NAME` if
442+
there is only a single class and `AST_NAME_LIST` otherwise.
443+
438444
### 30 (current)
439445

440446
Supported since 2015-03-10.

ast.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,20 @@ static void ast_fill_children_ht(HashTable *ht, zend_ast *ast, zend_long version
357357
&& (ast->kind == ZEND_AST_PROP_ELEM || ast->kind == ZEND_AST_CONST_ELEM)) {
358358
/* Skip docComment child -- It's handled separately */
359359
continue;
360+
#if PHP_VERSION_ID >= 70100
361+
} else if (ast->kind == ZEND_AST_CATCH && version < 35
362+
&& i == 0 && zend_ast_get_list(child)->children == 1) {
363+
/* Emulate PHP 7.0 format (no list) */
364+
ast_create_virtual_node(
365+
&child_zv, AST_NAME, zend_ast_get_list(child)->child[0], version);
366+
#else
367+
} else if (ast->kind == ZEND_AST_CATCH && version >= 35) {
368+
/* Emulate PHP 7.1 format (name list) */
369+
zval tmp;
370+
ast_create_virtual_node(&tmo, AST_NAME, child, version);
371+
ast_create_virtual_node_ex(
372+
&child_zv, ZEND_AST_NAME_LIST, 0, zend_ast_get_lineno(child), &tmp, version);
373+
#endif
360374
} else {
361375
ast_to_zval(&child_zv, child, version);
362376
}
@@ -499,7 +513,7 @@ static void ast_to_zval(zval *zv, zend_ast *ast, zend_long version) {
499513
ast_fill_children_ht(Z_ARRVAL(tmp_zv), ast, version);
500514
}
501515

502-
static const zend_long versions[] = {10, 15, 20, 30, 40};
516+
static const zend_long versions[] = {10, 15, 20, 30, 35, 40};
503517
static const size_t versions_count = sizeof(versions)/sizeof(versions[0]);
504518

505519
static zend_string *ast_version_info() {

tests/try_catch_finally.phpt

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ PHP;
2020

2121
echo ast_dump(ast\parse_code($code, $version=15)), "\n";
2222
echo ast_dump(ast\parse_code($code, $version=20)), "\n";
23+
echo ast_dump(ast\parse_code($code, $version=35)), "\n";
2324

2425
?>
2526
--EXPECTF--
@@ -80,3 +81,32 @@ AST_STMT_LIST
8081
2: AST_STMT_LIST
8182
0: AST_ECHO
8283
0: "finally"
84+
AST_STMT_LIST
85+
0: AST_TRY
86+
try: AST_STMT_LIST
87+
0: AST_ECHO
88+
expr: "try"
89+
catches: AST_CATCH_LIST
90+
0: AST_CATCH
91+
class: AST_NAME_LIST
92+
0: AST_NAME
93+
flags: NAME_NOT_FQ (1)
94+
name: "Exception"
95+
var: AST_VAR
96+
name: "e"
97+
stmts: AST_STMT_LIST
98+
0: AST_ECHO
99+
expr: "catch 1"
100+
1: AST_CATCH
101+
class: AST_NAME_LIST
102+
0: AST_NAME
103+
flags: NAME_NOT_FQ (1)
104+
name: "bar\FooException"
105+
var: AST_VAR
106+
name: "e2"
107+
stmts: AST_STMT_LIST
108+
0: AST_ECHO
109+
expr: "catch 2"
110+
finally: AST_STMT_LIST
111+
0: AST_ECHO
112+
expr: "finally"

0 commit comments

Comments
 (0)