diff --git a/acorn/src/expression.js b/acorn/src/expression.js index 71b02016f..3342335c6 100644 --- a/acorn/src/expression.js +++ b/acorn/src/expression.js @@ -838,16 +838,14 @@ pp.parseFunctionBody = function(node, isArrowFunction, isMethod) { // Add the params to varDeclaredNames to ensure that an error is thrown // if a let/const declaration in the function clashes with one of the params. this.checkParams(node, !oldStrict && !useStrict && !isArrowFunction && !isMethod && this.isSimpleParamList(node.params)) - node.body = this.parseBlock(false) + // Ensure the function name isn't a forbidden identifier in strict mode, e.g. 'eval' + if (this.strict && node.id) this.checkLVal(node.id, BIND_OUTSIDE) + node.body = this.parseBlock(false, undefined, useStrict && !oldStrict) node.expression = false this.adaptDirectivePrologue(node.body.body) this.labels = oldLabels } this.exitScope() - - // Ensure the function name isn't a forbidden identifier in strict mode, e.g. 'eval' - if (this.strict && node.id) this.checkLVal(node.id, BIND_OUTSIDE) - this.strict = oldStrict } pp.isSimpleParamList = function(params) { diff --git a/acorn/src/statement.js b/acorn/src/statement.js index 8cadb5118..d15bb8e73 100644 --- a/acorn/src/statement.js +++ b/acorn/src/statement.js @@ -418,14 +418,16 @@ pp.parseExpressionStatement = function(node, expr) { // strict"` declarations when `allowStrict` is true (used for // function bodies). -pp.parseBlock = function(createNewLexicalScope = true, node = this.startNode()) { +pp.parseBlock = function(createNewLexicalScope = true, node = this.startNode(), exitStrict) { node.body = [] this.expect(tt.braceL) if (createNewLexicalScope) this.enterScope(0) - while (!this.eat(tt.braceR)) { + while (this.type !== tt.braceR) { let stmt = this.parseStatement(null) node.body.push(stmt) } + if (exitStrict) this.strict = false + this.next() if (createNewLexicalScope) this.exitScope() return this.finishNode(node, "BlockStatement") } @@ -578,7 +580,7 @@ pp.parseClass = function(node, isStatement) { let hadConstructor = false classBody.body = [] this.expect(tt.braceL) - while (!this.eat(tt.braceR)) { + while (this.type !== tt.braceR) { const element = this.parseClassElement(node.superClass !== null) if (element) { classBody.body.push(element) @@ -588,8 +590,9 @@ pp.parseClass = function(node, isStatement) { } } } - node.body = this.finishNode(classBody, "ClassBody") this.strict = oldStrict + this.next() + node.body = this.finishNode(classBody, "ClassBody") return this.finishNode(node, isStatement ? "ClassDeclaration" : "ClassExpression") } diff --git a/test/tests-harmony.js b/test/tests-harmony.js index c6b58dd5c..e270abefa 100644 --- a/test/tests-harmony.js +++ b/test/tests-harmony.js @@ -16516,3 +16516,7 @@ test("({ a = 42, b: c.d } = e)", {}, {ecmaVersion: 6}) testFail("({ a = 42, b: c = d })", "Shorthand property assignments are valid only in destructuring patterns (1:5)", {ecmaVersion: 6}) test("({ __proto__: x, __proto__: y, __proto__: z }) => {}", {}, {ecmaVersion: 6}) + +// Don't parse first token after a class or strict function as strict +test("class x {}\n05", {}, {ecmaVersion: 6}) +test("function x() { 'use strict' }\n05", {}, {ecmaVersion: 6})