Skip to content

Commit 21057fb

Browse files
authored
Support php 8.0 grouped attributes with #[ (nikic#173)
The choice of null AST_ARG_LIST seems deliberate in php-src, so that zend_ast_export_attribute_group can emit a different representation for `attr()` and `attr`
1 parent 2b4a381 commit 21057fb

File tree

9 files changed

+125
-40
lines changed

9 files changed

+125
-40
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,7 @@ AST_YIELD_FROM: expr
454454
AST_ARG_LIST
455455
AST_ARRAY
456456
AST_ATTRIBUTE_LIST // php 8.0+ attributes (version 80+)
457+
AST_ATTRIBUTE_GROUP // php 8.0+ attributes (version 80+)
457458
AST_CATCH_LIST
458459
AST_CLASS_CONST_DECL
459460
AST_CLOSURE_USES

ast_data.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ const zend_ast_kind ast_kinds[] = {
2020
ZEND_AST_USE,
2121
ZEND_AST_TYPE_UNION,
2222
ZEND_AST_ATTRIBUTE_LIST,
23+
ZEND_AST_ATTRIBUTE_GROUP,
2324
ZEND_AST_MATCH_ARM_LIST,
2425
AST_NAME,
2526
AST_CLOSURE_VAR,
@@ -130,6 +131,7 @@ const char *ast_kind_to_name(zend_ast_kind kind) {
130131
case ZEND_AST_USE: return "AST_USE";
131132
case ZEND_AST_TYPE_UNION: return "AST_TYPE_UNION";
132133
case ZEND_AST_ATTRIBUTE_LIST: return "AST_ATTRIBUTE_LIST";
134+
case ZEND_AST_ATTRIBUTE_GROUP: return "AST_ATTRIBUTE_GROUP";
133135
case ZEND_AST_MATCH_ARM_LIST: return "AST_MATCH_ARM_LIST";
134136
case AST_NAME: return "AST_NAME";
135137
case AST_CLOSURE_VAR: return "AST_CLOSURE_VAR";
@@ -741,6 +743,7 @@ void ast_register_kind_constants(INIT_FUNC_ARGS) {
741743
REGISTER_NS_LONG_CONSTANT("ast", "AST_USE", ZEND_AST_USE, CONST_CS | CONST_PERSISTENT);
742744
REGISTER_NS_LONG_CONSTANT("ast", "AST_TYPE_UNION", ZEND_AST_TYPE_UNION, CONST_CS | CONST_PERSISTENT);
743745
REGISTER_NS_LONG_CONSTANT("ast", "AST_ATTRIBUTE_LIST", ZEND_AST_ATTRIBUTE_LIST, CONST_CS | CONST_PERSISTENT);
746+
REGISTER_NS_LONG_CONSTANT("ast", "AST_ATTRIBUTE_GROUP", ZEND_AST_ATTRIBUTE_GROUP, CONST_CS | CONST_PERSISTENT);
744747
REGISTER_NS_LONG_CONSTANT("ast", "AST_MATCH_ARM_LIST", ZEND_AST_MATCH_ARM_LIST, CONST_CS | CONST_PERSISTENT);
745748
REGISTER_NS_LONG_CONSTANT("ast", "AST_NAME", AST_NAME, CONST_CS | CONST_PERSISTENT);
746749
REGISTER_NS_LONG_CONSTANT("ast", "AST_CLOSURE_VAR", AST_CLOSURE_VAR, CONST_CS | CONST_PERSISTENT);

ast_stub.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
const AST_USE = 143;
2727
const AST_TYPE_UNION = 144;
2828
const AST_ATTRIBUTE_LIST = 145;
29+
const AST_ATTRIBUTE_GROUP = 146;
2930
const AST_MATCH_ARM_LIST = 147;
3031
const AST_NAME = 2048;
3132
const AST_CLOSURE_VAR = 2049;

package.xml

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,18 @@
1818
<email>[email protected]</email>
1919
<active>yes</active>
2020
</lead>
21-
<date>2020-09-02</date>
21+
<date>2020-09-03</date>
2222
<version>
23-
<release>1.0.9</release>
24-
<api>1.0.9</api>
23+
<release>1.0.10dev</release>
24+
<api>1.0.10dev</api>
2525
</version>
2626
<stability>
2727
<release>stable</release>
2828
<api>stable</api>
2929
</stability>
3030
<license uri="https://github.com/nikic/php-ast/blob/master/LICENSE">BSD-3-Clause</license>
3131
<notes>
32-
- Support API change in php 8.0.0beta3.
32+
- Support attributes syntax change (`#[...]`) in php 8.0.0RC1.
3333
</notes>
3434
<contents>
3535
<dir name="/">
@@ -132,6 +132,21 @@
132132
<providesextension>ast</providesextension>
133133
<extsrcrelease />
134134
<changelog>
135+
<release>
136+
<date>2020-09-02</date>
137+
<version>
138+
<release>1.0.9</release>
139+
<api>1.0.9</api>
140+
</version>
141+
<stability>
142+
<release>stable</release>
143+
<api>stable</api>
144+
</stability>
145+
<license uri="https://github.com/nikic/php-ast/blob/master/LICENSE">BSD-3-Clause</license>
146+
<notes>
147+
- Support API change in php 8.0.0beta3.
148+
</notes>
149+
</release>
135150
<release>
136151
<date>2020-08-04</date>
137152
<version>

php_ast.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
extern zend_module_entry ast_module_entry;
88
#define phpext_ast_ptr &ast_module_entry
99

10-
#define PHP_AST_VERSION "1.0.9"
10+
#define PHP_AST_VERSION "1.0.10dev"
1111

1212
#ifdef PHP_WIN32
1313
# define PHP_AST_API __declspec(dllexport)
@@ -62,6 +62,7 @@ extern ast_str_globals str_globals;
6262
# define ZEND_AST_TYPE_UNION ((1 << (ZEND_AST_IS_LIST_SHIFT + 1)) - 2)
6363
# define ZEND_AST_ATTRIBUTE_LIST ((1 << (ZEND_AST_IS_LIST_SHIFT + 1)) - 3)
6464
# define ZEND_AST_MATCH_ARM_LIST ((1 << (ZEND_AST_IS_LIST_SHIFT + 1)) - 4)
65+
# define ZEND_AST_ATTRIBUTE_GROUP ((1 << (ZEND_AST_IS_LIST_SHIFT + 1)) - 5)
6566
/* 2 child nodes */
6667
# define ZEND_AST_CLASS_CONST_GROUP 0x2fe
6768
# define ZEND_AST_ATTRIBUTE 0x2fd

scripts/generate_ast_data.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@
172172
'ZEND_AST_USE',
173173
'ZEND_AST_TYPE_UNION',
174174
'ZEND_AST_ATTRIBUTE_LIST',
175+
'ZEND_AST_ATTRIBUTE_GROUP',
175176
'ZEND_AST_MATCH_ARM_LIST',
176177
];
177178

tests/attributes_01.phpt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@ $code = <<<'PHP'
1111
<?php
1212
namespace NS;
1313
14-
@@SomeAttribute
15-
function test(@@namespace\SomeAttribute(2+2) Type $arg) {
14+
#[SomeAttribute]
15+
function test(#[namespace\SomeAttribute(2+2)] Type $arg) {
1616
}
1717
18-
$x = @@SomeAttribute function () {};
18+
$x = #[SomeAttribute] function () {};
1919
20-
$y = @@SomeAttribute fn (@@\SomeAttribute $a) => $x;
20+
$y = #[SomeAttribute] fn (#[\SomeAttribute] $a) => $x;
2121
PHP;
2222

2323
echo ast_dump(ast\parse_code($code, $version=70));

tests/attributes_02.phpt

Lines changed: 93 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,29 @@ Attributes in PHP 8.0 on classes
77

88
require __DIR__ . '/../util.php';
99

10+
// Some edge cases in parsing attributes to compare other parsers against
1011
$code = <<<'PHP'
1112
<?php
1213
namespace NS;
1314
14-
@@\SomeAttribute()
15+
#[\SomeAttribute()]
1516
class X {
16-
@@Attr1
17-
@@Attr2(true)
17+
#[Attr1]
18+
#[
19+
Attr2(true), # Line comment on an attribute
20+
]
1821
public $prop;
1922
20-
@@Attr3
23+
#[Attr3]
2124
public const CONST_WITH_ATTRIBUTE = 123;
2225
23-
@@Attr4
24-
public static function hasAttribute() {}
26+
#[Attr4, Attr5()]
27+
public static function hasAttribute(
28+
#[ThisIsAnAttribute, \AnotherAttribute] $parameter
29+
) {}
2530
}
31+
#[Deprecated]
32+
function myGlobal() {}
2633
PHP;
2734

2835
echo ast_dump(ast\parse_code($code, $version=70));
@@ -60,10 +67,23 @@ AST_STMT_LIST
6067
name: "hasAttribute"
6168
docComment: null
6269
params: AST_PARAM_LIST
70+
0: AST_PARAM
71+
flags: 0
72+
type: null
73+
name: "parameter"
74+
default: null
6375
stmts: AST_STMT_LIST
6476
returnType: null
6577
__declId: 0
6678
__declId: 1
79+
2: AST_FUNC_DECL
80+
flags: 0
81+
name: "myGlobal"
82+
docComment: null
83+
params: AST_PARAM_LIST
84+
stmts: AST_STMT_LIST
85+
returnType: null
86+
__declId: 2
6787
In version 80
6888
AST_STMT_LIST
6989
0: AST_NAMESPACE
@@ -86,20 +106,22 @@ AST_STMT_LIST
86106
default: null
87107
docComment: null
88108
attributes: AST_ATTRIBUTE_LIST
89-
0: AST_ATTRIBUTE
90-
class: AST_NAME
91-
flags: NAME_NOT_FQ (%d)
92-
name: "Attr1"
93-
args: null
94-
1: AST_ATTRIBUTE
95-
class: AST_NAME
96-
flags: NAME_NOT_FQ (%d)
97-
name: "Attr2"
98-
args: AST_ARG_LIST
99-
0: AST_CONST
100-
name: AST_NAME
101-
flags: NAME_NOT_FQ (%d)
102-
name: "true"
109+
0: AST_ATTRIBUTE_GROUP
110+
0: AST_ATTRIBUTE
111+
class: AST_NAME
112+
flags: NAME_NOT_FQ (%d)
113+
name: "Attr1"
114+
args: null
115+
1: AST_ATTRIBUTE_GROUP
116+
0: AST_ATTRIBUTE
117+
class: AST_NAME
118+
flags: NAME_NOT_FQ (%d)
119+
name: "Attr2"
120+
args: AST_ARG_LIST
121+
0: AST_CONST
122+
name: AST_NAME
123+
flags: NAME_NOT_FQ (%d)
124+
name: "true"
103125
1: AST_CLASS_CONST_GROUP
104126
flags: MODIFIER_PUBLIC (%d)
105127
const: AST_CLASS_CONST_DECL
@@ -109,24 +131,64 @@ AST_STMT_LIST
109131
value: 123
110132
docComment: null
111133
attributes: AST_ATTRIBUTE_LIST
112-
0: AST_ATTRIBUTE
113-
class: AST_NAME
114-
flags: NAME_NOT_FQ (%d)
115-
name: "Attr3"
116-
args: null
134+
0: AST_ATTRIBUTE_GROUP
135+
0: AST_ATTRIBUTE
136+
class: AST_NAME
137+
flags: NAME_NOT_FQ (%d)
138+
name: "Attr3"
139+
args: null
117140
2: AST_METHOD
118141
flags: MODIFIER_PUBLIC | MODIFIER_STATIC (%d)
119142
name: "hasAttribute"
120143
docComment: null
121144
params: AST_PARAM_LIST
145+
0: AST_PARAM
146+
flags: 0
147+
type: null
148+
name: "parameter"
149+
default: null
150+
attributes: AST_ATTRIBUTE_LIST
151+
0: AST_ATTRIBUTE_GROUP
152+
0: AST_ATTRIBUTE
153+
class: AST_NAME
154+
flags: NAME_NOT_FQ (%d)
155+
name: "ThisIsAnAttribute"
156+
args: null
157+
1: AST_ATTRIBUTE
158+
class: AST_NAME
159+
flags: NAME_FQ (%d)
160+
name: "AnotherAttribute"
161+
args: null
162+
docComment: null
122163
stmts: AST_STMT_LIST
123164
returnType: null
124165
attributes: AST_ATTRIBUTE_LIST
125-
0: AST_ATTRIBUTE
126-
class: AST_NAME
127-
flags: NAME_NOT_FQ (%d)
128-
name: "Attr4"
129-
args: null
166+
0: AST_ATTRIBUTE_GROUP
167+
0: AST_ATTRIBUTE
168+
class: AST_NAME
169+
flags: NAME_NOT_FQ (%d)
170+
name: "Attr4"
171+
args: null
172+
1: AST_ATTRIBUTE
173+
class: AST_NAME
174+
flags: NAME_NOT_FQ (%d)
175+
name: "Attr5"
176+
args: AST_ARG_LIST
130177
__declId: 0
131178
attributes: null
132-
__declId: 1
179+
__declId: 1
180+
2: AST_FUNC_DECL
181+
flags: 0
182+
name: "myGlobal"
183+
docComment: null
184+
params: AST_PARAM_LIST
185+
stmts: AST_STMT_LIST
186+
returnType: null
187+
attributes: AST_ATTRIBUTE_LIST
188+
0: AST_ATTRIBUTE_GROUP
189+
0: AST_ATTRIBUTE
190+
class: AST_NAME
191+
flags: NAME_NOT_FQ (%d)
192+
name: "Deprecated"
193+
args: null
194+
__declId: 2

tests/metadata.phpt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ AST_TRAIT_ADAPTATIONS: []
4545
AST_USE: [USE_NORMAL, USE_FUNCTION, USE_CONST]
4646
AST_TYPE_UNION: []
4747
AST_ATTRIBUTE_LIST: []
48+
AST_ATTRIBUTE_GROUP: []
4849
AST_MATCH_ARM_LIST: []
4950
AST_NAME: [NAME_FQ, NAME_NOT_FQ, NAME_RELATIVE]
5051
AST_CLOSURE_VAR: [CLOSURE_USE_REF]

0 commit comments

Comments
 (0)