summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Zend/zend_ast.h1
-rw-r--r--Zend/zend_compile.c23
-rw-r--r--Zend/zend_language_parser.y23
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); }