Skip to content

Commit d60bc0e

Browse files
authored
Support doc comments on enum cases (#6984)
Because php supports doc comments on class constants, I believe it would also make sense to support them on enum cases. I don't have strong opinions about whether attributes should be moved to be the last element or whether the doc comment should go after the attribute, but the ast will likely change again before php 8.1 is stable. So far, all attributes are the last ast child node. I didn't notice that doc comments weren't implemented due to #6489 being a large change. https://wiki.php.net/rfc/enumerations did not mention whether or not doc comments were meant to be supported
1 parent 87e4970 commit d60bc0e

File tree

5 files changed

+39
-10
lines changed

5 files changed

+39
-10
lines changed

Zend/zend_ast.c

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2201,8 +2201,8 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio
22012201
zend_ast_export_name(str, ast->child[1], 0, indent);
22022202
APPEND_DEFAULT_VALUE(2);
22032203
case ZEND_AST_ENUM_CASE:
2204-
if (ast->child[2]) {
2205-
zend_ast_export_attributes(str, ast->child[2], indent, 1);
2204+
if (ast->child[3]) {
2205+
zend_ast_export_attributes(str, ast->child[3], indent, 1);
22062206
}
22072207
smart_str_appends(str, "case ");
22082208
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)
23292329
ast->child[2] = attr;
23302330
break;
23312331
case ZEND_AST_PARAM:
2332+
case ZEND_AST_ENUM_CASE:
23322333
ast->child[3] = attr;
23332334
break;
23342335
case ZEND_AST_CLASS_CONST_GROUP:
23352336
ast->child[1] = attr;
23362337
break;
2337-
case ZEND_AST_ENUM_CASE:
2338-
ast->child[2] = attr;
2339-
break;
23402338
EMPTY_SWITCH_DEFAULT_CASE()
23412339
}
23422340

Zend/zend_ast.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,14 +159,14 @@ enum _zend_ast_kind {
159159
ZEND_AST_PROP_GROUP,
160160
ZEND_AST_PROP_ELEM,
161161
ZEND_AST_CONST_ELEM,
162-
ZEND_AST_ENUM_CASE,
163162

164163
// Pseudo node for initializing enums
165164
ZEND_AST_CONST_ENUM_INIT,
166165

167166
/* 4 child nodes */
168167
ZEND_AST_FOR = 4 << ZEND_AST_NUM_CHILDREN_SHIFT,
169168
ZEND_AST_FOREACH,
169+
ZEND_AST_ENUM_CASE,
170170

171171
/* 5 child nodes */
172172
ZEND_AST_PARAM = 5 << ZEND_AST_NUM_CHILDREN_SHIFT,

Zend/zend_compile.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7748,11 +7748,19 @@ static void zend_compile_enum_case(zend_ast *ast)
77487748

77497749
zval value_zv;
77507750
zend_const_expr_to_zval(&value_zv, &const_enum_init_ast);
7751-
zend_class_constant *c = zend_declare_class_constant_ex(enum_class, enum_case_name, &value_zv, ZEND_ACC_PUBLIC, NULL);
7751+
7752+
/* Doc comment has been appended as second last element in ZEND_AST_ENUM ast - attributes are conventionally last */
7753+
zend_ast *doc_comment_ast = ast->child[2];
7754+
zend_string *doc_comment = NULL;
7755+
if (doc_comment_ast) {
7756+
doc_comment = zend_string_copy(zend_ast_get_str(doc_comment_ast));
7757+
}
7758+
7759+
zend_class_constant *c = zend_declare_class_constant_ex(enum_class, enum_case_name, &value_zv, ZEND_ACC_PUBLIC, doc_comment);
77527760
ZEND_CLASS_CONST_FLAGS(c) |= ZEND_CLASS_CONST_IS_CASE;
77537761
zend_ast_destroy(const_enum_init_ast);
77547762

7755-
zend_ast *attr_ast = ast->child[2];
7763+
zend_ast *attr_ast = ast->child[3];
77567764
if (attr_ast) {
77577765
zend_compile_attributes(&c->attributes, attr_ast, 0, ZEND_ATTRIBUTE_TARGET_CLASS_CONST);
77587766
}

Zend/zend_language_parser.y

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -607,8 +607,8 @@ enum_backing_type:
607607
;
608608

609609
enum_case:
610-
T_CASE identifier enum_case_expr ';'
611-
{ $$ = zend_ast_create(ZEND_AST_ENUM_CASE, $2, $3, NULL); }
610+
T_CASE backup_doc_comment identifier enum_case_expr ';'
611+
{ $$ = zend_ast_create(ZEND_AST_ENUM_CASE, $3, $4, ($2 ? zend_ast_create_zval_from_str($2) : NULL), NULL); }
612612
;
613613

614614
enum_case_expr:
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
--TEST--
2+
ReflectionEnumUnitCase::getDocComment()
3+
--FILE--
4+
<?php
5+
// enum cases should support doc comments, like class constants.
6+
7+
enum Foo {
8+
/** Example doc comment */
9+
case Bar;
10+
case Baz;
11+
}
12+
13+
var_dump((new ReflectionEnumUnitCase(Foo::class, 'Bar'))->getDocComment());
14+
var_dump((new ReflectionEnumUnitCase(Foo::class, 'Baz'))->getDocComment());
15+
var_dump((new ReflectionClassConstant(Foo::class, 'Bar'))->getDocComment());
16+
var_dump((new ReflectionClassConstant(Foo::class, 'Baz'))->getDocComment());
17+
18+
?>
19+
--EXPECT--
20+
string(26) "/** Example doc comment */"
21+
bool(false)
22+
string(26) "/** Example doc comment */"
23+
bool(false)

0 commit comments

Comments
 (0)