Skip to content

Commit 62820a3

Browse files
authored
Merge branch 'prettier' into feat-spread_operator_for_array
2 parents bf80c6f + 3279b7e commit 62820a3

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+2886
-657
lines changed

index.d.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,8 @@ declare module "php-parser" {
141141
T_COALESCE = 230,
142142
T_POW = 231,
143143
T_POW_EQUAL = 232,
144-
T_SPACESHIP = 233
144+
T_SPACESHIP = 233,
145+
T_COALESCE_EQUAL = 234
145146
}
146147

147148
/**

package-lock.json

Lines changed: 234 additions & 277 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/ast.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,8 @@ AST.prototype.resolvePrecedence = function(result, parser) {
336336
this.swapLocations(buffer, buffer.left, buffer.right, parser);
337337
result = buffer;
338338
}
339+
} else if (result.kind === "expressionstatement") {
340+
this.swapLocations(result, result.expression, result, parser);
339341
}
340342
return result;
341343
};

src/ast/encapsedpart.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,19 @@ const KIND = "encapsedpart";
1212
* Part of `Encapsed` node
1313
* @constructor EncapsedPart
1414
* @extends {Expression}
15-
* @property {Expression} what
15+
* @property {Expression} expression
16+
* @property {String} syntax
17+
* @property {Boolean} curly
1618
*/
1719
module.exports = Expression.extends(KIND, function EncapsedPart(
1820
expression,
21+
syntax,
1922
curly,
2023
docs,
2124
location
2225
) {
2326
Expression.apply(this, [KIND, docs, location]);
2427
this.expression = expression;
28+
this.syntax = syntax;
2529
this.curly = curly;
2630
});

src/ast/nowdoc.js

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,14 @@ const KIND = "nowdoc";
1414
* @extends {Literal}
1515
* @property {String} label
1616
* @property {String} raw
17-
* @property {Boolean} quote
1817
*/
1918
module.exports = Literal.extends(KIND, function Nowdoc(
2019
value,
2120
raw,
2221
label,
23-
quote,
2422
docs,
2523
location
2624
) {
2725
Literal.apply(this, [KIND, value, raw, docs, location]);
2826
this.label = label;
29-
this.quote = quote;
3027
});

src/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ const engine = function(options) {
9696
}
9797
options.lexer.php7 = options.parser.php7;
9898
options.lexer.php73 = options.parser.php73;
99+
options.lexer.php74 = options.parser.php74;
99100
}
100101
combine(options, this);
101102
}

