Skip to content

Commit

Permalink
Merge pull request #941 from czosel/fix-enum-as-identifier-2
Browse files Browse the repository at this point in the history
  • Loading branch information
MaartenStaa authored May 30, 2022
2 parents e9df70c + a9beddb commit 1517786
Show file tree
Hide file tree
Showing 3 changed files with 191 additions and 0 deletions.
23 changes: 23 additions & 0 deletions src/lexer/tokens.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,29 @@ module.exports = {
}
}

// https://github.com/php/php-src/blob/master/Zend/zend_language_scanner.l#L1546
if (id === this.tok.T_ENUM) {
if (this.version < 801) {
return this.tok.T_STRING;
}
const initial = this.offset;
let ch = this.input();
while (ch == " ") {
ch = this.input();
}
let isEnum = false;
if (this.is_LABEL_START()) {
while (this.is_LABEL()) {
ch += this.input();
}
const label = ch.slice(0, -1).toLowerCase();
isEnum = label !== "extends" && label !== "implements";
}

this.unput(this.offset - initial);
return isEnum ? this.tok.T_ENUM : this.tok.T_STRING;
}

if (this.offset < this.size && id !== this.tok.T_YIELD_FROM) {
// If immediately followed by a backslash, this is a T_NAME_RELATIVE or T_NAME_QUALIFIED.
let ch = this.input();
Expand Down
147 changes: 147 additions & 0 deletions test/snapshot/__snapshots__/enum.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -275,8 +275,155 @@ Program {
}
`;

exports[`Test enums can't be parsed with PHP < 8 1`] = `"Parse Error : syntax error, unexpected 'Foo' (T_STRING), expecting ';' on line 1"`;

exports[`Test enums cannot have properties 1`] = `"Parse Error : syntax error, unexpected 'int' (T_STRING) on line 3"`;

exports[`Test enums doesn't confuse enums with identifiers 1`] = `
Program {
"children": Array [
Class {
"attrGroups": Array [],
"body": Array [
Method {
"arguments": Array [],
"attrGroups": Array [],
"body": Block {
"children": Array [],
"kind": "block",
},
"byref": false,
"isAbstract": false,
"isFinal": false,
"isStatic": false,
"kind": "method",
"name": Identifier {
"kind": "identifier",
"name": "enum",
},
"nullable": false,
"type": null,
"visibility": "",
},
],
"extends": null,
"implements": null,
"isAbstract": false,
"isAnonymous": false,
"isFinal": false,
"kind": "class",
"name": Identifier {
"kind": "identifier",
"name": "Enum",
},
},
Interface {
"attrGroups": Array [],
"body": Array [],
"extends": null,
"kind": "interface",
"name": Identifier {
"kind": "identifier",
"name": "Enum",
},
},
Trait {
"body": Array [],
"kind": "trait",
"name": Identifier {
"kind": "identifier",
"name": "Enum",
},
},
_Function {
"arguments": Array [],
"attrGroups": Array [],
"body": Block {
"children": Array [],
"kind": "block",
},
"byref": false,
"kind": "function",
"name": Identifier {
"kind": "identifier",
"name": "enum",
},
"nullable": false,
"type": null,
},
Class {
"attrGroups": Array [],
"body": Array [],
"extends": Name {
"kind": "name",
"name": "Foo",
"resolution": "uqn",
},
"implements": null,
"isAbstract": false,
"isAnonymous": false,
"isFinal": false,
"kind": "class",
"name": Identifier {
"kind": "identifier",
"name": "Enum",
},
},
Class {
"attrGroups": Array [],
"body": Array [],
"extends": null,
"implements": Array [
Name {
"kind": "name",
"name": "Foo",
"resolution": "uqn",
},
],
"isAbstract": false,
"isAnonymous": false,
"isFinal": false,
"kind": "class",
"name": Identifier {
"kind": "identifier",
"name": "Enum",
},
},
Class {
"attrGroups": Array [],
"body": Array [],
"extends": Name {
"kind": "name",
"name": "Foo",
"resolution": "uqn",
},
"implements": null,
"isAbstract": false,
"isAnonymous": false,
"isFinal": false,
"kind": "class",
"name": Identifier {
"kind": "identifier",
"name": "Enum",
},
},
Enum {
"attrGroups": Array [],
"body": Array [],
"implements": null,
"kind": "enum",
"name": Identifier {
"kind": "identifier",
"name": "extendsFoo",
},
"valueType": null,
},
],
"errors": Array [],
"kind": "program",
}
`;

exports[`Test enums empty 1`] = `
Program {
"children": Array [
Expand Down
21 changes: 21 additions & 0 deletions test/snapshot/enum.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,4 +90,25 @@ describe("Test enums", function () {
`);
}).toThrowErrorMatchingSnapshot();
});

it("doesn't confuse enums with identifiers", function () {
expect(
parser.parseEval(`
class Enum { function enum () {} }
interface Enum {}
trait Enum {}
function enum() {}
class Enum extends Foo {}
class Enum implements Foo {}
class Enum exTends Foo {}
enum extendsFoo {}
`)
).toMatchSnapshot();
});

it("can't be parsed with PHP < 8", function () {
expect(() => {
parser.parseEval("enum Foo {}", { parser: { version: "8.0" } });
}).toThrowErrorMatchingSnapshot();
});
});

0 comments on commit 1517786

Please sign in to comment.