Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 3a8b3d2

Browse files
committed
Fix AST and name resolution
1 parent 24bcdee commit 3a8b3d2

File tree

3 files changed

+112
-18
lines changed

3 files changed

+112
-18
lines changed

‎Zend/zend_ast.c

Lines changed: 53 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1569,6 +1569,16 @@ static ZEND_COLD void zend_ast_export_ns_name(smart_str *str, zend_ast *ast, int
15691569
zend_ast_export_ex(str, ast, priority, indent);
15701570
}
15711571

1572+
static ZEND_COLD void zend_ast_export_class_name(smart_str *str, zend_ast *ast, int priority, int indent)
1573+
{
1574+
if (ast->kind == ZEND_AST_CLASS_REF) {
1575+
ZEND_ASSERT(ast->child[1] == NULL && "Generic params not supported yet");
1576+
zend_ast_export_ns_name(str, ast->child[0], priority, indent);
1577+
return;
1578+
}
1579+
zend_ast_export_ex(str, ast, priority, indent);
1580+
}
1581+
15721582
static ZEND_COLD bool zend_ast_valid_var_char(char ch)
15731583
{
15741584
unsigned char c = (unsigned char)ch;
@@ -1689,7 +1699,7 @@ static ZEND_COLD void zend_ast_export_name_list_ex(smart_str *str, zend_ast_list
16891699
if (i != 0) {
16901700
smart_str_appends(str, separator);
16911701
}
1692-
zend_ast_export_name(str, list->child[i], 0, indent);
1702+
zend_ast_export_ns_name(str, list->child[i], 0, indent);
16931703
i++;
16941704
}
16951705
}
@@ -1956,6 +1966,21 @@ static ZEND_COLD void zend_ast_export_type(smart_str *str, zend_ast *ast, int in
19561966
zend_ast_export_ns_name(str, ast, 0, indent);
19571967
}
19581968

1969+
static ZEND_COLD void zend_ast_export_generic_arg_list(smart_str *str, const zend_ast_list *list, int indent) {
1970+
// TODO Why cannot I just use
1971+
// zend_ast_export_list(str, list, true, 0, indent);
1972+
// ?
1973+
1974+
uint32_t i = 0;
1975+
while (i < list->children) {
1976+
if (i != 0) {
1977+
smart_str_appends(str, ", ");
1978+
}
1979+
zend_ast_export_type(str, list->child[i], indent);
1980+
i++;
1981+
}
1982+
}
1983+
19591984
static ZEND_COLD void zend_ast_export_hook_list(smart_str *str, zend_ast_list *hook_list, int indent)
19601985
{
19611986
smart_str_appends(str, " {");
@@ -2155,10 +2180,17 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio
21552180
}
21562181
smart_str_appends(str, "class ");
21572182
}
2158-
smart_str_appendl(str, ZSTR_VAL(decl->name), ZSTR_LEN(decl->name));
2159-
if (decl->flags & ZEND_ACC_ENUM && decl->child[4]) {
2160-
smart_str_appends(str, ": ");
2161-
zend_ast_export_type(str, decl->child[4], indent);
2183+
smart_str_append(str, decl->name);
2184+
if (decl->child[4]) {
2185+
if (decl->flags & ZEND_ACC_ENUM) {
2186+
smart_str_appends(str, ": ");
2187+
zend_ast_export_type(str, decl->child[4], indent);
2188+
} else {
2189+
ZEND_ASSERT(decl->flags & ZEND_ACC_INTERFACE);
2190+
smart_str_appendc(str, '<');
2191+
zend_ast_export_list(str, zend_ast_get_list(decl->child[4]), true, 0, indent);
2192+
smart_str_appendc(str, '>');
2193+
}
21622194
}
21632195
zend_ast_export_class_no_header(str, decl, indent);
21642196
smart_str_appendc(str, '\n');
@@ -2443,6 +2475,21 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio
24432475
smart_str_appends(str, "::");
24442476
zend_ast_export_name(str, ast->child[1], 0, indent);
24452477
break;
2478+
case ZEND_AST_GENERIC_PARAM:
2479+
zend_ast_export_name(str, ast->child[0], 0, indent);
2480+
if (ast->child[1]) {
2481+
smart_str_appendl(str, ZEND_STRL(" : "));
2482+
zend_ast_export_type(str, ast->child[1], indent);
2483+
}
2484+
break;
2485+
case ZEND_AST_CLASS_REF:
2486+
zend_ast_export_ns_name(str, ast->child[0], 0, indent);
2487+
if (ast->child[1]) {
2488+
smart_str_appendc(str, '<');
2489+
zend_ast_export_generic_arg_list(str, zend_ast_get_list(ast->child[1]), indent);
2490+
smart_str_appendc(str, '>');
2491+
}
2492+
break;
24462493
case ZEND_AST_CLASS_NAME:
24472494
if (ast->child[0] == NULL) {
24482495
/* The const expr representation stores the fetch type instead. */
@@ -2456,7 +2503,7 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio
24562503
EMPTY_SWITCH_DEFAULT_CASE()
24572504
}
24582505
} else {
2459-
zend_ast_export_ns_name(str, ast->child[0], 0, indent);
2506+
zend_ast_export_class_name(str, ast->child[0], 0, indent);
24602507
}
24612508
smart_str_appends(str, "::class");
24622509
break;
@@ -2724,17 +2771,6 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio
27242771
smart_str_appends(str, ": ");
27252772
ast = ast->child[1];
27262773
goto tail_call;
2727-
// TODO Export generic types
2728-
//case ZEND_AST_ASSOCIATED_TYPE:
2729-
// smart_str_appends(str, "type ");
2730-
// zend_ast_export_name(str, ast->child[0], 0, indent);
2731-
// if (ast->child[1]) {
2732-
// smart_str_appends(str, " : ");
2733-
// smart_str_appends(str, " : ");
2734-
// zend_ast_export_type(str, ast->child[1], indent);
2735-
// }
2736-
// smart_str_appendc(str, ';');
2737-
//break;
27382774

