From: Nikita Popov Date: Fri, 18 Jul 2014 13:23:16 +0000 (+0200) Subject: Handle function doc comments X-Git-Tag: POST_AST_MERGE^2~132 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=405b97e8a9c2f63a8e6d334227aa01b7ee9606ee;p=php Handle function doc comments --- diff --git a/Zend/zend_ast.c b/Zend/zend_ast.c index 4b87712e7c..891b36d9af 100644 --- a/Zend/zend_ast.c +++ b/Zend/zend_ast.c @@ -47,7 +47,8 @@ ZEND_API zend_ast *zend_ast_create_zval_ex(zval *zv, zend_ast_attr attr) ZEND_API zend_ast *zend_ast_create_func_decl( zend_ast_kind kind, zend_bool returns_ref, zend_uint start_lineno, zend_uint end_lineno, - unsigned char *lex_pos, zend_string *name, zend_ast *params, zend_ast *uses, zend_ast *stmt + unsigned char *lex_pos, zend_string *doc_comment, zend_string *name, + zend_ast *params, zend_ast *uses, zend_ast *stmt ) { zend_ast_func_decl *ast = emalloc(sizeof(zend_ast_func_decl)); @@ -56,6 +57,7 @@ ZEND_API zend_ast *zend_ast_create_func_decl( ast->start_lineno = start_lineno; ast->end_lineno = end_lineno; ast->lex_pos = lex_pos; + ast->doc_comment = doc_comment; ast->name = name; ast->params = params; ast->uses = uses; @@ -349,6 +351,9 @@ ZEND_API void zend_ast_destroy(zend_ast *ast) { zend_ast_func_decl *fn = (zend_ast_func_decl *) ast; STR_RELEASE(fn->name); + if (fn->doc_comment) { + STR_RELEASE(fn->doc_comment); + } zend_ast_destroy(fn->params); zend_ast_destroy(fn->uses); zend_ast_destroy(fn->stmt); diff --git a/Zend/zend_ast.h b/Zend/zend_ast.h index 87cbe9c98e..d3eca8117c 100644 --- a/Zend/zend_ast.h +++ b/Zend/zend_ast.h @@ -129,6 +129,7 @@ typedef struct _zend_ast_func_decl { zend_uint start_lineno; zend_uint end_lineno; unsigned char *lex_pos; + zend_string *doc_comment; zend_string *name; zend_ast *params; zend_ast *uses; @@ -148,7 +149,8 @@ ZEND_API zend_ast *zend_ast_create( ZEND_API zend_ast *zend_ast_create_func_decl( zend_ast_kind kind, zend_bool by_ref, zend_uint start_lineno, zend_uint end_lineno, - unsigned char *lex_pos, zend_string *name, zend_ast *params, zend_ast *uses, zend_ast *stmt + unsigned char *lex_pos, zend_string *doc_comment, zend_string *name, + zend_ast *params, zend_ast *uses, zend_ast *stmt ); ZEND_API zend_ast *zend_ast_create_dynamic(zend_ast_kind kind); diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 9f5c4a6fee..e6e641abf0 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -1047,7 +1047,7 @@ void zend_do_begin_function_declaration(znode *function_token, znode *function_n { zend_op_array op_array; zend_string *name = Z_STR(function_name->u.constant); - int function_begin_line = function_token->u.op.opline_num; + int function_begin_line = function_token->EA; zend_uint fn_flags; zend_string *lcname; zend_bool orig_interactive; @@ -7025,6 +7025,9 @@ void zend_compile_func_decl(znode *result, zend_ast *ast TSRMLS_DC) { op_array->line_start = fn->start_lineno; op_array->line_end = fn->end_lineno; + if (fn->doc_comment) { + op_array->doc_comment = STR_COPY(fn->doc_comment); + } if (fn->returns_ref) { op_array->fn_flags |= ZEND_ACC_RETURN_REFERENCE; } diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index f6471008ca..68049e098f 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -390,7 +390,7 @@ unset_variable: function_declaration_statement: function is_reference T_STRING '(' parameter_list ')' '{' inner_statement_list '}' { $$.u.ast = zend_ast_create_func_decl(ZEND_AST_FUNC_DECL, $2.op_type, - $1.u.op.opline_num, CG(zend_lineno), LANG_SCNG(yy_text), + $1.EA, CG(zend_lineno), LANG_SCNG(yy_text), $1.u.op.ptr, Z_STR($3.u.constant), $5.u.ast, NULL, $8.u.ast); } ; @@ -629,7 +629,7 @@ class_statement: variable_modifiers { CG(access_type) = Z_LVAL($1.u.constant); } class_variable_declaration ';' | class_constant_declaration ';' | trait_use_statement - | method_modifiers function is_reference T_STRING { zend_do_begin_function_declaration(&$2, &$4, 1, $3.op_type, &$1 TSRMLS_CC); } + | method_modifiers function2 is_reference T_STRING { zend_do_begin_function_declaration(&$2, &$4, 1, $3.op_type, &$1 TSRMLS_CC); } '(' parameter_list ')' { zend_compile_params($7.u.ast TSRMLS_CC); zend_ast_destroy($7.u.ast); } method_body { zend_do_abstract_method(&$4, &$1, &$10 TSRMLS_CC); zend_do_end_function_declaration(&$2 TSRMLS_CC); } ; @@ -872,16 +872,21 @@ expr_without_variable: { $$.u.ast = zend_ast_create_binary(ZEND_YIELD, $4.u.ast, $2.u.ast); } | function is_reference '(' parameter_list ')' lexical_vars '{' inner_statement_list '}' { $$.u.ast = zend_ast_create_func_decl(ZEND_AST_CLOSURE, $2.op_type, - $1.u.op.opline_num, CG(zend_lineno), LANG_SCNG(yy_text), + $1.EA, CG(zend_lineno), LANG_SCNG(yy_text), $1.u.op.ptr, STR_INIT("{closure}", sizeof("{closure}") - 1, 0), $4.u.ast, $6.u.ast, $8.u.ast); } - | T_STATIC function is_reference { zend_do_begin_lambda_function_declaration(&$$, &$2, $3.op_type, 1 TSRMLS_CC); } + | T_STATIC function2 is_reference { zend_do_begin_lambda_function_declaration(&$$, &$2, $3.op_type, 1 TSRMLS_CC); } '(' parameter_list ')' { zend_compile_params($6.u.ast TSRMLS_CC); zend_ast_destroy($6.u.ast); } lexical_vars { zend_compile_closure_uses($9.u.ast TSRMLS_CC); if ($9.u.ast) zend_ast_destroy($9.u.ast); } '{' inner_statement_list '}' { AS($12); zend_do_end_function_declaration(&$2 TSRMLS_CC); $$.u.ast = AST_ZNODE(&$4); } ; function: - T_FUNCTION { $$.u.op.opline_num = CG(zend_lineno); } + T_FUNCTION + { $$.EA = CG(zend_lineno); $$.u.op.ptr = CG(doc_comment); CG(doc_comment) = NULL; } +; + +function2: + T_FUNCTION { $$.EA = CG(zend_lineno); } ; lexical_vars: