From 3d97f68a877fa1ca9cc42258e605e01f19821a45 Mon Sep 17 00:00:00 2001 From: mainframe98 Date: Sun, 18 Oct 2026 20:04:46 +0200 Subject: [PATCH] zend_test: Fix function and constant imports in compile_to_ast and add support for grouping While writing a test for it, I discovered the logic for printing the AST representation of use statements was broken and grouping did not work. That has been fixed and incorporated into the test. --- Zend/zend_ast.c | 29 +++++++- .../tests/compile_to_ast/namespace.phpt | 68 +++++++++++++++++++ 2 files changed, 95 insertions(+), 2 deletions(-) create mode 100644 ext/zend_test/tests/compile_to_ast/namespace.phpt diff --git a/Zend/zend_ast.c b/Zend/zend_ast.c index a39f8d30820c..4e640a321d1f 100644 --- a/Zend/zend_ast.c +++ b/Zend/zend_ast.c @@ -2046,9 +2046,9 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio break; case ZEND_AST_USE: smart_str_appends(str, "use "); - if (ast->attr == T_FUNCTION) { + if (ast->attr == ZEND_SYMBOL_FUNCTION) { smart_str_appends(str, "function "); - } else if (ast->attr == T_CONST) { + } else if (ast->attr == ZEND_SYMBOL_CONST) { smart_str_appends(str, "const "); } goto simple_list; @@ -2489,6 +2489,19 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio } break; case ZEND_AST_USE_ELEM: + if (ast->attr == ZEND_SYMBOL_FUNCTION) { + smart_str_appends(str, "function "); + } else if (ast->attr == ZEND_SYMBOL_CONST) { + smart_str_appends(str, "const "); + } + + zend_ast_export_name(str, ast->child[0], 0, indent); + + if (ast->child[1]) { + smart_str_appends(str, " as "); + zend_ast_export_name(str, ast->child[1], 0, indent); + } + break; case ZEND_AST_TRAIT_ALIAS: zend_ast_export_name(str, ast->child[0], 0, indent); if (ast->attr & ZEND_ACC_PUBLIC) { @@ -2510,6 +2523,18 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio smart_str_appends(str, ": "); ast = ast->child[1]; goto tail_call; + case ZEND_AST_GROUP_USE: + smart_str_appends(str, "use "); + if (ast->attr == ZEND_SYMBOL_FUNCTION) { + smart_str_appends(str, "function "); + } else if (ast->attr == ZEND_SYMBOL_CONST) { + smart_str_appends(str, "const "); + } + smart_str_append(str, zend_ast_get_str(ast->child[0])); + smart_str_appends(str, "\\{"); + zend_ast_export_list(str, zend_ast_get_list(ast->child[1]), true, 20, indent); + smart_str_appends(str, "}"); + break; /* 3 child nodes */ case ZEND_AST_METHOD_CALL: diff --git a/ext/zend_test/tests/compile_to_ast/namespace.phpt b/ext/zend_test/tests/compile_to_ast/namespace.phpt new file mode 100644 index 000000000000..ee0165a2600b --- /dev/null +++ b/ext/zend_test/tests/compile_to_ast/namespace.phpt @@ -0,0 +1,68 @@ +--TEST-- +AST can be recreated (namespace) +--EXTENSIONS-- +zend_test +--FILE-- + +--EXPECT-- +namespace Foo { + class FooTest { + } + + function fn_foo() { + } + + function fn_bar() { + } + +} + +namespace Bar { + class BarTest { + } + + function fn_bar() { + } + +} + +namespace { + use function Bar\fn_bar; + use Foo\{function fn_foo, FooTest, function fn_bar as fn_foobar}; + new FooTest(); + fn_bar(); + fn_foobar(); + echo zend_test_compile_to_ast(file_get_contents(__FILE__)); +}