Skip to content

Commit

Permalink
Don't tokenize the token after a class or strict function as strict
Browse files Browse the repository at this point in the history
Closes #912
  • Loading branch information
marijnh committed Mar 2, 2020
1 parent c6f08e8 commit 44e52b2
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 9 deletions.
8 changes: 3 additions & 5 deletions acorn/src/expression.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
11 changes: 7 additions & 4 deletions acorn/src/statement.js
Original file line number Diff line number Diff line change
Expand Up @@ -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")
}
Expand Down Expand Up @@ -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)
Expand All @@ -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")
}

Expand Down
4 changes: 4 additions & 0 deletions test/tests-harmony.js
Original file line number Diff line number Diff line change
Expand Up @@ -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})

0 comments on commit 44e52b2

Please sign in to comment.