Skip to content

Commit 8012fae

Browse files
TomasVotrubanikic
authored andcommitted
[PHP 7.4] Add array spread
1 parent f3b19c1 commit 8012fae

File tree

27 files changed

+1585
-1018
lines changed

27 files changed

+1585
-1018
lines changed

grammar/php5.y

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -988,6 +988,7 @@ array_pair:
988988
| expr { $$ = Expr\ArrayItem[$1, null, false]; }
989989
| expr T_DOUBLE_ARROW '&' variable { $$ = Expr\ArrayItem[$4, $1, true]; }
990990
| '&' variable { $$ = Expr\ArrayItem[$2, null, true]; }
991+
| T_ELLIPSIS expr { $$ = Expr\ArrayItem[$2, null, false, attributes(), true]; }
991992
;
992993

993994
encaps_list:

grammar/php7.y

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -983,6 +983,7 @@ array_pair:
983983
| expr { $$ = Expr\ArrayItem[$1, null, false]; }
984984
| expr T_DOUBLE_ARROW '&' variable { $$ = Expr\ArrayItem[$4, $1, true]; }
985985
| '&' variable { $$ = Expr\ArrayItem[$2, null, true]; }
986+
| T_ELLIPSIS expr { $$ = Expr\ArrayItem[$2, null, false, attributes(), true]; }
986987
| /* empty */ { $$ = null; }
987988
;
988989

lib/PhpParser/Node/Expr/ArrayItem.php

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ class ArrayItem extends Expr
1212
public $value;
1313
/** @var bool Whether to assign by reference */
1414
public $byRef;
15+
/** @var bool Whether to unpack the argument */
16+
public $unpack;
1517

