diff --git a/src/ast.js b/src/ast.js index 0c2c5ea8a..2c7c5ab7b 100644 --- a/src/ast.js +++ b/src/ast.js @@ -323,18 +323,15 @@ AST.prototype.resolvePrecedence = function(result, parser) { result = buffer; } } - } else if ( - result.kind === "silent" && - !result.expr.parenthesizedExpression - ) { - if (result.expr.kind === 'assign') return result; + } else if (result.kind === "silent" && !result.expr.parenthesizedExpression) { + if (result.expr.kind === "assign") return result; // overall least precedence if (result.expr.right) { buffer = result.expr; result.expr = buffer.left; buffer.left = result; this.swapLocations(buffer, buffer.left, buffer.right, parser); - result = buffer; + result = buffer; } } return result; diff --git a/src/parser/statement.js b/src/parser/statement.js index a28770a84..a74d57fc2 100644 --- a/src/parser/statement.js +++ b/src/parser/statement.js @@ -353,11 +353,13 @@ module.exports = { case this.tok.T_STRING: { const result = this.node(); const current = [this.token, this.lexer.getState()]; - const label = this.text(); + const labelNameText = this.text(); // AST : https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L457 if (this.next().token === ":") { + let labelName = this.node("identifier"); this.next(); - return result("label", label); + labelName = labelName(labelNameText); + return result("label", labelName); } // default fallback expr / T_STRING '::' (etc...) @@ -371,12 +373,15 @@ module.exports = { case this.tok.T_GOTO: { const result = this.node("goto"); - let label = null; + let labelName = null; if (this.next().expect(this.tok.T_STRING)) { - label = this.text(); - this.next().expectEndOfStatement(); + labelName = this.node("identifier"); + const name = this.text(); + this.next(); + labelName = labelName(name); + this.expectEndOfStatement(); } - return result(label); + return result(labelName); } default: { diff --git a/test/snapshot/__snapshots__/acid.test.js.snap b/test/snapshot/__snapshots__/acid.test.js.snap index 757eeeddd..809cc0bf5 100644 --- a/test/snapshot/__snapshots__/acid.test.js.snap +++ b/test/snapshot/__snapshots__/acid.test.js.snap @@ -3118,7 +3118,23 @@ Program { "offset": 1660, }, }, - "name": "next", + "name": Identifier { + "kind": "identifier", + "loc": Location { + "end": Position { + "column": 5, + "line": 83, + "offset": 1665, + }, + "source": ":", + "start": Position { + "column": 4, + "line": 83, + "offset": 1664, + }, + }, + "name": "next", + }, }, ExpressionStatement { "expression": Assign { @@ -3663,7 +3679,23 @@ Program { "alternate": null, "body": Goto { "kind": "goto", - "label": "next", + "label": Identifier { + "kind": "identifier", + "loc": Location { + "end": Position { + "column": 49, + "line": 90, + "offset": 1847, + }, + "source": "next", + "start": Position { + "column": 45, + "line": 90, + "offset": 1843, + }, + }, + "name": "next", + }, "loc": Location { "end": Position { "column": 50, diff --git a/test/snapshot/__snapshots__/goto.test.js.snap b/test/snapshot/__snapshots__/goto.test.js.snap index faf46c4fa..21e1f7817 100644 --- a/test/snapshot/__snapshots__/goto.test.js.snap +++ b/test/snapshot/__snapshots__/goto.test.js.snap @@ -5,7 +5,39 @@ Program { "children": Array [ Goto { "kind": "goto", - "label": "a", + "label": Identifier { + "kind": "identifier", + "name": "a", + }, + }, + Echo { + "expressions": Array [ + String { + "isDoubleQuote": true, + "kind": "string", + "raw": "\\"Foo\\"", + "unicode": false, + "value": "Foo", + }, + ], + "kind": "echo", + "shortForm": false, + }, + ], + "errors": Array [], + "kind": "program", +} +`; + +exports[`goto simple 2`] = ` +Program { + "children": Array [ + Goto { + "kind": "goto", + "label": Identifier { + "kind": "identifier", + "name": "longName", + }, }, Echo { "expressions": Array [ diff --git a/test/snapshot/__snapshots__/label.test.js.snap b/test/snapshot/__snapshots__/label.test.js.snap index 93c4f7b5b..936f8310d 100644 --- a/test/snapshot/__snapshots__/label.test.js.snap +++ b/test/snapshot/__snapshots__/label.test.js.snap @@ -5,7 +5,39 @@ Program { "children": Array [ Label { "kind": "label", - "name": "a", + "name": Identifier { + "kind": "identifier", + "name": "a", + }, + }, + Echo { + "expressions": Array [ + String { + "isDoubleQuote": true, + "kind": "string", + "raw": "\\"Foo\\"", + "unicode": false, + "value": "Foo", + }, + ], + "kind": "echo", + "shortForm": false, + }, + ], + "errors": Array [], + "kind": "program", +} +`; + +exports[`label simple 2`] = ` +Program { + "children": Array [ + Label { + "kind": "label", + "name": Identifier { + "kind": "identifier", + "name": "longName", + }, }, Echo { "expressions": Array [ diff --git a/test/snapshot/__snapshots__/location.test.js.snap b/test/snapshot/__snapshots__/location.test.js.snap index 51ff6b836..79a404bfa 100644 --- a/test/snapshot/__snapshots__/location.test.js.snap +++ b/test/snapshot/__snapshots__/location.test.js.snap @@ -5873,12 +5873,83 @@ Program { } `; +exports[`Test locations goto #2 1`] = ` +Program { + "children": Array [ + Goto { + "kind": "goto", + "label": Identifier { + "kind": "identifier", + "loc": Location { + "end": Position { + "column": 13, + "line": 1, + "offset": 13, + }, + "source": "longName", + "start": Position { + "column": 5, + "line": 1, + "offset": 5, + }, + }, + "name": "longName", + }, + "loc": Location { + "end": Position { + "column": 14, + "line": 1, + "offset": 14, + }, + "source": "goto longName;", + "start": Position { + "column": 0, + "line": 1, + "offset": 0, + }, + }, + }, + ], + "errors": Array [], + "kind": "program", + "loc": Location { + "end": Position { + "column": 14, + "line": 1, + "offset": 14, + }, + "source": "goto longName;", + "start": Position { + "column": 0, + "line": 1, + "offset": 0, + }, + }, +} +`; + exports[`Test locations goto 1`] = ` Program { "children": Array [ Goto { "kind": "goto", - "label": "a", + "label": Identifier { + "kind": "identifier", + "loc": Location { + "end": Position { + "column": 6, + "line": 1, + "offset": 6, + }, + "source": "a", + "start": Position { + "column": 5, + "line": 1, + "offset": 5, + }, + }, + "name": "a", + }, "loc": Location { "end": Position { "column": 7, @@ -6766,6 +6837,100 @@ Program { } `; +exports[`Test locations label #2 1`] = ` +Program { + "children": Array [ + Label { + "kind": "label", + "loc": Location { + "end": Position { + "column": 9, + "line": 1, + "offset": 9, + }, + "source": "longName:", + "start": Position { + "column": 0, + "line": 1, + "offset": 0, + }, + }, + "name": Identifier { + "kind": "identifier", + "loc": Location { + "end": Position { + "column": 9, + "line": 1, + "offset": 9, + }, + "source": ":", + "start": Position { + "column": 8, + "line": 1, + "offset": 8, + }, + }, + "name": "longName", + }, + }, + Echo { + "expressions": Array [ + String { + "isDoubleQuote": true, + "kind": "string", + "loc": Location { + "end": Position { + "column": 26, + "line": 1, + "offset": 26, + }, + "source": "\\"something\\"", + "start": Position { + "column": 15, + "line": 1, + "offset": 15, + }, + }, + "raw": "\\"something\\"", + "unicode": false, + "value": "something", + }, + ], + "kind": "echo", + "loc": Location { + "end": Position { + "column": 27, + "line": 1, + "offset": 27, + }, + "source": "echo \\"something\\";", + "start": Position { + "column": 10, + "line": 1, + "offset": 10, + }, + }, + "shortForm": false, + }, + ], + "errors": Array [], + "kind": "program", + "loc": Location { + "end": Position { + "column": 27, + "line": 1, + "offset": 27, + }, + "source": "longName: echo \\"something\\";", + "start": Position { + "column": 0, + "line": 1, + "offset": 0, + }, + }, +} +`; + exports[`Test locations label 1`] = ` Program { "children": Array [ @@ -6784,7 +6949,23 @@ Program { "offset": 0, }, }, - "name": "a", + "name": Identifier { + "kind": "identifier", + "loc": Location { + "end": Position { + "column": 2, + "line": 1, + "offset": 2, + }, + "source": ":", + "start": Position { + "column": 1, + "line": 1, + "offset": 1, + }, + }, + "name": "a", + }, }, Echo { "expressions": Array [ diff --git a/test/snapshot/__snapshots__/statement.test.js.snap b/test/snapshot/__snapshots__/statement.test.js.snap index ec1eaa4c1..1e87a37f2 100644 --- a/test/snapshot/__snapshots__/statement.test.js.snap +++ b/test/snapshot/__snapshots__/statement.test.js.snap @@ -343,7 +343,10 @@ Program { "children": Array [ Label { "kind": "label", - "name": "start", + "name": Identifier { + "kind": "identifier", + "name": "start", + }, }, ExpressionStatement { "expression": Post { @@ -359,7 +362,10 @@ Program { }, Goto { "kind": "goto", - "label": "start", + "label": Identifier { + "kind": "identifier", + "name": "start", + }, }, ], "errors": Array [], diff --git a/test/snapshot/goto.test.js b/test/snapshot/goto.test.js index 25d47931c..2611d1b5a 100644 --- a/test/snapshot/goto.test.js +++ b/test/snapshot/goto.test.js @@ -1,7 +1,8 @@ -const parser = require('../main'); +const parser = require("../main"); describe("goto", function() { it("simple", function() { expect(parser.parseEval('goto a; echo "Foo";')).toMatchSnapshot(); + expect(parser.parseEval('goto longName; echo "Foo";')).toMatchSnapshot(); }); }); diff --git a/test/snapshot/label.test.js b/test/snapshot/label.test.js index 69085a62e..b7acae611 100644 --- a/test/snapshot/label.test.js +++ b/test/snapshot/label.test.js @@ -3,5 +3,6 @@ const parser = require('../main'); describe("label", function() { it("simple", function() { expect(parser.parseEval('a: echo "Foo";')).toMatchSnapshot(); + expect(parser.parseEval('longName: echo "Foo";')).toMatchSnapshot(); }); }); diff --git a/test/snapshot/location.test.js b/test/snapshot/location.test.js index 789220c17..8fc0bda19 100644 --- a/test/snapshot/location.test.js +++ b/test/snapshot/location.test.js @@ -312,6 +312,16 @@ describe("Test locations", function() { }) ).toMatchSnapshot(); }); + it("goto #2", function() { + expect( + parser.parseEval("goto longName;", { + ast: { + withPositions: true, + withSource: true + } + }) + ).toMatchSnapshot(); + }); it("label", function() { expect( parser.parseEval('a: echo "something";', { @@ -322,6 +332,16 @@ describe("Test locations", function() { }) ).toMatchSnapshot(); }); + it("label #2", function() { + expect( + parser.parseEval('longName: echo "something";', { + ast: { + withPositions: true, + withSource: true + } + }) + ).toMatchSnapshot(); + }); it("function", function() { expect( parser.parseEval('function fn() { echo "something"; }', {