]> granicus.if.org Git - php/commitdiff
Fix bug #70650
authorMárcio Almada <marcio3w@gmail.com>
Tue, 6 Oct 2015 20:32:23 +0000 (17:32 -0300)
committerNikita Popov <nikic@php.net>
Wed, 7 Oct 2015 14:25:59 +0000 (16:25 +0200)
NEWS
Zend/zend_ast.h
Zend/zend_compile.c
Zend/zend_compile.h
Zend/zend_language_parser.y
ext/reflection/tests/ReflectionMethod_getDocComment_property_list.phpt [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index d641dddb87382b66af3aea70dc28949cceb958c7..1bfcfffbae873ded92c9797af03e9d45e816a24f 100644 (file)
--- 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:
index 2b8d4d37b8bd4cb157536a5375c7a312062ce68d..2defa1c2b3dcff3801499fe630772e176354df47 100644 (file)
@@ -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,
index 98af0a7c7464036ccd2605fab30560fbc8264968..26655ad795428fdc7d94ed55994130bf039a02ba 100644 (file)
@@ -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;
        }
 }
 /* }}} */
index 68cc39ad8419e25559d4d048da2b9868ac5c1734..b777a0ba8c26672846940e7abf3c4cd9eaa0644b 100644 (file)
@@ -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 */
index c52c252f6c27993b67020ee2bf57f396efe91635..dde76351e9e7aa041cf468efbd8ac32668b9105d 100644 (file)
@@ -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 (file)
index 0000000..4719571
--- /dev/null
@@ -0,0 +1,41 @@
+--TEST--
+ReflectionMethod::getDocComment()
+--INI--
+opcache.save_comments=1
+--FILE--
+<?php
+
+class X {
+    /**
+     * doc 1
+     */
+    // Some comment
+    public
+        $x = "x",
+        $y = 'y',
+        /** doc 2 */
+        $z = 'z'
+    ;
+}
+
+$reflection = new ReflectionProperty('\X', 'x');
+echo 'X::x', PHP_EOL;
+var_dump($reflection->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 */"