Skip to content

Commit c533904

Browse files
authored
Support php 8.1 read-only properties, first-class callable syntax (#209)
Add php 8.1 readonly property support, first-class callables And run all tests even after the first case fails Mark ast version 90 as current and 85 as no longer experimental. Add date to changelog, bump version in php_ast.h
1 parent 900e41a commit c533904

File tree

12 files changed

+177
-25
lines changed

12 files changed

+177
-25
lines changed

.github/workflows/main.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ jobs:
2222

2323
# See https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#using-environment-variables-in-a-matrix
2424
strategy:
25+
fail-fast: false
2526
matrix:
2627
include:
2728
# NOTE: If this is not quoted, the yaml parser will convert 7.0 to the number 7,

README.md

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ Basic usage
5959

6060
Code can be parsed using either `ast\parse_code()`, which accepts a code string, or
6161
`ast\parse_file()`, which accepts a file path. Additionally, both functions require a `$version`
62-
argument to ensure forward-compatibility. The current version is 70.
62+
argument to ensure forward-compatibility. The current version is 90.
6363

6464
```php
6565
$ast = ast\parse_code('<?php ...', $version=70);
@@ -235,6 +235,7 @@ ast\flags\MODIFIER_PRIVATE
235235
ast\flags\MODIFIER_STATIC
236236
ast\flags\MODIFIER_ABSTRACT
237237
ast\flags\MODIFIER_FINAL
238+
ast\flags\MODIFIER_READONLY
238239
239240
// Used by ast\AST_CLOSURE, ast\AST_ARROW_FUNC (combinable)
240241
ast\flags\MODIFIER_STATIC
@@ -374,6 +375,7 @@ AST_ATTRIBUTE: class, args // php 8.0+ attributes (version
374375
AST_BINARY_OP: left, right
375376
AST_BREAK: depth
376377
AST_CALL: expr, args
378+
AST_CALLABLE_CONVERT: // php 8.1+ first-class callable syntax
377379
AST_CAST: expr
378380
AST_CATCH: class, var, stmts
379381
AST_CLASS: name, docComment, extends, implements, stmts, (for enums) type
@@ -495,11 +497,19 @@ function accepts a boolean argument that determines whether deprecated versions
495497
In the following the changes in the respective AST versions, as well as their current support state,
496498
are listed.
497499

498-
### 85 (experimental)
500+
### 90 (current)
501+
502+
Supported since 1.0.14 (2021-07-24)
503+
504+
* Same as AST version 85.
505+
506+
### 85 (stable)
507+
508+
Supported since 1.0.11 (2021-04-20)
499509

500510
* Add a `type` child node (for enum type) for all AST_CLASS nodes.
501511

502-
### 80 (current)
512+
### 80 (stable)
503513

504514
Supported since 1.0.10 (2020-09-12).
505515

ast.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@
5151
#define AST_CACHE_SLOT_LINENO &AST_G(cache_slots)[3 * 2]
5252
#define AST_CACHE_SLOT_CHILDREN &AST_G(cache_slots)[3 * 3]
5353

54-
#define AST_CURRENT_VERSION 80
54+
#define AST_CURRENT_VERSION 90
5555

5656
/* Additional flags for BINARY_OP */
5757
#define AST_BINARY_IS_GREATER 256
@@ -267,7 +267,8 @@ static const char *closure_use_flags[] = {
267267
AST_VISIBILITY_FLAGS, \
268268
AST_FLAG(MODIFIER_STATIC), \
269269
AST_FLAG(MODIFIER_ABSTRACT), \
270-
AST_FLAG(MODIFIER_FINAL)
270+
AST_FLAG(MODIFIER_FINAL), \
271+
AST_FLAG(MODIFIER_READONLY)
271272

272273
static const char *visibility_flags[] = {
273274
AST_VISIBILITY_FLAGS,
@@ -1075,7 +1076,7 @@ static void ast_to_zval(zval *zv, zend_ast *ast, ast_state_info_t *state) {
10751076
#endif
10761077
}
10771078

1078-
static const zend_long versions[] = {50, 60, 70, 80, 85};
1079+
static const zend_long versions[] = {50, 60, 70, 80, 85, 90};
10791080
static const size_t versions_count = sizeof(versions)/sizeof(versions[0]);
10801081

10811082
static inline zend_bool ast_version_deprecated(zend_long version) {
@@ -1408,6 +1409,7 @@ PHP_MINIT_FUNCTION(ast) {
14081409
ast_register_flag_constant("MODIFIER_STATIC", ZEND_ACC_STATIC);
14091410
ast_register_flag_constant("MODIFIER_ABSTRACT", ZEND_ACC_ABSTRACT);
14101411
ast_register_flag_constant("MODIFIER_FINAL", ZEND_ACC_FINAL);
1412+
ast_register_flag_constant("MODIFIER_READONLY", ZEND_ACC_READONLY);
14111413

14121414
ast_register_flag_constant("PARAM_MODIFIER_PUBLIC", PARAM_MODIFIER_PUBLIC);
14131415
ast_register_flag_constant("PARAM_MODIFIER_PROTECTED", PARAM_MODIFIER_PROTECTED);

ast_data.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ const zend_ast_kind ast_kinds[] = {
3333
ZEND_AST_CLASS,
3434
ZEND_AST_MAGIC_CONST,
3535
ZEND_AST_TYPE,
36+
ZEND_AST_CALLABLE_CONVERT,
3637
ZEND_AST_VAR,
3738
ZEND_AST_CONST,
3839
ZEND_AST_UNPACK,
@@ -146,6 +147,7 @@ const char *ast_kind_to_name(zend_ast_kind kind) {
146147
case ZEND_AST_CLASS: return "AST_CLASS";
147148
case ZEND_AST_MAGIC_CONST: return "AST_MAGIC_CONST";
148149
case ZEND_AST_TYPE: return "AST_TYPE";
150+
case ZEND_AST_CALLABLE_CONVERT: return "AST_CALLABLE_CONVERT";
149151
case ZEND_AST_VAR: return "AST_VAR";
150152
case ZEND_AST_CONST: return "AST_CONST";
151153
case ZEND_AST_UNPACK: return "AST_UNPACK";
@@ -265,6 +267,7 @@ zend_string *ast_kind_child_name(zend_ast_kind kind, uint32_t child) {
265267
return NULL;
266268
case ZEND_AST_MAGIC_CONST:
267269
case ZEND_AST_TYPE:
270+
case ZEND_AST_CALLABLE_CONVERT:
268271
return NULL;
269272
case ZEND_AST_UNPACK:
270273
case ZEND_AST_CAST:
@@ -597,6 +600,7 @@ void ast_register_kind_constants(INIT_FUNC_ARGS) {
597600
REGISTER_NS_LONG_CONSTANT("ast", "AST_CLASS", ZEND_AST_CLASS, CONST_CS | CONST_PERSISTENT);
598601
REGISTER_NS_LONG_CONSTANT("ast", "AST_MAGIC_CONST", ZEND_AST_MAGIC_CONST, CONST_CS | CONST_PERSISTENT);
599602
REGISTER_NS_LONG_CONSTANT("ast", "AST_TYPE", ZEND_AST_TYPE, CONST_CS | CONST_PERSISTENT);
603+
REGISTER_NS_LONG_CONSTANT("ast", "AST_CALLABLE_CONVERT", ZEND_AST_CALLABLE_CONVERT, CONST_CS | CONST_PERSISTENT);
600604
REGISTER_NS_LONG_CONSTANT("ast", "AST_VAR", ZEND_AST_VAR, CONST_CS | CONST_PERSISTENT);
601605
REGISTER_NS_LONG_CONSTANT("ast", "AST_CONST", ZEND_AST_CONST, CONST_CS | CONST_PERSISTENT);
602606
REGISTER_NS_LONG_CONSTANT("ast", "AST_UNPACK", ZEND_AST_UNPACK, CONST_CS | CONST_PERSISTENT);

ast_stub.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
const AST_CLASS = 70;
4040
const AST_MAGIC_CONST = 0;
4141
const AST_TYPE = 1;
42+
const AST_CALLABLE_CONVERT = 3;
4243
const AST_VAR = 256;
4344
const AST_CONST = 257;
4445
const AST_UNPACK = 258;
@@ -127,6 +128,7 @@
127128
const MODIFIER_STATIC = 16;
128129
const MODIFIER_ABSTRACT = 64;
129130
const MODIFIER_FINAL = 32;
131+
const MODIFIER_READONLY = 128;
130132
const PARAM_MODIFIER_PUBLIC = 1;
131133
const PARAM_MODIFIER_PROTECTED = 2;
132134
const PARAM_MODIFIER_PRIVATE = 4;

package.xml

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,20 +18,20 @@
1818
<email>[email protected]</email>
1919
<active>yes</active>
2020
</lead>
21-
<date>2021-07-08</date>
21+
<date>2021-07-24</date>
2222
<version>
23-
<release>1.0.13</release>
24-
<api>1.0.13</api>
23+
<release>1.0.14</release>
24+
<api>1.0.14</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-
- Indicate in metadata that 'AST_CLASS_CONST_GROUP' and 'AST_CLASS_CONST_DECL' can have MODIFIER_FINAL
33-
(and any modifier a class element can have, to reflect what the parser can actually parse)
34-
- Support php 8.1 intersection types, add node kind 'AST_TYPE_INTERSECTION'
32+
- Support php 8.1 readonly properties with the flag 'MODIFIER_READONLY'
33+
- Support php 8.1 first-class callable syntax, add the node kind 'AST_CALLABLE_CONVERT'
34+
- Change the current AST version from 80 to the new version 90. AST version 85 is no longer experimental.
3535
</notes>
3636
<contents>
3737
<dir name="/">
@@ -113,8 +113,10 @@
113113
<file name="php80_union_types_nullable.phpt" role="test" />
114114
<file name="php80_union_types.phpt" role="test" />
115115
<file name="php81_enums.phpt" role="test" />
116+
<file name="php81_first_class_callable_support.phpt" role="test" />
116117
<file name="php81_final_class_const.phpt" role="test" />
117118
<file name="php81_intersection_types.phpt" role="test" />
119+
<file name="php81_readonly.phpt" role="test" />
118120
<file name="prop_doc_comments.phpt" role="test" />
119121
<file name="short_arrow_function.phpt" role="test" />
120122
<file name="short_arrow_function_return.phpt" role="test" />
@@ -142,6 +144,23 @@
142144
<providesextension>ast</providesextension>
143145
<extsrcrelease />
144146
<changelog>
147+
<release>
148+
<date>2021-07-08</date>
149+
<version>
150+
<release>1.0.13</release>
151+
<api>1.0.13</api>
152+
</version>
153+
<stability>
154+
<release>stable</release>
155+
<api>stable</api>
156+
</stability>
157+
<license uri="https://github.com/nikic/php-ast/blob/master/LICENSE">BSD-3-Clause</license>
158+
<notes>
159+
- Indicate in metadata that 'AST_CLASS_CONST_GROUP' and 'AST_CLASS_CONST_DECL' can have 'MODIFIER_FINAL'
160+
(and any modifier a class element can have, to reflect what the parser can actually parse)
161+
- Support php 8.1 intersection types, add the node kind 'AST_TYPE_INTERSECTION'
162+
</notes>
163+
</release>
145164
<release>
146165
<date>2021-05-16</date>
147166
<version>
@@ -154,7 +173,7 @@
154173
</stability>
155174
<license uri="https://github.com/nikic/php-ast/blob/master/LICENSE">BSD-3-Clause</license>
156175
<notes>
157-
- Support parsing 'docComment' on php 8.1 enums
176+
- Support parsing 'docComment' on php 8.1 enum cases
158177
- Indicate in metadata that 'AST_CLASS_CONST_GROUP' and 'AST_CLASS_CONST_DECL' can have MODIFIER_FINAL
159178
</notes>
160179
</release>

php_ast.h

Lines changed: 5 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.13"
10+
#define PHP_AST_VERSION "1.0.14"
1111

1212
#ifdef PHP_WIN32
1313
# define PHP_AST_API __declspec(dllexport)
@@ -77,6 +77,10 @@ extern ast_str_globals str_globals;
7777

7878
#if PHP_VERSION_ID < 80100
7979
# define ZEND_ACC_ENUM (1 << 22)
80+
# define ZEND_ACC_READONLY (1 << 7)
81+
82+
/* 0 child nodes */
83+
# define ZEND_AST_CALLABLE_CONVERT 3
8084
/* 3 child nodes - name, expr, attributes */
8185
# define ZEND_AST_ENUM_CASE 0x3fe
8286
# define ZEND_AST_TYPE_INTERSECTION ((1 << (ZEND_AST_IS_LIST_SHIFT + 1)) - 6)

scripts/generate_ast_data.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
/* 0 child nodes */
6464
'ZEND_AST_MAGIC_CONST' => [],
6565
'ZEND_AST_TYPE' => [],
66+
'ZEND_AST_CALLABLE_CONVERT' => [],
6667

6768
/* 1 child node */
6869
'ZEND_AST_VAR' => ['name'],

tests/get_supported_versions.phpt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ var_dump(ast\get_supported_versions(true));
88

99
?>
1010
--EXPECT--
11-
array(5) {
11+
array(6) {
1212
[0]=>
1313
int(50)
1414
[1]=>
@@ -19,8 +19,10 @@ array(5) {
1919
int(80)
2020
[4]=>
2121
int(85)
22+
[5]=>
23+
int(90)
2224
}
23-
array(5) {
25+
array(6) {
2426
[0]=>
2527
int(50)
2628
[1]=>
@@ -31,4 +33,6 @@ array(5) {
3133
int(80)
3234
[4]=>
3335
int(85)
36+
[5]=>
37+
int(90)
3438
}

tests/metadata.phpt

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,9 @@ AST_SWITCH_LIST: []
3737
AST_CATCH_LIST: []
3838
AST_PARAM_LIST: []
3939
AST_CLOSURE_USES: []
40-
AST_PROP_DECL: (combinable) [MODIFIER_PUBLIC, MODIFIER_PROTECTED, MODIFIER_PRIVATE, MODIFIER_STATIC, MODIFIER_ABSTRACT, MODIFIER_FINAL]
40+
AST_PROP_DECL: (combinable) [MODIFIER_PUBLIC, MODIFIER_PROTECTED, MODIFIER_PRIVATE, MODIFIER_STATIC, MODIFIER_ABSTRACT, MODIFIER_FINAL, MODIFIER_READONLY]
4141
AST_CONST_DECL: []
42-
AST_CLASS_CONST_DECL: (combinable) [MODIFIER_PUBLIC, MODIFIER_PROTECTED, MODIFIER_PRIVATE, MODIFIER_STATIC, MODIFIER_ABSTRACT, MODIFIER_FINAL]
42+
AST_CLASS_CONST_DECL: (combinable) [MODIFIER_PUBLIC, MODIFIER_PROTECTED, MODIFIER_PRIVATE, MODIFIER_STATIC, MODIFIER_ABSTRACT, MODIFIER_FINAL, MODIFIER_READONLY]
4343
AST_NAME_LIST: []
4444
AST_TRAIT_ADAPTATIONS: []
4545
AST_USE: [USE_NORMAL, USE_FUNCTION, USE_CONST]
@@ -51,13 +51,14 @@ AST_MATCH_ARM_LIST: []
5151
AST_NAME: [NAME_FQ, NAME_NOT_FQ, NAME_RELATIVE]
5252
AST_CLOSURE_VAR: [CLOSURE_USE_REF]
5353
AST_NULLABLE_TYPE: []
54-
AST_FUNC_DECL: (combinable) [MODIFIER_PUBLIC, MODIFIER_PROTECTED, MODIFIER_PRIVATE, MODIFIER_STATIC, MODIFIER_ABSTRACT, MODIFIER_FINAL, FUNC_RETURNS_REF, FUNC_GENERATOR]
55-
AST_CLOSURE: (combinable) [MODIFIER_PUBLIC, MODIFIER_PROTECTED, MODIFIER_PRIVATE, MODIFIER_STATIC, MODIFIER_ABSTRACT, MODIFIER_FINAL, FUNC_RETURNS_REF, FUNC_GENERATOR]
56-
AST_METHOD: (combinable) [MODIFIER_PUBLIC, MODIFIER_PROTECTED, MODIFIER_PRIVATE, MODIFIER_STATIC, MODIFIER_ABSTRACT, MODIFIER_FINAL, FUNC_RETURNS_REF, FUNC_GENERATOR]
57-
AST_ARROW_FUNC: (combinable) [MODIFIER_PUBLIC, MODIFIER_PROTECTED, MODIFIER_PRIVATE, MODIFIER_STATIC, MODIFIER_ABSTRACT, MODIFIER_FINAL, FUNC_RETURNS_REF, FUNC_GENERATOR]
54+
AST_FUNC_DECL: (combinable) [MODIFIER_PUBLIC, MODIFIER_PROTECTED, MODIFIER_PRIVATE, MODIFIER_STATIC, MODIFIER_ABSTRACT, MODIFIER_FINAL, MODIFIER_READONLY, FUNC_RETURNS_REF, FUNC_GENERATOR]
55+
AST_CLOSURE: (combinable) [MODIFIER_PUBLIC, MODIFIER_PROTECTED, MODIFIER_PRIVATE, MODIFIER_STATIC, MODIFIER_ABSTRACT, MODIFIER_FINAL, MODIFIER_READONLY, FUNC_RETURNS_REF, FUNC_GENERATOR]
56+
AST_METHOD: (combinable) [MODIFIER_PUBLIC, MODIFIER_PROTECTED, MODIFIER_PRIVATE, MODIFIER_STATIC, MODIFIER_ABSTRACT, MODIFIER_FINAL, MODIFIER_READONLY, FUNC_RETURNS_REF, FUNC_GENERATOR]
57+
AST_ARROW_FUNC: (combinable) [MODIFIER_PUBLIC, MODIFIER_PROTECTED, MODIFIER_PRIVATE, MODIFIER_STATIC, MODIFIER_ABSTRACT, MODIFIER_FINAL, MODIFIER_READONLY, FUNC_RETURNS_REF, FUNC_GENERATOR]
5858
AST_CLASS: (combinable) [CLASS_ABSTRACT, CLASS_FINAL, CLASS_TRAIT, CLASS_INTERFACE, CLASS_ANONYMOUS, CLASS_ENUM]
5959
AST_MAGIC_CONST: [MAGIC_LINE, MAGIC_FILE, MAGIC_DIR, MAGIC_NAMESPACE, MAGIC_FUNCTION, MAGIC_METHOD, MAGIC_CLASS, MAGIC_TRAIT]
6060
AST_TYPE: [TYPE_NULL, TYPE_FALSE, TYPE_BOOL, TYPE_LONG, TYPE_DOUBLE, TYPE_STRING, TYPE_ARRAY, TYPE_OBJECT, TYPE_CALLABLE, TYPE_VOID, TYPE_ITERABLE, TYPE_STATIC, TYPE_MIXED, TYPE_NEVER]
61+
AST_CALLABLE_CONVERT: []
6162
AST_VAR: []
6263
AST_CONST: []
6364
AST_UNPACK: []
@@ -87,7 +88,7 @@ AST_GOTO: []
8788
AST_BREAK: []
8889
AST_CONTINUE: []
8990
AST_CLASS_NAME: []
90-
AST_CLASS_CONST_GROUP: (combinable) [MODIFIER_PUBLIC, MODIFIER_PROTECTED, MODIFIER_PRIVATE, MODIFIER_STATIC, MODIFIER_ABSTRACT, MODIFIER_FINAL]
91+
AST_CLASS_CONST_GROUP: (combinable) [MODIFIER_PUBLIC, MODIFIER_PROTECTED, MODIFIER_PRIVATE, MODIFIER_STATIC, MODIFIER_ABSTRACT, MODIFIER_FINAL, MODIFIER_READONLY]
9192
AST_DIM: (combinable) [DIM_ALTERNATIVE_SYNTAX]
9293
AST_PROP: []
9394
AST_NULLSAFE_PROP: []
@@ -110,14 +111,14 @@ AST_SWITCH: []
110111
AST_SWITCH_CASE: []
111112
AST_DECLARE: []
112113
AST_PROP_ELEM: []
113-
AST_PROP_GROUP: (combinable) [MODIFIER_PUBLIC, MODIFIER_PROTECTED, MODIFIER_PRIVATE, MODIFIER_STATIC, MODIFIER_ABSTRACT, MODIFIER_FINAL]
114+
AST_PROP_GROUP: (combinable) [MODIFIER_PUBLIC, MODIFIER_PROTECTED, MODIFIER_PRIVATE, MODIFIER_STATIC, MODIFIER_ABSTRACT, MODIFIER_FINAL, MODIFIER_READONLY]
114115
AST_CONST_ELEM: []
115116
AST_USE_TRAIT: []
116117
AST_TRAIT_PRECEDENCE: []
117118
AST_METHOD_REFERENCE: []
118119
AST_NAMESPACE: []
119120
AST_USE_ELEM: [USE_NORMAL, USE_FUNCTION, USE_CONST]
120-
AST_TRAIT_ALIAS: (combinable) [MODIFIER_PUBLIC, MODIFIER_PROTECTED, MODIFIER_PRIVATE, MODIFIER_STATIC, MODIFIER_ABSTRACT, MODIFIER_FINAL]
121+
AST_TRAIT_ALIAS: (combinable) [MODIFIER_PUBLIC, MODIFIER_PROTECTED, MODIFIER_PRIVATE, MODIFIER_STATIC, MODIFIER_ABSTRACT, MODIFIER_FINAL, MODIFIER_READONLY]
121122
AST_GROUP_USE: [USE_NORMAL, USE_FUNCTION, USE_CONST]
122123
AST_ATTRIBUTE: []
123124
AST_MATCH: []

0 commit comments

Comments
 (0)