Skip to content

Commit 9ad99b6

Browse files
committed
add the variadic node
1 parent 36e64a8 commit 9ad99b6

File tree

5 files changed

+60
-2
lines changed

5 files changed

+60
-2
lines changed

docs/AST.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
- [Expression](#expression)
2020
- [Array](#array)
2121
- [Variable](#variable)
22+
- [Variadic](#variadic)
2223
- [ConstRef](#constref)
2324
- [Lookup](#lookup)
2425
- [PropertyLookup](#propertylookup)
@@ -1057,6 +1058,16 @@ be any expression in general, an expression can also be a pattern.
10571058
- `name` **([String](#string) \| [Node](#node))**
10581059
- `byref` **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)**
10591060

1061+
# Variadic
1062+
1063+
**Extends Expression**
1064+
1065+
Introduce a list of items into the arguments of the call
1066+
1067+
**Properties**
1068+
1069+
- `what` **([Array](#array) \| [Expression](#expression))**
1070+
10601071
# While
10611072

10621073
**Extends Statement**

src/ast.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ var Position = require('./ast/position');
2525
* - [Expression](#expression)
2626
* - [Array](#array)
2727
* - [Variable](#variable)
28+
* - [Variadic](#variadic)
2829
* - [ConstRef](#constref)
2930
* - [Lookup](#lookup)
3031
* - [PropertyLookup](#propertylookup)
@@ -245,6 +246,7 @@ AST.prototype.prepare = function(kind, parser) {
245246
require('./ast/usegroup'),
246247
require('./ast/useitem'),
247248
require('./ast/variable'),
249+
require('./ast/variadic'),
248250
require('./ast/while')
249251
].forEach(function (ctor) {
250252
var kind = ctor.prototype.constructor.name.toLowerCase();

src/ast/variadic.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/*!
2+
* Copyright (C) 2017 Glayzzle (BSD3 License)
3+
* @authors https://github.com/glayzzle/php-parser/graphs/contributors
4+
* @url http://glayzzle.com
5+
*/
6+
"use strict";
7+
var Expr = require('./expression');
8+
var KIND = 'variadic';
9+
10+
/**
11+
* Introduce a list of items into the arguments of the call
12+
* @constructor Variadic
13+
* @extends {Expression}
14+
* @property {Array|Expression} what
15+
* @see https://wiki.php.net/rfc/argument_unpacking
16+
*/
17+
var Variadic = Expr.extends(function Variadic(what, location) {
18+
Expr.apply(this, [KIND, location]);
19+
this.what = what;
20+
});
21+
22+
module.exports = Variadic;

src/parser/function.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,10 +178,17 @@ module.exports = {
178178
*/
179179
,read_function_argument_list: function() {
180180
var result = [];
181+
var wasVariadic = false;
181182
this.expect('(') && this.next();
182183
if (this.token !== ')') {
183184
while(this.token != this.EOF) {
184-
result.push(this.read_argument_list());
185+
var argument = this.read_argument_list();
186+
result.push(argument);
187+
if (argument.kind === 'variadic') {
188+
wasVariadic = true;
189+
} else if (wasVariadic) {
190+
this.raiseError('Unexpected argument after a variadic argument');
191+
}
185192
if (this.token === ',') {
186193
this.next();
187194
} else break;

test/functionTests.js

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,25 @@ describe('Function tests', function() {
66
'function &foo($a = 1, callable $b, ?array &...$params) : ?boolean {}',
77
'$a = function &($b) use($c) : array {',
88
' return true;',
9-
'};'
9+
'};',
10+
'$b = foo(...[1, null, 1, 2, 3]);'
1011
].join('\n'));
1112

13+
14+
it('test variadic error', function () {
15+
var astErr = parser.parseEval([
16+
'$b = foo(...[1, 2, 3], $a);'
17+
].join('\n'), {
18+
parser: {
19+
suppressErrors: true
20+
}
21+
});
22+
var msg = 'Unexpected argument after a variadic argument on line 1';
23+
astErr.errors.length.should.be.exactly(1);
24+
astErr.errors[0].line.should.be.exactly(1);
25+
astErr.errors[0].message.should.be.exactly(msg);
26+
});
27+
1228
it('test description', function () {
1329
// Get result from parser
1430
ast.children[0].kind.should.be.exactly('function');

0 commit comments

Comments
 (0)