diff options
-rw-r--r-- | Zend/zend_ast.h | 1 | ||||
-rw-r--r-- | Zend/zend_compile.c | 23 | ||||
-rw-r--r-- | Zend/zend_language_parser.y | 23 |
3 files changed, 47 insertions, 0 deletions
diff --git a/Zend/zend_ast.h b/Zend/zend_ast.h index bc26ea2168..854576df0c 100644 --- a/Zend/zend_ast.h +++ b/Zend/zend_ast.h @@ -132,6 +132,7 @@ enum _zend_ast_kind { ZEND_AST_NAMESPACE, ZEND_AST_USE_ELEM, ZEND_AST_TRAIT_ALIAS, + ZEND_AST_BATCH_USE, /* 3 child nodes */ ZEND_AST_METHOD_CALL = 3 << ZEND_AST_NUM_CHILDREN_SHIFT, diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 3a3347ee89..28c7ea3d42 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -4935,6 +4935,26 @@ static void zend_check_already_in_use(uint32_t type, zend_string *old_name, zend } /* }}} */ +void zend_compile_batch_use(zend_ast *ast) /* {{{ */ +{ + zend_string *ns = zend_ast_get_str(ast->child[0]); + zend_ast_list *list = zend_ast_get_list(ast->child[1]); + uint32_t i; + + for (i = 0; i < list->children; i++) { + zend_ast *use = list->child[i]; + zval *name_zval = zend_ast_get_zval(use->child[0]); + zend_string *name = Z_STR_P(name_zval); + zend_string *compound_ns = zend_concat_names(ns->val, ns->len, name->val, name->len); + zend_string_release(name); + ZVAL_STR(name_zval, compound_ns); + zend_ast_list *inline_use = zend_ast_create_list(1, ZEND_AST_USE, use); + inline_use->attr = use->attr; + zend_compile_use(inline_use); + } +} +/* }}} */ + void zend_compile_use(zend_ast *ast) /* {{{ */ { zend_ast_list *list = zend_ast_get_list(ast); @@ -6439,6 +6459,9 @@ void zend_compile_stmt(zend_ast *ast) /* {{{ */ case ZEND_AST_CLASS: zend_compile_class_decl(ast); break; + case ZEND_AST_BATCH_USE: + zend_compile_batch_use(ast); + break; case ZEND_AST_USE: zend_compile_use(ast); break; diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index a9794f6fac..1bded228ab 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -229,6 +229,7 @@ static YYSIZE_T zend_yytnamerr(char*, const char*); %type <ast> top_statement namespace_name name statement function_declaration_statement %type <ast> class_declaration_statement trait_declaration_statement %type <ast> interface_declaration_statement interface_extends_list +%type <ast> batch_use_declarations inline_use_declarations inline_use_declaration %type <ast> use_declaration const_decl inner_statement %type <ast> expr optional_expr while_statement for_statement foreach_variable %type <ast> foreach_statement declare_statement finally_statement unset_variable variable @@ -297,12 +298,34 @@ top_statement: | T_NAMESPACE { RESET_DOC_COMMENT(); } '{' top_statement_list '}' { $$ = zend_ast_create(ZEND_AST_NAMESPACE, NULL, $4); } + | T_USE batch_use_declarations ';' { $$ = $2; } | T_USE use_declarations ';' { $$ = $2; $$->attr = T_CLASS; } | T_USE T_FUNCTION use_declarations ';' { $$ = $3; $$->attr = T_FUNCTION; } | T_USE T_CONST use_declarations ';' { $$ = $3; $$->attr = T_CONST; } | T_CONST const_list ';' { $$ = $2; } ; +batch_use_declarations: + namespace_name '{' inline_use_declarations '}' + {$$ = zend_ast_create(ZEND_AST_BATCH_USE, $1, $3);} +; + +inline_use_declarations: + inline_use_declarations ',' inline_use_declaration + { $$ = zend_ast_list_add($1, $3); } + | inline_use_declaration + { $$ = zend_ast_create_list(1, ZEND_AST_USE, $1); } +; + +inline_use_declaration: + use_declaration + { $$ = $1; $$->attr = T_CLASS; } + | T_FUNCTION use_declaration + { $$ = $2; $$->attr = T_FUNCTION; } + | T_CONST use_declaration + { $$ = $2; $$->attr = T_CONST; } +; + use_declarations: use_declarations ',' use_declaration { $$ = zend_ast_list_add($1, $3); } |