Skip to content

Commit 67f8bea

Browse files
committed
modify grammar
Now we modify the grammar to allow specifying visibility on a class.
1 parent ab38c00 commit 67f8bea

File tree

3 files changed

+53
-5
lines changed

3 files changed

+53
-5
lines changed

Zend/zend_compile.c

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -893,20 +893,21 @@ uint32_t zend_modifier_token_to_flag(zend_modifier_target target, uint32_t token
893893
}
894894
break;
895895
case T_READONLY:
896-
if (target == ZEND_MODIFIER_TARGET_PROPERTY || target == ZEND_MODIFIER_TARGET_CPP) {
896+
if (target == ZEND_MODIFIER_TARGET_PROPERTY || target == ZEND_MODIFIER_TARGET_CPP || target == ZEND_MODIFIER_TARGET_NESTED_CLASS) {
897897
return ZEND_ACC_READONLY;
898898
}
899899
break;
900900
case T_ABSTRACT:
901-
if (target == ZEND_MODIFIER_TARGET_METHOD || target == ZEND_MODIFIER_TARGET_PROPERTY) {
901+
if (target == ZEND_MODIFIER_TARGET_METHOD || target == ZEND_MODIFIER_TARGET_PROPERTY || target == ZEND_MODIFIER_TARGET_NESTED_CLASS) {
902902
return ZEND_ACC_ABSTRACT;
903903
}
904904
break;
905905
case T_FINAL:
906906
if (target == ZEND_MODIFIER_TARGET_METHOD
907907
|| target == ZEND_MODIFIER_TARGET_CONSTANT
908908
|| target == ZEND_MODIFIER_TARGET_PROPERTY
909-
|| target == ZEND_MODIFIER_TARGET_PROPERTY_HOOK) {
909+
|| target == ZEND_MODIFIER_TARGET_PROPERTY_HOOK
910+
|| target == ZEND_MODIFIER_TARGET_NESTED_CLASS) {
910911
return ZEND_ACC_FINAL;
911912
}
912913
break;
@@ -943,6 +944,8 @@ uint32_t zend_modifier_token_to_flag(zend_modifier_target target, uint32_t token
943944
member = "parameter";
944945
} else if (target == ZEND_MODIFIER_TARGET_PROPERTY_HOOK) {
945946
member = "property hook";
947+
} else if (target == ZEND_MODIFIER_TARGET_NESTED_CLASS) {
948+
member = "nested class";
946949
} else {
947950
ZEND_UNREACHABLE();
948951
}
@@ -1050,6 +1053,37 @@ uint32_t zend_add_member_modifier(uint32_t flags, uint32_t new_flag, zend_modifi
10501053
return 0;
10511054
}
10521055
}
1056+
if (target == ZEND_MODIFIER_TARGET_NESTED_CLASS) {
1057+
if ((flags & ZEND_ACC_PPP_MASK) && (new_flag & ZEND_ACC_PPP_MASK)) {
1058+
zend_throw_exception(zend_ce_compile_error,
1059+
"Multiple access type modifiers are not allowed", 0);
1060+
return 0;
1061+
}
1062+
1063+
if ((flags & ZEND_ACC_STATIC) || (new_flag & ZEND_ACC_STATIC)) {
1064+
zend_throw_exception(zend_ce_compile_error,
1065+
"Static inner classes are not allowed", 0);
1066+
return 0;
1067+
}
1068+
1069+
if ((flags & ZEND_ACC_PUBLIC_SET) || (new_flag & ZEND_ACC_PUBLIC_SET)) {
1070+
zend_throw_exception(zend_ce_compile_error,
1071+
"Public(set) inner classes are not allowed", 0);
1072+
return 0;
1073+
}
1074+
1075+
if ((flags & ZEND_ACC_PROTECTED_SET) || (new_flag & ZEND_ACC_PROTECTED_SET)) {
1076+
zend_throw_exception(zend_ce_compile_error,
1077+
"Protected(set) inner classes are not allowed", 0);
1078+
return 0;
1079+
}
1080+
1081+
if ((flags & ZEND_ACC_PRIVATE_SET) || (new_flag & ZEND_ACC_PRIVATE_SET)) {
1082+
zend_throw_exception(zend_ce_compile_error,
1083+
"Private(set) inner classes are not allowed", 0);
1084+
return 0;
1085+
}
1086+
}
10531087
return new_flags;
10541088
}
10551089
/* }}} */

