Skip to content

Commit bd868b6

Browse files
committed
feat(zend): allow generic type arguments on array, iterable, self, static, and parent
Signed-off-by: azjezz <azjezz@protonmail.com>
1 parent 841bfe9 commit bd868b6

3 files changed

Lines changed: 30 additions & 5 deletions

File tree

Zend/zend_ast.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2065,7 +2065,13 @@ static ZEND_COLD void zend_ast_export_type(smart_str *str, zend_ast *ast, int in
20652065
if (ast->attr & ZEND_TYPE_NULLABLE) {
20662066
smart_str_appendc(str, '?');
20672067
}
2068-
zend_ast_export_ns_name(str, ast->child[0], 0, indent);
2068+
2069+
zend_ast *name_ast = ast->child[0];
2070+
if (name_ast->kind == ZEND_AST_TYPE) {
2071+
zend_ast_export_type(str, name_ast, indent);
2072+
} else {
2073+
zend_ast_export_ns_name(str, name_ast, 0, indent);
2074+
}
20692075
zend_ast_export_generic_type_argument_list(str, ast->child[1], indent);
20702076
return;
20712077
}

Zend/zend_compile.c

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -579,12 +579,27 @@ static zend_type zend_compile_pre_erasure_typename(zend_ast *ast)
579579
zend_ast *name_ast = ast->child[0];
580580
zend_ast_list *args_list = zend_ast_get_list(ast->child[1]);
581581
zend_type_named_with_args *payload = emalloc(ZEND_TYPE_NAMED_WITH_ARGS_SIZE(args_list->children));
582-
payload->name = zend_string_copy(zval_make_interned_string(zend_ast_get_zval(name_ast)));
583-
payload->name_attr = name_ast->attr;
582+
if (name_ast->kind == ZEND_AST_TYPE) {
583+
const char *cname;
584+
switch (name_ast->attr) {
585+
case IS_ARRAY: cname = "array"; break;
586+
case IS_STATIC: cname = "static"; break;
587+
default:
588+
ZEND_UNREACHABLE();
589+
}
590+
591+
payload->name = zend_string_init_interned(cname, strlen(cname), 0);
592+
payload->name_attr = 0;
593+
} else {
594+
payload->name = zend_string_copy(zval_make_interned_string(zend_ast_get_zval(name_ast)));
595+
payload->name_attr = name_ast->attr;
596+
}
597+
584598
payload->count = args_list->children;
585599
for (uint32_t i = 0; i < args_list->children; i++) {
586600
payload->args[i] = zend_compile_pre_erasure_typename(args_list->child[i]);
587601
}
602+
588603
ZEND_TYPE_SET_PTR(result, payload);
589604
ZEND_TYPE_FULL_MASK(result) |= _ZEND_TYPE_NAMED_WITH_ARGS_BIT;
590605
} else if (ast->kind == ZEND_AST_TYPE) {

Zend/zend_language_parser.y

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -943,7 +943,9 @@ type_expr:
943943

944944
type:
945945
type_without_static { $$ = $1; }
946-
| T_STATIC { $$ = zend_ast_create_ex(ZEND_AST_TYPE, IS_STATIC); }
946+
| T_STATIC optional_generic_type_argument_list
947+
{ zend_ast *bare = zend_ast_create_ex(ZEND_AST_TYPE, IS_STATIC);
948+
$$ = $2 ? zend_ast_create(ZEND_AST_GENERIC_NAMED_TYPE, bare, $2) : bare; }
947949
;
948950

949951
union_type_element:
@@ -974,7 +976,9 @@ type_expr_without_static:
974976
;
975977

976978
type_without_static:
977-
T_ARRAY { $$ = zend_ast_create_ex(ZEND_AST_TYPE, IS_ARRAY); }
979+
T_ARRAY optional_generic_type_argument_list
980+
{ zend_ast *bare = zend_ast_create_ex(ZEND_AST_TYPE, IS_ARRAY);
981+
$$ = $2 ? zend_ast_create(ZEND_AST_GENERIC_NAMED_TYPE, bare, $2) : bare; }
978982
| T_CALLABLE { $$ = zend_ast_create_ex(ZEND_AST_TYPE, IS_CALLABLE); }
979983
| name optional_generic_type_argument_list
980984
{ $$ = $2 ? zend_ast_create(ZEND_AST_GENERIC_NAMED_TYPE, $1, $2) : $1; }

0 commit comments

Comments
 (0)