src/lexer.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ const lexer = function(engine) {
3131
this.short_tags = false;
3232
this.php7 = true;
3333
this.php73 = true;
34+
this.php74 = true;
3435
this.yyprevcol = 0;
3536
this.keywords = {
3637
__class__: this.tok.T_CLASS_C,

src/lexer/tokens.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,8 +154,13 @@ module.exports = {
154154
},
155155
"?": function() {
156156
if (this.php7 && this._input[this.offset] === "?") {
157-
this.input();
158-
return this.tok.T_COALESCE;
157+
if (this.php74 && this._input[this.offset + 1] === "=") {
158+
this.consume(2);
159+
return this.tok.T_COALESCE_EQUAL;
160+
} else {
161+
this.input();
162+
return this.tok.T_COALESCE;
163+
}
159164
}
160165
return "?";
161166
},

src/parser/class.js

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ module.exports = {
1414
*/
1515
read_class_declaration_statement: function() {
1616
const result = this.node("class");
17-
const flag = this.read_class_scope();
17+
const flag = this.read_class_modifiers();
1818
// graceful mode : ignore token & go next
1919
if (this.token !== this.tok.T_CLASS) {
2020
this.error(this.tok.T_CLASS);
@@ -32,23 +32,25 @@ module.exports = {
3232
const body = this.next().read_class_body();
3333
return result(propName, propExtends, propImplements, body, flag);
3434
},
35-
/**
36-
* Read the class visibility
37-
* ```ebnf
38-
* class_scope ::= (T_FINAL | T_ABSTRACT)?
39-
* ```
40-
*/
41-
read_class_scope: function() {
42-
const result = this.token;
43-
if (result == this.tok.T_FINAL) {
35+
36+
read_class_modifiers: function() {
37+
return [0, 0, this.read_class_modifier()];
38+
},
39+
40+
read_class_modifier: function() {
41+
let result = 0;
42+
43+
if (this.token === this.tok.T_ABSTRACT) {
4444
this.next();
45-
return [0, 0, 2];
46-
} else if (result == this.tok.T_ABSTRACT) {
45+
return 1;
46+
} else if (this.token === this.tok.T_FINAL) {
4747
this.next();
48-
return [0, 0, 1];
48+
return 2;
4949
}
50-
return [0, 0, 0];
50+
51+
return result;
5152
},
53+
5254
/**
5355
* Reads a class body
5456
* ```ebnf
@@ -344,7 +346,7 @@ module.exports = {
344346
* trait ::= T_TRAIT T_STRING (T_EXTENDS (NAMESPACE_NAME ',')* NAMESPACE_NAME)? '{' FUNCTION* '}'
345347
* ```
346348
*/
347-
read_trait: function() {
349+
read_trait_declaration_statement: function() {
348350
const result = this.node("trait");
349351
// graceful mode : ignore token & go next
350352
if (this.token !== this.tok.T_TRAIT) {

src/parser/expr.js

Lines changed: 102 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -126,10 +126,98 @@ module.exports = {
126126
/**
127127
* Reads isset variables
128128
*/
129-
read_isset_variables: function () {
129+
read_isset_variables: function() {
130130
return this.read_function_list(this.read_isset_variable, ",");
131131
},
132132

133+
/*
134+
* Reads internal PHP functions
135+
*/
136+
read_internal_functions_in_yacc: function() {
137+
let result = null;
138+
switch (this.token) {
139+
case this.tok.T_ISSET:
140+
{
141+
result = this.node("isset");
142+
if (this.next().expect("(")) {
143+
this.next();
144+
}
145+
const variables = this.read_isset_variables();
146+
if (this.expect(")")) {
147+
this.next();
148+
}
149+
result = result(variables);
150+
}
151+
break;
152+
case this.tok.T_EMPTY:
153+
{
154+
result = this.node("empty");
155+
if (this.next().expect("(")) {
156+
this.next();
157+
}
158+
const expression = this.read_expr();
159+
if (this.expect(")")) {
160+
this.next();
161+
}
162+
result = result(expression);
163+
}
164+
break;
165+
case this.tok.T_INCLUDE:
166+
result = this.node("include")(false, false, this.next().read_expr());
167+
break;
168+
case this.tok.T_INCLUDE_ONCE:
169+
result = this.node("include")(true, false, this.next().read_expr());
170+
break;
171+
case this.tok.T_EVAL:
172+
{
173+
result = this.node("eval");
174+
if (this.next().expect("(")) {
175+
this.next();
176+
}
177+
const expr = this.read_expr();
178+
if (this.expect(")")) {
179+
this.next();
180+
}
181+
result = result(expr);
182+
}
183+
break;
184+
case this.tok.T_REQUIRE:
185+
result = this.node("include")(false, true, this.next().read_expr());
186+
break;
187+
case this.tok.T_REQUIRE_ONCE:
188+
result = this.node("include")(true, true, this.next().read_expr());
189+
break;
190+
}
191+
192+
return result;
193+
},
194+
195+
/**
196+
* Reads optional expression
197+
*/
198+
read_optional_expr: function(stopToken) {
199+
if (this.token !== stopToken) {
200+
return this.read_expr();
201+
}
202+
203+
return null;
204+
},
205+
206+
/**
207+
* Reads exit expression
208+
*/
209+
read_exit_expr: function() {
210+
let expression = null;
211+
212+
if (this.token === "(") {
213+
this.next();
214+
expression = this.read_optional_expr(')');
215+
this.expect(')') && this.next();
216+
}
217+
218+
return expression;
219+
},
220+
133221
/**
134222
* ```ebnf
135223
* Reads an expression
@@ -224,51 +312,14 @@ module.exports = {
224312
case this.tok.T_NEW:
225313
return this.read_new_expr();
226314

227-
case this.tok.T_ISSET: {
228-
result = this.node("isset");
229-
if (this.next().expect("(")) {
230-
this.next();
231-
}
232-
const variables = this.read_isset_variables();
233-
if (this.expect(")")) {
234-
this.next();
235-
}
236-
return result(variables);
237-
}
238-
case this.tok.T_EMPTY: {
239-
result = this.node("empty");
240-
if (this.next().expect("(")) {
241-
this.next();
242-
}
243-
const expression = this.read_expr();
244-
if (this.expect(")")) {
245-
this.next();
246-
}
247-
return result(expression);
248-
}
315+
case this.tok.T_ISSET:
316+
case this.tok.T_EMPTY:
249317
case this.tok.T_INCLUDE:
250-
return this.node("include")(false, false, this.next().read_expr());
251-
252318
case this.tok.T_INCLUDE_ONCE:
253-
return this.node("include")(true, false, this.next().read_expr());
254-
319+
case this.tok.T_EVAL:
255320
case this.tok.T_REQUIRE:
256-
return this.node("include")(false, true, this.next().read_expr());
257-
258321
case this.tok.T_REQUIRE_ONCE:
259-
return this.node("include")(true, true, this.next().read_expr());
260-
261-
case this.tok.T_EVAL:
262-
result = this.node("eval");
263-
if (this.next().expect("(")) {
264-
this.next();
265-
}
266-
expr = this.read_expr();
267-
if (this.expect(")")) {
268-
this.next();
269-
}
270-
return result(expr);
271-
322+
return this.read_internal_functions_in_yacc();
272323
case this.tok.T_INT_CAST:
273324
return this.read_expr_cast("int");
274325

@@ -295,17 +346,8 @@ module.exports = {
295346
case this.tok.T_EXIT: {
296347
const useDie = this.lexer.yytext.toLowerCase() === "die";
297348
result = this.node("exit");
298-
let expression = null;
299-
if (this.next().token === "(") {
300-
if (this.next().token !== ")") {
301-
expression = this.read_expr();
302-
if (this.expect(")")) {
303-
this.next();
304-
}
305-
} else {
306-
this.next();
307-
}
308-
}
349+
this.next();
350+
const expression = this.read_exit_expr();
309351
return result(expression, useDie);
310352
}
311353

@@ -433,6 +475,10 @@ module.exports = {
433475
if (isConst) this.error("VARIABLE");
434476
return result("assign", expr, this.next().read_expr(), ">>=");
435477

478+
case this.tok.T_COALESCE_EQUAL:
479+
if (isConst) this.error("VARIABLE");
480+
return result("assign", expr, this.next().read_expr(), "??=");
481+
436482
case this.tok.T_INC:
437483
if (isConst) this.error("VARIABLE");
438484
this.next();
@@ -483,7 +529,7 @@ module.exports = {
483529
const what = this.node("class");
484530
// Annonymous class declaration
485531
if (this.next().token === "(") {
486-
args = this.read_function_argument_list();
532+
args = this.read_argument_list();
487533
}
488534
const propExtends = this.read_extends_from();
489535
const propImplements = this.read_implements_list();
@@ -499,7 +545,7 @@ module.exports = {
499545
// Already existing class
500546
const name = this.read_new_class_name();
501547
if (this.token === "(") {
502-
args = this.read_function_argument_list();
548+
args = this.read_argument_list();
503549
}
504550
return result(name, args);
505551
},
@@ -537,7 +583,7 @@ module.exports = {
537583
expr = this.read_dereferencable(expr);
538584
} else if (this.token === "(") {
539585
// https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L1118
540-
expr = this.node("call")(expr, this.read_function_argument_list());
586+
expr = this.node("call")(expr, this.read_argument_list());
541587
} else {
542588
return expr;
543589
}

0 commit comments

Comments
 (0)