1618
/**
1719
* Constructs an array item node.
@@ -21,17 +23,18 @@ class ArrayItem extends Expr
2123
* @param bool $byRef Whether to assign by reference
2224
* @param array $attributes Additional attributes
2325
*/
24-
public function __construct(Expr $value, Expr $key = null, bool $byRef = false, array $attributes = []) {
26+
public function __construct(Expr $value, Expr $key = null, bool $byRef = false, array $attributes = [], bool $unpack = false) {
2527
parent::__construct($attributes);
2628
$this->key = $key;
2729
$this->value = $value;
2830
$this->byRef = $byRef;
31+
$this->unpack = $unpack;
2932
}
3033

3134
public function getSubNodeNames() : array {
32-
return ['key', 'value', 'byRef'];
35+
return ['key', 'value', 'byRef', 'unpack'];
3336
}
34-
37+
3538
public function getType() : string {
3639
return 'Expr_ArrayItem';
3740
}

lib/PhpParser/Parser/Php5.php

Lines changed: 452 additions & 448 deletions
Large diffs are not rendered by default.

lib/PhpParser/Parser/Php7.php

Lines changed: 430 additions & 428 deletions
Large diffs are not rendered by default.

lib/PhpParser/Parser/Tokens.php

Lines changed: 137 additions & 138 deletions
Original file line numberDiff line numberDiff line change
@@ -6,142 +6,141 @@
66
final class Tokens
77
{
88
const YYERRTOK = 256;
9-
const T_ARROW_FUNCTION = 257;
10-
const T_INCLUDE = 258;
11-
const T_INCLUDE_ONCE = 259;
12-
const T_EVAL = 260;
13-
const T_REQUIRE = 261;
14-
const T_REQUIRE_ONCE = 262;
15-
const T_LOGICAL_OR = 263;
16-
const T_LOGICAL_XOR = 264;
17-
const T_LOGICAL_AND = 265;
18-
const T_PRINT = 266;
19-
const T_YIELD = 267;
20-
const T_DOUBLE_ARROW = 268;
21-
const T_YIELD_FROM = 269;
22-
const T_PLUS_EQUAL = 270;
23-
const T_MINUS_EQUAL = 271;
24-
const T_MUL_EQUAL = 272;
25-
const T_DIV_EQUAL = 273;
26-
const T_CONCAT_EQUAL = 274;
27-
const T_MOD_EQUAL = 275;
28-
const T_AND_EQUAL = 276;
29-
const T_OR_EQUAL = 277;
30-
const T_XOR_EQUAL = 278;
31-
const T_SL_EQUAL = 279;
32-
const T_SR_EQUAL = 280;
33-
const T_POW_EQUAL = 281;
34-
const T_COALESCE_EQUAL = 282;
35-
const T_COALESCE = 283;
36-
const T_BOOLEAN_OR = 284;
37-
const T_BOOLEAN_AND = 285;
38-
const T_IS_EQUAL = 286;
39-
const T_IS_NOT_EQUAL = 287;
40-
const T_IS_IDENTICAL = 288;
41-
const T_IS_NOT_IDENTICAL = 289;
42-
const T_SPACESHIP = 290;
43-
const T_IS_SMALLER_OR_EQUAL = 291;
44-
const T_IS_GREATER_OR_EQUAL = 292;
45-
const T_SL = 293;
46-
const T_SR = 294;
47-
const T_INSTANCEOF = 295;
48-
const T_INC = 296;
49-
const T_DEC = 297;
50-
const T_INT_CAST = 298;
51-
const T_DOUBLE_CAST = 299;
52-
const T_STRING_CAST = 300;
53-
const T_ARRAY_CAST = 301;
54-
const T_OBJECT_CAST = 302;
55-
const T_BOOL_CAST = 303;
56-
const T_UNSET_CAST = 304;
57-
const T_POW = 305;
58-
const T_NEW = 306;
59-
const T_CLONE = 307;
60-
const T_EXIT = 308;
61-
const T_IF = 309;
62-
const T_ELSEIF = 310;
63-
const T_ELSE = 311;
64-
const T_ENDIF = 312;
65-
const T_LNUMBER = 313;
66-
const T_DNUMBER = 314;
67-
const T_STRING = 315;
68-
const T_STRING_VARNAME = 316;
69-
const T_VARIABLE = 317;
70-
const T_NUM_STRING = 318;
71-
const T_INLINE_HTML = 319;
72-
const T_CHARACTER = 320;
73-
const T_BAD_CHARACTER = 321;
74-
const T_ENCAPSED_AND_WHITESPACE = 322;
75-
const T_CONSTANT_ENCAPSED_STRING = 323;
76-
const T_ECHO = 324;
77-
const T_DO = 325;
78-
const T_WHILE = 326;
79-
const T_ENDWHILE = 327;
80-
const T_FOR = 328;
81-
const T_ENDFOR = 329;
82-
const T_FOREACH = 330;
83-
const T_ENDFOREACH = 331;
84-
const T_DECLARE = 332;
85-
const T_ENDDECLARE = 333;
86-
const T_AS = 334;
87-
const T_SWITCH = 335;
88-
const T_ENDSWITCH = 336;
89-
const T_CASE = 337;
90-
const T_DEFAULT = 338;
91-
const T_BREAK = 339;
92-
const T_CONTINUE = 340;
93-
const T_GOTO = 341;
94-
const T_FUNCTION = 342;
95-
const T_FN = 343;
96-
const T_CONST = 344;
97-
const T_RETURN = 345;
98-
const T_TRY = 346;
99-
const T_CATCH = 347;
100-
const T_FINALLY = 348;
101-
const T_THROW = 349;
102-
const T_USE = 350;
103-
const T_INSTEADOF = 351;
104-
const T_GLOBAL = 352;
105-
const T_STATIC = 353;
106-
const T_ABSTRACT = 354;
107-
const T_FINAL = 355;
108-
const T_PRIVATE = 356;
109-
const T_PROTECTED = 357;
110-
const T_PUBLIC = 358;
111-
const T_VAR = 359;
112-
const T_UNSET = 360;
113-
const T_ISSET = 361;
114-
const T_EMPTY = 362;
115-
const T_HALT_COMPILER = 363;
116-
const T_CLASS = 364;
117-
const T_TRAIT = 365;
118-
const T_INTERFACE = 366;
119-
const T_EXTENDS = 367;
120-
const T_IMPLEMENTS = 368;
121-
const T_OBJECT_OPERATOR = 369;
122-
const T_LIST = 370;
123-
const T_ARRAY = 371;
124-
const T_CALLABLE = 372;
125-
const T_CLASS_C = 373;
126-
const T_TRAIT_C = 374;
127-
const T_METHOD_C = 375;
128-
const T_FUNC_C = 376;
129-
const T_LINE = 377;
130-
const T_FILE = 378;
131-
const T_COMMENT = 379;
132-
const T_DOC_COMMENT = 380;
133-
const T_OPEN_TAG = 381;
134-
const T_OPEN_TAG_WITH_ECHO = 382;
135-
const T_CLOSE_TAG = 383;
136-
const T_WHITESPACE = 384;
137-
const T_START_HEREDOC = 385;
138-
const T_END_HEREDOC = 386;
139-
const T_DOLLAR_OPEN_CURLY_BRACES = 387;
140-
const T_CURLY_OPEN = 388;
141-
const T_PAAMAYIM_NEKUDOTAYIM = 389;
142-
const T_NAMESPACE = 390;
143-
const T_NS_C = 391;
144-
const T_DIR = 392;
145-
const T_NS_SEPARATOR = 393;
146-
const T_ELLIPSIS = 394;
9+
const T_INCLUDE = 257;
10+
const T_INCLUDE_ONCE = 258;
11+
const T_EVAL = 259;
12+
const T_REQUIRE = 260;
13+
const T_REQUIRE_ONCE = 261;
14+
const T_LOGICAL_OR = 262;
15+
const T_LOGICAL_XOR = 263;
16+
const T_LOGICAL_AND = 264;
17+
const T_PRINT = 265;
18+
const T_YIELD = 266;
19+
const T_DOUBLE_ARROW = 267;
20+
const T_YIELD_FROM = 268;
21+
const T_PLUS_EQUAL = 269;
22+
const T_MINUS_EQUAL = 270;
23+
const T_MUL_EQUAL = 271;
24+
const T_DIV_EQUAL = 272;
25+
const T_CONCAT_EQUAL = 273;
26+
const T_MOD_EQUAL = 274;
27+
const T_AND_EQUAL = 275;
28+
const T_OR_EQUAL = 276;
29+
const T_XOR_EQUAL = 277;
30+
const T_SL_EQUAL = 278;
31+
const T_SR_EQUAL = 279;
32+
const T_POW_EQUAL = 280;
33+
const T_COALESCE_EQUAL = 281;
34+
const T_COALESCE = 282;
35+
const T_BOOLEAN_OR = 283;
36+
const T_BOOLEAN_AND = 284;
37+
const T_IS_EQUAL = 285;
38+
const T_IS_NOT_EQUAL = 286;
39+
const T_IS_IDENTICAL = 287;
40+
const T_IS_NOT_IDENTICAL = 288;
41+
const T_SPACESHIP = 289;
42+
const T_IS_SMALLER_OR_EQUAL = 290;
43+
const T_IS_GREATER_OR_EQUAL = 291;
44+
const T_SL = 292;
45+
const T_SR = 293;
46+
const T_INSTANCEOF = 294;
47+
const T_INC = 295;
48+
const T_DEC = 296;
49+
const T_INT_CAST = 297;
50+
const T_DOUBLE_CAST = 298;
51+
const T_STRING_CAST = 299;
52+
const T_ARRAY_CAST = 300;
53+
const T_OBJECT_CAST = 301;
54+
const T_BOOL_CAST = 302;
55+
const T_UNSET_CAST = 303;
56+
const T_POW = 304;
57+
const T_NEW = 305;
58+
const T_CLONE = 306;
59+
const T_EXIT = 307;
60+
const T_IF = 308;
61+
const T_ELSEIF = 309;
62+
const T_ELSE = 310;
63+
const T_ENDIF = 311;
64+
const T_LNUMBER = 312;
65+
const T_DNUMBER = 313;
66+
const T_STRING = 314;
67+
const T_STRING_VARNAME = 315;
68+
const T_VARIABLE = 316;
69+
const T_NUM_STRING = 317;
70+
const T_INLINE_HTML = 318;
71+
const T_CHARACTER = 319;
72+
const T_BAD_CHARACTER = 320;
73+
const T_ENCAPSED_AND_WHITESPACE = 321;
74+
const T_CONSTANT_ENCAPSED_STRING = 322;
75+
const T_ECHO = 323;
76+
const T_DO = 324;
77+
const T_WHILE = 325;
78+
const T_ENDWHILE = 326;
79+
const T_FOR = 327;
80+
const T_ENDFOR = 328;
81+
const T_FOREACH = 329;
82+
const T_ENDFOREACH = 330;
83+
const T_DECLARE = 331;
84+
const T_ENDDECLARE = 332;
85+
const T_AS = 333;
86+
const T_SWITCH = 334;
87+
const T_ENDSWITCH = 335;
88+
const T_CASE = 336;
89+
const T_DEFAULT = 337;
90+
const T_BREAK = 338;
91+
const T_CONTINUE = 339;
92+
const T_GOTO = 340;
93+
const T_FUNCTION = 341;
94+
const T_FN = 342;
95+
const T_CONST = 343;
96+
const T_RETURN = 344;
97+
const T_TRY = 345;
98+
const T_CATCH = 346;
99+
const T_FINALLY = 347;
100+
const T_THROW = 348;
101+
const T_USE = 349;
102+
const T_INSTEADOF = 350;
103+
const T_GLOBAL = 351;
104+
const T_STATIC = 352;
105+
const T_ABSTRACT = 353;
106+
const T_FINAL = 354;
107+
const T_PRIVATE = 355;
108+
const T_PROTECTED = 356;
109+
const T_PUBLIC = 357;
110+
const T_VAR = 358;
111+
const T_UNSET = 359;
112+
const T_ISSET = 360;
113+
const T_EMPTY = 361;
114+
const T_HALT_COMPILER = 362;
115+
const T_CLASS = 363;
116+
const T_TRAIT = 364;
117+
const T_INTERFACE = 365;
118+
const T_EXTENDS = 366;
119+
const T_IMPLEMENTS = 367;
120+
const T_OBJECT_OPERATOR = 368;
121+
const T_LIST = 369;
122+
const T_ARRAY = 370;
123+
const T_CALLABLE = 371;
124+
const T_CLASS_C = 372;
125+
const T_TRAIT_C = 373;
126+
const T_METHOD_C = 374;
127+
const T_FUNC_C = 375;
128+
const T_LINE = 376;
129+
const T_FILE = 377;
130+
const T_COMMENT = 378;
131+
const T_DOC_COMMENT = 379;
132+
const T_OPEN_TAG = 380;
133+
const T_OPEN_TAG_WITH_ECHO = 381;
134+
const T_CLOSE_TAG = 382;
135+
const T_WHITESPACE = 383;
136+
const T_START_HEREDOC = 384;
137+
const T_END_HEREDOC = 385;
138+
const T_DOLLAR_OPEN_CURLY_BRACES = 386;
139+
const T_CURLY_OPEN = 387;
140+
const T_PAAMAYIM_NEKUDOTAYIM = 388;
141+
const T_NAMESPACE = 389;
142+
const T_NS_C = 390;
143+
const T_DIR = 391;
144+
const T_NS_SEPARATOR = 392;
145+
const T_ELLIPSIS = 393;
147146
}

lib/PhpParser/PrettyPrinter/Standard.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -545,7 +545,9 @@ protected function pExpr_Array(Expr\Array_ $node) {
545545

546546
protected function pExpr_ArrayItem(Expr\ArrayItem $node) {
547547
return (null !== $node->key ? $this->p($node->key) . ' => ' : '')
548-
. ($node->byRef ? '&' : '') . $this->p($node->value);
548+
. ($node->byRef ? '&' : '')
549+
. ($node->unpack ? '...' : '')
550+
. $this->p($node->value);
549551
}
550552

551553
protected function pExpr_ArrayDimFetch(Expr\ArrayDimFetch $node) {

test/PhpParser/NodeDumperTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ public function provideTestDump() {
5353
value: Foo
5454
)
5555
byRef: false
56+
unpack: false
5657
)
5758
)
5859
)'
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
Array spread
2+
-----
3+
<?php
4+
$items = [
5+
...$value
6+
];
7+
-----
8+
$array = $stmts[0]->expr->expr;
9+
$array->items[] = new Expr\ArrayItem(new Expr\Variable('b'));
10+
-----
11+
<?php
12+
$items = [
13+
...$value, $b
14+
];
15+
-----
16+
<?php
17+
$items =
18+
[
19+
... $value
20+
];
21+
-----
22+
$array = $stmts[0]->expr->expr;
23+
$array->items[] = new Expr\ArrayItem(new Expr\Variable('c'), null, false, [], true);
24+
-----
25+
<?php
26+
$items =
27+
[
28+
... $value, ...$c
29+
];

0 commit comments

Comments
 (0)