27392775
/* 3 child nodes */
27402776
case ZEND_AST_METHOD_CALL:

‎Zend/zend_compile.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9120,7 +9120,7 @@ static zend_string *zend_generate_anon_class_name(zend_ast_decl *decl)
91209120
prefix = zend_resolve_const_class_name_reference(decl->child[0], "class name");
91219121
} else if (decl->child[1]) {
91229122
zend_ast_list *list = zend_ast_get_list(decl->child[1]);
9123-
prefix = zend_resolve_const_class_name_reference(list->child[0], "interface name");
9123+
prefix = zend_resolve_const_class_name_reference_with_generics(list->child[0], "interface name");
91249124
}
91259125

91269126
zend_string *result = zend_strpprintf(0, "%s@anonymous%c%s:%" PRIu32 "$%" PRIx32,
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
--TEST--
2+
AST can be recreated (interface with generic types)
3+
--EXTENSIONS--
4+
zend_test
5+
--FILE--
6+
<?php
7+
8+
namespace {
9+
interface MyInterface1<T1 : string|Stringable|int, T2> {
10+
public function bar(T1 $v): T2;
11+
}
12+
}
13+
14+
namespace Foo {
15+
interface MyInterface2<S : string|\Stringable|int> extends \MyInterface1<S, S> {
16+
public function foobar(S $v): int;
17+
}
18+
19+
class MyClass implements MyInterface2<string> {
20+
public function bar(string $v): string {}
21+
public function foobar(string $v): int {}
22+
}
23+
}
24+
25+
namespace {
26+
echo zend_test_compile_to_ast( file_get_contents( __FILE__ ) );
27+
}
28+
29+
?>
30+
--EXPECT--
31+
namespace {
32+
interface MyInterface1<T1 : string|Stringable|int, T2> {
33+
public function bar(T1 $v): T2;
34+
35+
}
36+
37+
}
38+
39+
namespace Foo {
40+
interface MyInterface2<S : string|\Stringable|int> implements \MyInterface1<S, S> {
41+
public function foobar(S $v): int;
42+
43+
}
44+
45+
class MyClass implements MyInterface2<string> {
46+
public function bar(string $v): string {
47+
}
48+
49+
public function foobar(string $v): int {
50+
}
51+
52+
}
53+
54+
}
55+
56+
namespace {
57+
echo zend_test_compile_to_ast(file_get_contents(__FILE__));
58+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /