diff --git a/Zend/zend_ast.c b/Zend/zend_ast.c index a09c13fd89ece..0d4a9dff5aaff 100644 --- a/Zend/zend_ast.c +++ b/Zend/zend_ast.c @@ -2201,8 +2201,8 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio zend_ast_export_name(str, ast->child[1], 0, indent); APPEND_DEFAULT_VALUE(2); case ZEND_AST_ENUM_CASE: - if (ast->child[2]) { - zend_ast_export_attributes(str, ast->child[2], indent, 1); + if (ast->child[3]) { + zend_ast_export_attributes(str, ast->child[3], indent, 1); } smart_str_appends(str, "case "); zend_ast_export_name(str, ast->child[0], 0, indent); @@ -2329,14 +2329,12 @@ zend_ast * ZEND_FASTCALL zend_ast_with_attributes(zend_ast *ast, zend_ast *attr) ast->child[2] = attr; break; case ZEND_AST_PARAM: + case ZEND_AST_ENUM_CASE: ast->child[3] = attr; break; case ZEND_AST_CLASS_CONST_GROUP: ast->child[1] = attr; break; - case ZEND_AST_ENUM_CASE: - ast->child[2] = attr; - break; EMPTY_SWITCH_DEFAULT_CASE() } diff --git a/Zend/zend_ast.h b/Zend/zend_ast.h index fb6587b48cd31..0e3468ebde110 100644 --- a/Zend/zend_ast.h +++ b/Zend/zend_ast.h @@ -159,7 +159,6 @@ enum _zend_ast_kind { ZEND_AST_PROP_GROUP, ZEND_AST_PROP_ELEM, ZEND_AST_CONST_ELEM, - ZEND_AST_ENUM_CASE, // Pseudo node for initializing enums ZEND_AST_CONST_ENUM_INIT, @@ -167,6 +166,7 @@ enum _zend_ast_kind { /* 4 child nodes */ ZEND_AST_FOR = 4 << ZEND_AST_NUM_CHILDREN_SHIFT, ZEND_AST_FOREACH, + ZEND_AST_ENUM_CASE, /* 5 child nodes */ ZEND_AST_PARAM = 5 << ZEND_AST_NUM_CHILDREN_SHIFT, diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 1a884206fd7c8..ee01dee43f47c 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -7748,11 +7748,19 @@ static void zend_compile_enum_case(zend_ast *ast) zval value_zv; zend_const_expr_to_zval(&value_zv, &const_enum_init_ast); - zend_class_constant *c = zend_declare_class_constant_ex(enum_class, enum_case_name, &value_zv, ZEND_ACC_PUBLIC, NULL); + + /* Doc comment has been appended as second last element in ZEND_AST_ENUM ast - attributes are conventionally last */ + zend_ast *doc_comment_ast = ast->child[2]; + zend_string *doc_comment = NULL; + if (doc_comment_ast) { + doc_comment = zend_string_copy(zend_ast_get_str(doc_comment_ast)); + } + + zend_class_constant *c = zend_declare_class_constant_ex(enum_class, enum_case_name, &value_zv, ZEND_ACC_PUBLIC, doc_comment); ZEND_CLASS_CONST_FLAGS(c) |= ZEND_CLASS_CONST_IS_CASE; zend_ast_destroy(const_enum_init_ast); - zend_ast *attr_ast = ast->child[2]; + zend_ast *attr_ast = ast->child[3]; if (attr_ast) { zend_compile_attributes(&c->attributes, attr_ast, 0, ZEND_ATTRIBUTE_TARGET_CLASS_CONST); } diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index fcbdcb622261b..917a34b8c3c29 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -607,8 +607,8 @@ enum_backing_type: ; enum_case: - T_CASE identifier enum_case_expr ';' - { $$ = zend_ast_create(ZEND_AST_ENUM_CASE, $2, $3, NULL); } + T_CASE backup_doc_comment identifier enum_case_expr ';' + { $$ = zend_ast_create(ZEND_AST_ENUM_CASE, $3, $4, ($2 ? zend_ast_create_zval_from_str($2) : NULL), NULL); } ; enum_case_expr: diff --git a/ext/reflection/tests/ReflectionEnumUnitCase_getDocComment.phpt b/ext/reflection/tests/ReflectionEnumUnitCase_getDocComment.phpt new file mode 100644 index 0000000000000..d51543601d917 --- /dev/null +++ b/ext/reflection/tests/ReflectionEnumUnitCase_getDocComment.phpt @@ -0,0 +1,23 @@ +--TEST-- +ReflectionEnumUnitCase::getDocComment() +--FILE-- +getDocComment()); +var_dump((new ReflectionEnumUnitCase(Foo::class, 'Baz'))->getDocComment()); +var_dump((new ReflectionClassConstant(Foo::class, 'Bar'))->getDocComment()); +var_dump((new ReflectionClassConstant(Foo::class, 'Baz'))->getDocComment()); + +?> +--EXPECT-- +string(26) "/** Example doc comment */" +bool(false) +string(26) "/** Example doc comment */" +bool(false)