Zend/zend_compile.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -894,6 +894,7 @@ typedef enum {
894894
ZEND_MODIFIER_TARGET_CONSTANT,
895895
ZEND_MODIFIER_TARGET_CPP,
896896
ZEND_MODIFIER_TARGET_PROPERTY_HOOK,
897+
ZEND_MODIFIER_TARGET_NESTED_CLASS,
897898
} zend_modifier_target;
898899

899900
/* Used during AST construction */

Zend/zend_language_parser.y

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -285,10 +285,10 @@ static YYSIZE_T zend_yytnamerr(char*, const char*);
285285
%type <ast> enum_declaration_statement enum_backing_type enum_case enum_case_expr
286286
%type <ast> function_name non_empty_member_modifiers
287287
%type <ast> property_hook property_hook_list optional_property_hook_list hooked_property property_hook_body
288-
%type <ast> optional_parameter_list
288+
%type <ast> optional_parameter_list nested_class_statement
289289

290290
%type <num> returns_ref function fn is_reference is_variadic property_modifiers property_hook_modifiers
291-
%type <num> method_modifiers class_const_modifiers member_modifier optional_cpp_modifiers
291+
%type <num> method_modifiers class_const_modifiers member_modifier optional_cpp_modifiers nested_class_modifiers
292292
%type <num> class_modifiers class_modifier anonymous_class_modifiers anonymous_class_modifiers_optional use_type backup_fn_flags
293293

294294
%type <ptr> backup_lex_pos
@@ -628,6 +628,14 @@ class_modifier:
628628
| T_READONLY { $$ = ZEND_ACC_READONLY_CLASS|ZEND_ACC_NO_DYNAMIC_PROPERTIES; }
629629
;
630630

631+
nested_class_modifiers:
632+
non_empty_member_modifiers
633+
{ $$ = zend_modifier_list_to_flags(ZEND_MODIFIER_TARGET_NESTED_CLASS, $1);
634+
if (!$$) { YYERROR; } }
635+
| %empty
636+
{ $$ = ZEND_ACC_PUBLIC; }
637+
;
638+
631639
trait_declaration_statement:
632640
T_TRAIT { $<num>$ = CG(zend_lineno); }
633641
T_STRING backup_doc_comment '{' class_statement_list '}'
@@ -943,6 +951,10 @@ class_statement_list:
943951
{ $$ = zend_ast_create_list(0, ZEND_AST_STMT_LIST); }
944952
;
945953

954+
nested_class_statement:
955+
T_CLASS T_STRING { $<num>$ = CG(zend_lineno); } extends_from implements_list backup_doc_comment '{' class_statement_list '}'
956+
{ $$ = zend_ast_create_decl(ZEND_AST_CLASS, 0, $<num>3, $6, zend_ast_get_str($2), $4, $5, $8, NULL, NULL); }
957+
;
946958

947959
attributed_class_statement:
948960
property_modifiers optional_type_without_static property_list ';'
@@ -962,6 +974,7 @@ attributed_class_statement:
962974
{ $$ = zend_ast_create_decl(ZEND_AST_METHOD, $3 | $1 | $12, $2, $5,
963975
zend_ast_get_str($4), $7, NULL, $11, $9, NULL); CG(extra_fn_flags) = $10; }
964976
| enum_case { $$ = $1; }
977+
| nested_class_modifiers nested_class_statement { $$ = $2; $$->attr = $1; }
965978
;
966979

967980
class_statement:

0 commit comments

Comments
 (0)