Skip to content

Commit 5e3ebe2

Browse files
authored
Support parsing php 8.0 TYPE_STATIC, add test of $x::class (nikic#150)
Test ::class on objects Support parsing php 8.0 TYPE_STATIC Fixes nikic#149
1 parent 0a80cfb commit 5e3ebe2

File tree

8 files changed

+101
-7
lines changed

8 files changed

+101
-7
lines changed

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -267,8 +267,9 @@ ast\flags\TYPE_DOUBLE
267267
ast\flags\TYPE_STRING
268268
ast\flags\TYPE_ITERABLE
269269
ast\flags\TYPE_OBJECT
270-
ast\flags\TYPE_NULL // php 8.0 union types
271-
ast\flags\TYPE_FALSE // php 8.0 union types
270+
ast\flags\TYPE_NULL // php 8.0 union types
271+
ast\flags\TYPE_FALSE // php 8.0 union types
272+
ast\flags\TYPE_STATIC // php 8.0 static return type
272273
273274
// Used by ast\AST_CAST (exclusive)
274275
ast\flags\TYPE_NULL

ast.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,11 @@
6161
# define ZEND_PARENTHESIZED_CONDITIONAL 1
6262
#endif
6363

64+
/* Make IS_STATIC follow IS_ITERABLE in php 7.0 */
65+
#if PHP_VERSION_ID < 80000
66+
# define IS_STATIC 20
67+
#endif
68+
6469
/* This contains state of the ast Node creator. */
6570
typedef struct ast_state_info {
6671
zend_long version;
@@ -116,6 +121,7 @@ static const char *type_flags[] = {
116121
AST_FLAG(TYPE_CALLABLE),
117122
AST_FLAG(TYPE_VOID),
118123
AST_FLAG(TYPE_ITERABLE),
124+
AST_FLAG(TYPE_STATIC),
119125
NULL
120126
};
121127

@@ -1284,6 +1290,7 @@ PHP_MINIT_FUNCTION(ast) {
12841290
ast_register_flag_constant("TYPE_CALLABLE", IS_CALLABLE);
12851291
ast_register_flag_constant("TYPE_VOID", IS_VOID);
12861292
ast_register_flag_constant("TYPE_ITERABLE", IS_ITERABLE);
1293+
ast_register_flag_constant("TYPE_STATIC", IS_STATIC);
12871294

12881295
ast_register_flag_constant("UNARY_BOOL_NOT", ZEND_BOOL_NOT);
12891296
ast_register_flag_constant("UNARY_BITWISE_NOT", ZEND_BW_NOT);

ast_stub.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@
129129
const PARAM_VARIADIC = 2;
130130
const TYPE_NULL = 1;
131131
const TYPE_FALSE = 2;
132-
const TYPE_BOOL = 18;
132+
const TYPE_BOOL = 16;
133133
const TYPE_LONG = 4;
134134
const TYPE_DOUBLE = 5;
135135
const TYPE_STRING = 6;
@@ -138,6 +138,7 @@
138138
const TYPE_CALLABLE = 12;
139139
const TYPE_VOID = 14;
140140
const TYPE_ITERABLE = 13;
141+
const TYPE_STATIC = 15;
141142
const UNARY_BOOL_NOT = 14;
142143
const UNARY_BITWISE_NOT = 13;
143144
const UNARY_SILENCE = 260;

package.xml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
</stability>
3030
<license uri="https://github.com/nikic/php-ast/blob/master/LICENSE">BSD-3-Clause</license>
3131
<notes>
32-
- TBD
32+
- Support TYPE_STATIC for the php 8.0 static return type.
3333
</notes>
3434
<contents>
3535
<dir name="/">
@@ -53,6 +53,7 @@
5353
<file name="binary_ops.phpt" role="test" />
5454
<file name="by_ref_destructuring.phpt" role="test" />
5555
<file name="class_consts.phpt" role="test" />
56+
<file name="class_on_objects.phpt" role="test" />
5657
<file name="class_name_version_50.phpt" role="test" />
5758
<file name="class_name_version_70.phpt" role="test" />
5859
<file name="class.phpt" role="test" />
@@ -93,6 +94,7 @@
9394
<file name="php74_type_hints.phpt" role="test" />
9495
<file name="php80_union_types.phpt" role="test" />
9596
<file name="php80_union_types_nullable.phpt" role="test" />
97+
<file name="php80_static_type.phpt" role="test" />
9698
<file name="prop_doc_comments.phpt" role="test" />
9799
<file name="short_arrow_function.phpt" role="test" />
98100
<file name="short_arrow_function_return.phpt" role="test" />

tests/class_on_objects.phpt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
--TEST--
2+
$x::class in PHP 8.0
3+
--FILE--
4+
<?php
5+
6+
require __DIR__ . '/../util.php';
7+
8+
$code = <<<'PHP'
9+
<?php
10+
echo $x::class;
11+
PHP;
12+
13+
$node = ast\parse_code($code, $version=70);
14+
echo ast_dump($node), "\n";
15+
--EXPECTF--
16+
AST_STMT_LIST
17+
0: AST_ECHO
18+
expr: AST_CLASS_NAME
19+
class: AST_VAR
20+
name: "x"

tests/metadata.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,11 @@ AST_METHOD: (combinable) [MODIFIER_PUBLIC, MODIFIER_PROTECTED, MODIFIER_PRIVATE,
5151
AST_ARROW_FUNC: (combinable) [MODIFIER_PUBLIC, MODIFIER_PROTECTED, MODIFIER_PRIVATE, MODIFIER_STATIC, MODIFIER_ABSTRACT, MODIFIER_FINAL, FUNC_RETURNS_REF, FUNC_GENERATOR]
5252
AST_CLASS: [CLASS_ABSTRACT, CLASS_FINAL, CLASS_TRAIT, CLASS_INTERFACE, CLASS_ANONYMOUS]
5353
AST_MAGIC_CONST: [MAGIC_LINE, MAGIC_FILE, MAGIC_DIR, MAGIC_NAMESPACE, MAGIC_FUNCTION, MAGIC_METHOD, MAGIC_CLASS, MAGIC_TRAIT]
54-
AST_TYPE: [TYPE_NULL, TYPE_FALSE, TYPE_BOOL, TYPE_LONG, TYPE_DOUBLE, TYPE_STRING, TYPE_ARRAY, TYPE_OBJECT, TYPE_CALLABLE, TYPE_VOID, TYPE_ITERABLE]
54+
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]
5555
AST_VAR: []
5656
AST_CONST: []
5757
AST_UNPACK: []
58-
AST_CAST: [TYPE_NULL, TYPE_FALSE, TYPE_BOOL, TYPE_LONG, TYPE_DOUBLE, TYPE_STRING, TYPE_ARRAY, TYPE_OBJECT, TYPE_CALLABLE, TYPE_VOID, TYPE_ITERABLE]
58+
AST_CAST: [TYPE_NULL, TYPE_FALSE, TYPE_BOOL, TYPE_LONG, TYPE_DOUBLE, TYPE_STRING, TYPE_ARRAY, TYPE_OBJECT, TYPE_CALLABLE, TYPE_VOID, TYPE_ITERABLE, TYPE_STATIC]
5959
AST_EMPTY: []
6060
AST_ISSET: []
6161
AST_SHELL_EXEC: []

tests/parse_file_not_existing.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ try {
1111

1212
?>
1313
--EXPECTF--
14-
RuntimeException: ast\parse_file(%stests/non_existing_file.php): failed to open stream: No such file or directory in %s:%d
14+
RuntimeException: ast\parse_file(%stests/non_existing_file.php): %sailed to open stream: No such file or directory in %s:%d
1515
Stack trace:
1616
#0 %s(%d): ast\parse_file('%s', %d)
1717
#1 {main}

tests/php80_static_type.phpt

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
--TEST--
2+
Union types in PHP 8.0
3+
--SKIPIF--
4+
<?php if (PHP_VERSION_ID < 80000) die('skip PHP >= 8.0 only'); ?>
5+
--FILE--
6+
<?php
7+
8+
require __DIR__ . '/../util.php';
9+
10+
$code = <<<'PHP'
11+
<?php
12+
class Xyz {
13+
public function test() : static {
14+
return $this;
15+
}
16+
public function test2() : static|false|OtherClass {
17+
return $this;
18+
}
19+
}
20+
PHP;
21+
22+
$node = ast\parse_code($code, $version=70);
23+
echo ast_dump($node), "\n";
24+
--EXPECTF--
25+
AST_STMT_LIST
26+
0: AST_CLASS
27+
flags: 0
28+
name: "Xyz"
29+
docComment: null
30+
extends: null
31+
implements: null
32+
stmts: AST_STMT_LIST
33+
0: AST_METHOD
34+
flags: MODIFIER_PUBLIC (1)
35+
name: "test"
36+
docComment: null
37+
params: AST_PARAM_LIST
38+
stmts: AST_STMT_LIST
39+
0: AST_RETURN
40+
expr: AST_VAR
41+
name: "this"
42+
returnType: AST_TYPE
43+
flags: TYPE_STATIC (%d)
44+
__declId: 0
45+
1: AST_METHOD
46+
flags: MODIFIER_PUBLIC (1)
47+
name: "test2"
48+
docComment: null
49+
params: AST_PARAM_LIST
50+
stmts: AST_STMT_LIST
51+
0: AST_RETURN
52+
expr: AST_VAR
53+
name: "this"
54+
returnType: AST_TYPE_UNION
55+
0: AST_TYPE
56+
flags: TYPE_STATIC (%d)
57+
1: AST_TYPE
58+
flags: TYPE_FALSE (%d)
59+
2: AST_NAME
60+
flags: NAME_NOT_FQ (%d)
61+
name: "OtherClass"
62+
__declId: 1
63+
__declId: 2

0 commit comments

Comments
 (0)