From dc596d73d3715c0c7b8543653733c3358d3b02b0 Mon Sep 17 00:00:00 2001 From: TSUYUSATO Kitsune Date: Sun, 22 Nov 2015 03:06:21 +0900 Subject: [PATCH] Fixed T6675 https://phabricator.babeljs.io/T6675. --- src/parser/statement.js | 61 ++++---- .../fixtures/core/uncategorised/542/actual.js | 2 + .../core/uncategorised/542/expected.json | 138 ++++++++++++++++++ 3 files changed, 167 insertions(+), 34 deletions(-) create mode 100644 test/fixtures/core/uncategorised/542/actual.js create mode 100644 test/fixtures/core/uncategorised/542/expected.json diff --git a/src/parser/statement.js b/src/parser/statement.js index d86f25bfc3..91357595b0 100644 --- a/src/parser/statement.js +++ b/src/parser/statement.js @@ -27,22 +27,21 @@ const loopLabel = {kind: "loop"}, switchLabel = {kind: "switch"}; // TODO -pp.parseDirective = function () { - let directiveLiteral = this.startNode(); - let directive = this.startNode(); +pp.stmtToDirective = function (stmt) { + let expr = stmt.expression; - let raw = this.input.slice(this.state.start, this.state.end); + let directiveLiteral = this.startNodeAt(expr.start, expr.loc.start); + let directive = this.startNodeAt(stmt.start, stmt.loc.start); + + let raw = this.input.slice(expr.start, expr.end); let val = directiveLiteral.value = raw.slice(1, -1); // remove quotes this.addExtra(directiveLiteral, "raw", raw); this.addExtra(directiveLiteral, "rawValue", val); - this.next(); + directive.value = this.finishNodeAt(directiveLiteral, "DirectiveLiteral", expr.end, expr.loc.end); - directive.value = this.finishNode(directiveLiteral, "DirectiveLiteral"); - - this.semicolon(); - return this.finishNode(directive, "Directive"); + return this.finishNodeAt(directive, "Directive", stmt.end, stmt.loc.end); }; // Parse a single statement. @@ -454,37 +453,31 @@ pp.parseBlockBody = function (node, allowDirectives, topLevel, end) { let octalPosition; while (!this.eat(end)) { - if (allowDirectives && !parsedNonDirective && this.match(tt.string)) { - let oldState = this.state; - let lookahead = this.lookahead(); - this.state = lookahead; - let isDirective = this.isLineTerminator(); - this.state = oldState; + if (!parsedNonDirective && this.state.containsOctal && !octalPosition) { + octalPosition = this.state.octalPosition; + } - if (isDirective) { - if (this.state.containsOctal && !octalPosition) { - octalPosition = this.state.octalPosition; + let stmt = this.parseStatement(true, topLevel); + + if (allowDirectives && !parsedNonDirective && + stmt.type === "ExpressionStatement" && stmt.expression.type === "StringLiteral") { + let directive = this.stmtToDirective(stmt); + node.directives.push(directive); + + if (directive.value.value === "use strict") { + oldStrict = this.state.strict; + this.setStrict(true); + + if (octalPosition) { + this.raise(octalPosition, "Octal literal in strict mode"); } - - let stmt = this.parseDirective(); - node.directives.push(stmt); - - if (allowDirectives && stmt.value.value === "use strict") { - oldStrict = this.state.strict; - this.state.strict = true; - this.setStrict(true); - - if (octalPosition) { - this.raise(octalPosition, "Octal literal in strict mode"); - } - } - - continue; } + + continue; } parsedNonDirective = true; - node.body.push(this.parseStatement(true, topLevel)); + node.body.push(stmt); } if (oldStrict === false) { diff --git a/test/fixtures/core/uncategorised/542/actual.js b/test/fixtures/core/uncategorised/542/actual.js new file mode 100644 index 0000000000..79c7df567c --- /dev/null +++ b/test/fixtures/core/uncategorised/542/actual.js @@ -0,0 +1,2 @@ +"foo" +.split(" ") diff --git a/test/fixtures/core/uncategorised/542/expected.json b/test/fixtures/core/uncategorised/542/expected.json new file mode 100644 index 0000000000..dac534f2f7 --- /dev/null +++ b/test/fixtures/core/uncategorised/542/expected.json @@ -0,0 +1,138 @@ +{ + "type": "File", + "start": 0, + "end": 17, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 2, + "column": 11 + } + }, + "program": { + "type": "Program", + "start": 0, + "end": 17, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 2, + "column": 11 + } + }, + "sourceType": "script", + "body": [ + { + "type": "ExpressionStatement", + "start": 0, + "end": 17, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 2, + "column": 11 + } + }, + "expression": { + "type": "CallExpression", + "start": 0, + "end": 17, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 2, + "column": 11 + } + }, + "callee": { + "type": "MemberExpression", + "start": 0, + "end": 12, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 2, + "column": 6 + } + }, + "object": { + "type": "StringLiteral", + "start": 0, + "end": 5, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 5 + } + }, + "extra": { + "rawValue": "foo", + "raw": "\"foo\"" + }, + "value": "foo" + }, + "property": { + "type": "Identifier", + "start": 7, + "end": 12, + "loc": { + "start": { + "line": 2, + "column": 1 + }, + "end": { + "line": 2, + "column": 6 + } + }, + "name": "split" + }, + "computed": false + }, + "arguments": [ + { + "type": "StringLiteral", + "start": 13, + "end": 16, + "loc": { + "start": { + "line": 2, + "column": 7 + }, + "end": { + "line": 2, + "column": 10 + } + }, + "extra": { + "rawValue": " ", + "raw": "\" \"" + }, + "value": " " + } + ] + } + } + ], + "directives": [] + } +}