Skip to content

Commit ccc0e2e

Browse files
committed
1 parent 162e8e8 commit ccc0e2e

File tree

9 files changed

+593
-31
lines changed

9 files changed

+593
-31
lines changed

src/parser.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ const parser = function(lexer, ast) {
3434
this.prev = null;
3535
this.debug = false;
3636
this.php7 = true;
37+
this.php73 = true;
3738
this.php74 = true;
3839
this.extractDoc = false;
3940
this.extractTokens = false;
@@ -264,6 +265,7 @@ parser.prototype.parse = function(code, filename) {
264265
this._tokens = null;
265266
}
266267
if (!this.php7) {
268+
this.php73 = false;
267269
this.php74 = false;
268270
}
269271
this._docIndex = 0;

src/parser/expr.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ module.exports = {
215215
if (this.next().expect("(")) {
216216
this.next();
217217
}
218-
const variables = this.read_list(this.read_expr, ",");
218+
const variables = this.read_function_list(this.read_expr, ",");
219219
if (this.expect(")")) {
220220
this.next();
221221
}

src/parser/function.js

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -218,24 +218,22 @@ module.exports = {
218218
* ```
219219
*/
220220
read_function_argument_list: function() {
221-
const result = [];
221+
let result = [];
222222
let wasVariadic = false;
223223
this.expect("(") && this.next();
224224
if (this.token !== ")") {
225-
while (this.token != this.EOF) {
225+
result = this.read_function_list(function() {
226226
const argument = this.read_argument_list();
227227
if (argument) {
228-
result.push(argument);
229-
if (argument.kind === "variadic") {
230-
wasVariadic = true;
231-
} else if (wasVariadic) {
228+
if (wasVariadic) {
232229
this.raiseError("Unexpected argument after a variadic argument");
233230
}
231+
if (argument.kind === "variadic") {
232+
wasVariadic = true;
233+
}
234234
}
235-
if (this.token === ",") {
236-
this.next();
237-
} else break;
238-
}
235+
return argument;
236+
}.bind(this), ',');
239237
}
240238
this.expect(")") && this.next();
241239
return result;

src/parser/statement.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ module.exports = {
264264
const result = this.node("echo");
265265
const text = this.text();
266266
const shortForm = text === "<?=" || text === "<%=";
267-
const expressions = this.next().read_list(this.read_expr, ",");
267+
const expressions = this.next().read_function_list(this.read_expr, ",");
268268
this.expectEndOfStatement();
269269
return result(expressions, shortForm);
270270
}
@@ -294,7 +294,7 @@ module.exports = {
294294
case this.tok.T_UNSET: {
295295
const result = this.node("unset");
296296
this.next().expect("(") && this.next();
297-
const variables = this.read_list(this.read_variable, ",");
297+
const variables = this.read_function_list(this.read_variable, ",");
298298
this.expect(")") && this.next();
299299
this.expect(";") && this.next();
300300
return result(variables);

src/parser/utils.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,30 @@ module.exports = {
2323
return body(null, items);
2424
},
2525

26+
/**
27+
* https://wiki.php.net/rfc/trailing-comma-function-calls
28+
* @param {*} item
29+
* @param {*} separator
30+
*/
31+
read_function_list: function(item, separator) {
32+
const result = [];
33+
do {
34+
if (this.token == separator && this.php73 && result.length > 0) {
35+
result.push(this.node('noop')());
36+
break;
37+
}
38+
result.push(item.apply(this, []));
39+
if (this.token != separator) {
40+
break;
41+
}
42+
if (this.next().token == ')' && this.php73) {
43+
result.push(this.node('noop')());
44+
break;
45+
}
46+
} while (this.token != this.EOF);
47+
return result;
48+
},
49+
2650
/**
2751
* Helper : reads a list of tokens / sample : T_STRING ',' T_STRING ...
2852
* ```ebnf

test/debug.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,14 @@
1717
const util = require('util');
1818
const parser = require("../src/index");
1919
const ast = parser.parseEval(`
20-
@$var += 10
20+
$foo = new Foo(
21+
'constructor',
22+
'bar',
23+
);
2124
`, {
2225
parser: {
2326
debug: true,
27+
php73: true,
2428
extractDoc: true
2529
},
2630
/*ast: {

test/snapshot/__snapshots__/graceful.test.js.snap

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -506,6 +506,9 @@ Program {
506506
"kind": "variable",
507507
"name": "arg",
508508
},
509+
Noop {
510+
"kind": "noop",
511+
},
509512
],
510513
"kind": "call",
511514
"what": PropertyLookup {
@@ -539,6 +542,9 @@ Program {
539542
"kind": "variable",
540543
"name": "baz",
541544
},
545+
Noop {
546+
"kind": "noop",
547+
},
542548
],
543549
"kind": "new",
544550
"what": ClassReference {
@@ -550,6 +556,10 @@ Program {
550556
},
551557
"kind": "expressionstatement",
552558
},
559+
ExpressionStatement {
560+
"expression": undefined,
561+
"kind": "expressionstatement",
562+
},
553563
ExpressionStatement {
554564
"expression": Variable {
555565
"curly": false,
@@ -564,33 +574,26 @@ Program {
564574
},
565575
],
566576
"errors": Array [
567-
Error {
568-
"expected": "EXPR",
569-
"kind": "error",
570-
"line": 2,
571-
"message": "Parse Error : syntax error, unexpected ')' on line 2",
572-
"token": "')'",
573-
},
574577
Error {
575578
"expected": ")",
576579
"kind": "error",
577-
"line": 2,
578-
"message": "Parse Error : syntax error, unexpected ';', expecting ')' on line 2",
579-
"token": "';'",
580+
"line": 3,
581+
"message": "Parse Error : syntax error, unexpected ',', expecting ')' on line 3",
582+
"token": "','",
580583
},
581584
Error {
582-
"expected": "EXPR",
585+
"expected": ";",
583586
"kind": "error",
584587
"line": 3,
585-
"message": "Parse Error : syntax error, unexpected ',' on line 3",
588+
"message": "Parse Error : syntax error, unexpected ',', expecting ';' on line 3",
586589
"token": "','",
587590
},
588591
Error {
589-
"expected": ")",
592+
"expected": "EXPR",
590593
"kind": "error",
591594
"line": 3,
592-
"message": "Parse Error : syntax error, unexpected '$foo' (T_VARIABLE), expecting ')' on line 3",
593-
"token": "'$foo' (T_VARIABLE)",
595+
"message": "Parse Error : syntax error, unexpected ',' on line 3",
596+
"token": "','",
594597
},
595598
Error {
596599
"expected": ";",

0 commit comments

Comments
 (0)