Skip to content

Commit c6cc7b1

Browse files
authored
Support php 8.0 named parameters (nikic#166)
https://wiki.php.net/rfc/named_params is accepted. This works when built against the PR implementing that RFC. Also, amend attributes so that tests pass on php 8.0-dev (they will be amended again based on the planned vote)
1 parent 49ebd1f commit c6cc7b1

File tree

9 files changed

+76
-9
lines changed

9 files changed

+76
-9
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,7 @@ AST_METHOD: name, docComment, params, stmts, returnType, attributes
412412
AST_METHOD_CALL: expr, method, args
413413
AST_METHOD_REFERENCE: class, method
414414
AST_NAME: name
415+
AST_NAMED_ARG: name, expr // php 8.0 named parameters
415416
AST_NAMESPACE: name, stmts
416417
AST_NEW: class, args
417418
AST_NULLABLE_TYPE: type // Used only since PHP 7.1

ast_data.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ const zend_ast_kind ast_kinds[] = {
9494
ZEND_AST_ATTRIBUTE,
9595
ZEND_AST_MATCH,
9696
ZEND_AST_MATCH_ARM,
97+
ZEND_AST_NAMED_ARG,
9798
ZEND_AST_METHOD_CALL,
9899
ZEND_AST_STATIC_CALL,
99100
ZEND_AST_CONDITIONAL,
@@ -201,6 +202,7 @@ const char *ast_kind_to_name(zend_ast_kind kind) {
201202
case ZEND_AST_ATTRIBUTE: return "AST_ATTRIBUTE";
202203
case ZEND_AST_MATCH: return "AST_MATCH";
203204
case ZEND_AST_MATCH_ARM: return "AST_MATCH_ARM";
205+
case ZEND_AST_NAMED_ARG: return "AST_NAMED_ARG";
204206
case ZEND_AST_METHOD_CALL: return "AST_METHOD_CALL";
205207
case ZEND_AST_STATIC_CALL: return "AST_STATIC_CALL";
206208
case ZEND_AST_CONDITIONAL: return "AST_CONDITIONAL";
@@ -631,6 +633,12 @@ zend_string *ast_kind_child_name(zend_ast_kind kind, uint32_t child) {
631633
case 1: return AST_STR(str_expr);
632634
}
633635
return NULL;
636+
case ZEND_AST_NAMED_ARG:
637+
switch (child) {
638+
case 0: return AST_STR(str_name);
639+
case 1: return AST_STR(str_expr);
640+
}
641+
return NULL;
634642
case ZEND_AST_METHOD_CALL:
635643
switch (child) {
636644
case 0: return AST_STR(str_expr);
@@ -790,6 +798,7 @@ void ast_register_kind_constants(INIT_FUNC_ARGS) {
790798
REGISTER_NS_LONG_CONSTANT("ast", "AST_ATTRIBUTE", ZEND_AST_ATTRIBUTE, CONST_CS | CONST_PERSISTENT);
791799
REGISTER_NS_LONG_CONSTANT("ast", "AST_MATCH", ZEND_AST_MATCH, CONST_CS | CONST_PERSISTENT);
792800
REGISTER_NS_LONG_CONSTANT("ast", "AST_MATCH_ARM", ZEND_AST_MATCH_ARM, CONST_CS | CONST_PERSISTENT);
801+
REGISTER_NS_LONG_CONSTANT("ast", "AST_NAMED_ARG", ZEND_AST_NAMED_ARG, CONST_CS | CONST_PERSISTENT);
793802
REGISTER_NS_LONG_CONSTANT("ast", "AST_METHOD_CALL", ZEND_AST_METHOD_CALL, CONST_CS | CONST_PERSISTENT);
794803
REGISTER_NS_LONG_CONSTANT("ast", "AST_STATIC_CALL", ZEND_AST_STATIC_CALL, CONST_CS | CONST_PERSISTENT);
795804
REGISTER_NS_LONG_CONSTANT("ast", "AST_CONDITIONAL", ZEND_AST_CONDITIONAL, CONST_CS | CONST_PERSISTENT);

package.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
The values of `ast\flags\MODIFIER_*` and `ast\flags\PARAM_VARIADIC` had some overlap in some php 7 versions.
3434
The new constants will have the same values as `ast\flags\MODIFIER_*` in PHP 8.0+, but different values in PHP 7
3535
(and these flags will never be set in php 7).
36+
- Support PHP 8.0's named arguments.
3637
</notes>
3738
<contents>
3839
<dir name="/">
@@ -100,6 +101,7 @@
100101
<file name="php74_ordinary_class.phpt" role="test" />
101102
<file name="php74_parenthesized_conditional.phpt" role="test" />
102103
<file name="php74_type_hints.phpt" role="test" />
104+
<file name="php80_named_params.phpt" role="test" />
103105
<file name="php80_noncapturing_catch.phpt" role="test" />
104106
<file name="php80_promotion.phpt" role="test" />
105107
<file name="php80_static_type.phpt" role="test" />

php_ast.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ extern ast_str_globals str_globals;
6666
# define ZEND_AST_ATTRIBUTE 0x2fd
6767
# define ZEND_AST_MATCH 0x2fc
6868
# define ZEND_AST_MATCH_ARM 0x2fb
69+
# define ZEND_AST_NAMED_ARG 0x2fa
6970
// NOTE: The first hex digit is the number of child nodes a given kind has
7071
#endif
7172

scripts/generate_ast_data.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@
132132
'ZEND_AST_ATTRIBUTE' => ['class', 'args'],
133133
'ZEND_AST_MATCH' => ['cond', 'stmts'],
134134
'ZEND_AST_MATCH_ARM' => ['cond', 'expr'],
135+
'ZEND_AST_NAMED_ARG' => ['name', 'expr'],
135136

136137
/* 3 child nodes */
137138
'ZEND_AST_METHOD_CALL' => ['expr', 'method', 'args'],

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: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,16 @@ $code = <<<'PHP'
1111
<?php
1212
namespace NS;
1313
14-
<<\SomeAttribute()>>
14+
@@\SomeAttribute()
1515
class X {
16-
<<Attr1>>
17-
<<Attr2(true)>>
16+
@@Attr1
17+
@@Attr2(true)
1818
public $prop;
1919
20-
<<Attr3>>
20+
@@Attr3
2121
public const CONST_WITH_ATTRIBUTE = 123;
2222
23-
<<Attr4>>
23+
@@Attr4
2424
public static function hasAttribute() {}
2525
}
2626
PHP;

tests/metadata.phpt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ AST_GROUP_USE: [USE_NORMAL, USE_FUNCTION, USE_CONST]
119119
AST_ATTRIBUTE: []
120120
AST_MATCH: []
121121
AST_MATCH_ARM: []
122+
AST_NAMED_ARG: []
122123
AST_METHOD_CALL: []
123124
AST_STATIC_CALL: []
124125
AST_CONDITIONAL: (combinable) [PARENTHESIZED_CONDITIONAL]

tests/php80_named_params.phpt

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
--TEST--
2+
Named parameters 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+
$foo(first: 1, second: 2);
13+
count(var: $argv);
14+
$other->count(1, myVar:$foo, myVar: 1); // error
15+
PHP;
16+
17+
$node = ast\parse_code($code, $version=70);
18+
echo ast_dump($node), "\n";
19+
--EXPECTF--
20+
AST_STMT_LIST
21+
0: AST_CALL
22+
expr: AST_VAR
23+
name: "foo"
24+
args: AST_ARG_LIST
25+
0: AST_NAMED_ARG
26+
name: "first"
27+
expr: 1
28+
1: AST_NAMED_ARG
29+
name: "second"
30+
expr: 2
31+
1: AST_CALL
32+
expr: AST_NAME
33+
flags: NAME_NOT_FQ (%d)
34+
name: "count"
35+
args: AST_ARG_LIST
36+
0: AST_NAMED_ARG
37+
name: "var"
38+
expr: AST_VAR
39+
name: "argv"
40+
2: AST_METHOD_CALL
41+
expr: AST_VAR
42+
name: "other"
43+
method: "count"
44+
args: AST_ARG_LIST
45+
0: 1
46+
1: AST_NAMED_ARG
47+
name: "myVar"
48+
expr: AST_VAR
49+
name: "foo"
50+
2: AST_NAMED_ARG
51+
name: "myVar"
52+
expr: 1

0 commit comments

Comments
 (0)