From ddb6d7801e5dfc2f196b549b8ad51376cdc1bc90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rcio=20Almada?= Date: Tue, 6 Oct 2015 17:32:23 -0300 Subject: [PATCH] Fix bug #70650 --- NEWS | 5 ++- Zend/zend_ast.h | 2 +- Zend/zend_compile.c | 29 ++++--------- Zend/zend_compile.h | 1 - Zend/zend_language_parser.y | 9 ++-- ...ionMethod_getDocComment_property_list.phpt | 41 +++++++++++++++++++ 6 files changed, 58 insertions(+), 29 deletions(-) create mode 100644 ext/reflection/tests/ReflectionMethod_getDocComment_property_list.phpt diff --git a/NEWS b/NEWS index d641dddb873..1bfcfffbae8 100644 --- a/NEWS +++ b/NEWS @@ -6,9 +6,12 @@ PHP NEWS . Fixed bug #70625 (mcrypt_encrypt() won't return data when no IV was specified under RC4). (Nikita) -- Phpdbg +- Phpdbg: . Fixed bug #70614 (incorrect exit code in -rr mode with Exceptions). (Bob) +- Reflection: + . Fixed bug #70650 (Wrong docblock assignment). (Marcio) + 01 Oct 2015, PHP 7.0.0 RC 4 - Core: diff --git a/Zend/zend_ast.h b/Zend/zend_ast.h index 2b8d4d37b8b..2defa1c2b3d 100644 --- a/Zend/zend_ast.h +++ b/Zend/zend_ast.h @@ -124,7 +124,6 @@ enum _zend_ast_kind { ZEND_AST_SWITCH, ZEND_AST_SWITCH_CASE, ZEND_AST_DECLARE, - ZEND_AST_PROP_ELEM, ZEND_AST_CONST_ELEM, ZEND_AST_USE_TRAIT, ZEND_AST_TRAIT_PRECEDENCE, @@ -142,6 +141,7 @@ enum _zend_ast_kind { ZEND_AST_TRY, ZEND_AST_CATCH, ZEND_AST_PARAM, + ZEND_AST_PROP_ELEM, /* 4 child nodes */ ZEND_AST_FOR = 4 << ZEND_AST_NUM_CHILDREN_SHIFT, diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 98af0a7c746..26655ad7954 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -1703,18 +1703,6 @@ zend_ast *zend_ast_append_str(zend_ast *left_ast, zend_ast *right_ast) /* {{{ */ } /* }}} */ -/* A hacky way that is used to store the doc comment for properties */ -zend_ast *zend_ast_append_doc_comment(zend_ast *list) /* {{{ */ -{ - if (CG(doc_comment)) { - list = zend_ast_list_add(list, zend_ast_create_zval_from_str(CG(doc_comment))); - CG(doc_comment) = NULL; - } - - return list; -} -/* }}} */ - void zend_verify_namespace(void) /* {{{ */ { if (FC(has_bracketed_namespaces) && !FC(in_namespace)) { @@ -4914,7 +4902,6 @@ void zend_compile_prop_decl(zend_ast *ast) /* {{{ */ uint32_t flags = list->attr; zend_class_entry *ce = CG(active_class_entry); uint32_t i, children = list->children; - zend_string *doc_comment = NULL; if (ce->ce_flags & ZEND_ACC_INTERFACE) { zend_error_noreturn(E_COMPILE_ERROR, "Interfaces may not include member variables"); @@ -4924,19 +4911,20 @@ void zend_compile_prop_decl(zend_ast *ast) /* {{{ */ zend_error_noreturn(E_COMPILE_ERROR, "Properties cannot be declared abstract"); } - /* Doc comment has been appended as last element in property list */ - if (list->child[children - 1]->kind == ZEND_AST_ZVAL) { - doc_comment = zend_string_copy(zend_ast_get_str(list->child[children - 1])); - children -= 1; - } - for (i = 0; i < children; ++i) { zend_ast *prop_ast = list->child[i]; zend_ast *name_ast = prop_ast->child[0]; zend_ast *value_ast = prop_ast->child[1]; + zend_ast *doc_comment_ast = prop_ast->child[2]; zend_string *name = zend_ast_get_str(name_ast); + zend_string *doc_comment = NULL; zval value_zv; + /* Doc comment has been appended as last element in ZEND_AST_PROP_ELEM ast */ + if (doc_comment_ast) { + doc_comment = zend_string_copy(zend_ast_get_str(doc_comment_ast)); + } + if (flags & ZEND_ACC_FINAL) { zend_error_noreturn(E_COMPILE_ERROR, "Cannot declare property %s::$%s final, " "the final modifier is allowed only for methods and classes", @@ -4956,9 +4944,6 @@ void zend_compile_prop_decl(zend_ast *ast) /* {{{ */ name = zend_new_interned_string_safe(name); zend_declare_property_ex(ce, name, &value_zv, flags, doc_comment); - - /* Doc comment is only assigned to first property */ - doc_comment = NULL; } } /* }}} */ diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index 68cc39ad841..b777a0ba8c2 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -698,7 +698,6 @@ void zend_emit_final_return(zval *zv); zend_ast *zend_ast_append_str(zend_ast *left, zend_ast *right); uint32_t zend_add_class_modifier(uint32_t flags, uint32_t new_flag); uint32_t zend_add_member_modifier(uint32_t flags, uint32_t new_flag); -zend_ast *zend_ast_append_doc_comment(zend_ast *list); void zend_handle_encoding_declaration(zend_ast *ast); /* parser-driven code generators */ diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index c52c252f6c2..dde76351e9e 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -700,7 +700,7 @@ class_statement_list: class_statement: variable_modifiers property_list ';' - { $$ = zend_ast_append_doc_comment($2); $$->attr = $1; } + { $$ = $2; $$->attr = $1; } | T_CONST class_const_list ';' { $$ = $2; RESET_DOC_COMMENT(); } | T_USE name_list trait_adaptations @@ -798,9 +798,10 @@ property_list: ; property: - T_VARIABLE { $$ = zend_ast_create(ZEND_AST_PROP_ELEM, $1, NULL); } - | T_VARIABLE '=' expr - { $$ = zend_ast_create(ZEND_AST_PROP_ELEM, $1, $3); } + T_VARIABLE backup_doc_comment + { $$ = zend_ast_create(ZEND_AST_PROP_ELEM, $1, NULL, ($2 ? zend_ast_create_zval_from_str($2) : NULL)); } + | T_VARIABLE '=' expr backup_doc_comment + { $$ = zend_ast_create(ZEND_AST_PROP_ELEM, $1, $3, ($4 ? zend_ast_create_zval_from_str($4) : NULL)); } ; class_const_list: diff --git a/ext/reflection/tests/ReflectionMethod_getDocComment_property_list.phpt b/ext/reflection/tests/ReflectionMethod_getDocComment_property_list.phpt new file mode 100644 index 00000000000..4719571124f --- /dev/null +++ b/ext/reflection/tests/ReflectionMethod_getDocComment_property_list.phpt @@ -0,0 +1,41 @@ +--TEST-- +ReflectionMethod::getDocComment() +--INI-- +opcache.save_comments=1 +--FILE-- +getDocComment()); + +$reflection = new ReflectionProperty('\X', 'y'); +echo 'X::y', PHP_EOL; +var_dump($reflection->getDocComment()); + +$reflection = new ReflectionProperty('\X', 'z'); +echo 'X::z', PHP_EOL; +var_dump($reflection->getDocComment()); +?> +--EXPECTF-- +X::x +string(24) "/** + * doc 1 + */" +X::y +bool(false) +X::z +string(12) "/** doc 2 */"