Skip to content

Commit 8741d13

Browse files
fix: invalid parsing of traitalias
1 parent 0df5a49 commit 8741d13

File tree

5 files changed

+605
-35
lines changed

5 files changed

+605
-35
lines changed

src/ast/traitalias.js

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,22 +26,26 @@ module.exports = Node.extends(KIND, function TraitAlias(
2626
trait,
2727
method,
2828
as,
29-
flags,
29+
visibility,
3030
docs,
3131
location
3232
) {
3333
Node.apply(this, [KIND, docs, location]);
3434
this.trait = trait;
3535
this.method = method;
3636
this.as = as;
37-
this.visibility = IS_UNDEFINED;
38-
if (flags) {
39-
if (flags[0] === 0) {
37+
38+
switch (visibility) {
39+
case 0:
4040
this.visibility = IS_PUBLIC;
41-
} else if (flags[0] === 1) {
41+
break;
42+
case 1:
4243
this.visibility = IS_PROTECTED;
43-
} else if (flags[0] === 2) {
44+
break;
45+
case 2:
4446
this.visibility = IS_PRIVATE;
45-
}
47+
break;
48+
default:
49+
this.visibility = IS_UNDEFINED;
4650
}
4751
});

src/parser/class.js

Lines changed: 81 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,40 @@ module.exports = {
203203

204204
return result(null, items, flags);
205205
},
206+
207+
read_member_modifier: function() {
208+
let modifier;
209+
210+
switch (this.token) {
211+
case this.tok.T_PUBLIC:
212+
modifier = 0;
213+
break;
214+
case this.tok.T_PROTECTED:
215+
modifier = 1;
216+
break;
217+
case this.tok.T_PRIVATE:
218+
modifier = 2;
219+
break;
220+
case this.tok.T_STATIC:
221+
modifier = 3;
222+
break;
223+
case this.tok.T_ABSTRACT:
224+
modifier = 4;
225+
break;
226+
case this.tok.T_FINAL:
227+
modifier = 5;
228+
break;
229+
default: {
230+
const err = this.error("T_MEMBER_FLAGS");
231+
this.next();
232+
return err;
233+
}
234+
}
235+
236+
this.next();
237+
return modifier;
238+
},
239+
206240
/**
207241
* Read member flags
208242
* @return array
@@ -213,31 +247,34 @@ module.exports = {
213247
read_member_flags: function(asInterface) {
214248
const result = [-1, -1, -1];
215249
if (this.is("T_MEMBER_FLAGS")) {
216-
let idx = 0,
217-
val = 0;
218250
do {
219-
switch (this.token) {
220-
case this.tok.T_PUBLIC:
251+
let idx = 0;
252+
let val = 0;
253+
254+
const visibility = this.read_member_modifier();
255+
256+
switch (visibility) {
257+
case 0:
221258
idx = 0;
222259
val = 0;
223260
break;
224-
case this.tok.T_PROTECTED:
261+
case 1:
225262
idx = 0;
226263
val = 1;
227264
break;
228-
case this.tok.T_PRIVATE:
265+
case 2:
229266
idx = 0;
230267
val = 2;
231268
break;
232-
case this.tok.T_STATIC:
269+
case 3:
233270
idx = 1;
234271
val = 1;
235272
break;
236-
case this.tok.T_ABSTRACT:
273+
case 4:
237274
idx = 2;
238275
val = 1;
239276
break;
240-
case this.tok.T_FINAL:
277+
case 5:
241278
idx = 2;
242279
val = 2;
243280
break;
@@ -259,7 +296,7 @@ module.exports = {
259296
} else if (val !== -1) {
260297
result[idx] = val;
261298
}
262-
} while (this.next().is("T_MEMBER_FLAGS"));
299+
} while (this.is("T_MEMBER_FLAGS"));
263300
}
264301

265302
if (result[1] == -1) result[1] = 0;
@@ -372,18 +409,18 @@ module.exports = {
372409
const node = this.node("traituse");
373410
this.expect(this.tok.T_USE) && this.next();
374411
const traits = [this.read_namespace_name()];
375-
let adaptations = null;
376412
while (this.token === ",") {
377413
traits.push(this.next().read_namespace_name());
378414
}
415+
const adaptations = this.read_trait_adaptations();
416+
return node(traits, adaptations);
417+
},
418+
419+
read_trait_adaptations: function() {
420+
let adaptations = null;
421+
379422
if (this.token === "{") {
380-
adaptations = [];
381-
// defines alias statements
382-
while (this.next().token !== this.EOF) {
383-
if (this.token === "}") break;
384-
adaptations.push(this.read_trait_use_alias());
385-
this.expect(";");
386-
}
423+
adaptations = this.read_trait_adaptation_list();
387424
if (this.expect("}")) {
388425
this.next();
389426
}
@@ -392,17 +429,34 @@ module.exports = {
392429
this.next();
393430
}
394431
}
395-
return node(traits, adaptations);
432+
433+
return adaptations;
396434
},
435+
436+
/*
437+
* Reads trait adaptation list
438+
*/
439+
read_trait_adaptation_list: function() {
440+
let adaptations = [];
441+
// defines alias statements
442+
while (this.next().token !== this.EOF) {
443+
if (this.token === "}") break;
444+
adaptations.push(this.read_trait_adaptation());
445+
this.expect(";");
446+
}
447+
448+
return adaptations;
449+
},
450+
397451
/**
398-
* Reading trait alias
452+
* Reading trait adaptation
399453
* ```ebnf
400454
* trait_use_alias ::= namespace_name ( T_DOUBLE_COLON T_STRING )? (T_INSTEADOF namespace_name) | (T_AS member_flags? T_STRING)
401455
* ```
402456
* name list : https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L303
403457
* trait adaptation : https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L742
404458
*/
405-
read_trait_use_alias: function() {
459+
read_trait_adaptation: function() {
406460
const node = this.node();
407461
let trait = null;
408462
let method;
@@ -445,10 +499,11 @@ module.exports = {
445499
);
446500
} else if (this.token === this.tok.T_AS) {
447501
// handle trait alias
448-
let flags = null;
502+
let visibility = null;
449503
let alias = null;
450-
if (this.next().is("T_MEMBER_FLAGS")) {
451-
flags = this.read_member_flags();
504+
this.next();
505+
if (this.is("T_MEMBER_FLAGS")) {
506+
visibility = this.read_member_modifier();
452507
}
453508

454509
if (
@@ -459,12 +514,12 @@ module.exports = {
459514
const name = this.text();
460515
this.next();
461516
alias = alias(name);
462-
} else if (flags === false) {
517+
} else if (visibility === false) {
463518
// no visibility flags and no name => too bad
464519
this.expect(this.tok.T_STRING);
465520
}
466521

467-
return node("traitalias", trait, method, alias, flags);
522+
return node("traitalias", trait, method, alias, visibility);
468523
}
469524

470525
// handle errors

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -575,8 +575,8 @@ Program {
575575
"expected": undefined,
576576
"kind": "error",
577577
"line": 3,
578-
"message": "Parse Error : syntax error, unexpected 'abstract' (T_ABSTRACT) on line 3",
579-
"token": "'abstract' (T_ABSTRACT)",
578+
"message": "Parse Error : syntax error, unexpected 'function' (T_FUNCTION) on line 3",
579+
"token": "'function' (T_FUNCTION)",
580580
},
581581
Error {
582582
"expected": ";",

0 commit comments

Comments
 (0)