Disallow async functions as loop bodies (#9314)

This commit is contained in:
Nicolò Ribaudo 2019-01-17 23:07:48 +01:00 committed by Henry Zhu
parent a27b9b4299
commit 0a88230ec4
9 changed files with 27 additions and 62 deletions

View File

@ -106,7 +106,12 @@ export default class StatementParser extends ExpressionParser {
return this.parseForStatement(node); return this.parseForStatement(node);
case tt._function: case tt._function:
if (this.lookahead().type === tt.dot) break; if (this.lookahead().type === tt.dot) break;
if (!declaration) this.unexpected(); if (!declaration) {
this.raise(
this.state.start,
"Function declaration not allowed in this context",
);
}
return this.parseFunctionStatement(node); return this.parseFunctionStatement(node);
case tt._class: case tt._class:
@ -189,7 +194,13 @@ export default class StatementParser extends ExpressionParser {
const state = this.state.clone(); const state = this.state.clone();
this.next(); this.next();
if (this.match(tt._function) && !this.canInsertSemicolon()) { if (this.match(tt._function) && !this.canInsertSemicolon()) {
this.expect(tt._function); if (!declaration) {
this.raise(
this.state.lastTokStart,
"Function declaration not allowed in this context",
);
}
this.next();
return this.parseFunction(node, true, false, true); return this.parseFunction(node, true, false, true);
} else { } else {
this.state = state; this.state = state;
@ -210,7 +221,7 @@ export default class StatementParser extends ExpressionParser {
expr.type === "Identifier" && expr.type === "Identifier" &&
this.eat(tt.colon) this.eat(tt.colon)
) { ) {
return this.parseLabeledStatement(node, maybeName, expr); return this.parseLabeledStatement(node, maybeName, expr, declaration);
} else { } else {
return this.parseExpressionStatement(node, expr); return this.parseExpressionStatement(node, expr);
} }
@ -649,6 +660,7 @@ export default class StatementParser extends ExpressionParser {
node: N.LabeledStatement, node: N.LabeledStatement,
maybeName: string, maybeName: string,
expr: N.Identifier, expr: N.Identifier,
declaration: boolean,
): N.LabeledStatement { ): N.LabeledStatement {
for (const label of this.state.labels) { for (const label of this.state.labels) {
if (label.name === maybeName) { if (label.name === maybeName) {
@ -676,7 +688,7 @@ export default class StatementParser extends ExpressionParser {
kind: kind, kind: kind,
statementStart: this.state.start, statementStart: this.state.start,
}); });
node.body = this.parseStatement(true); node.body = this.parseStatement(declaration);
if ( if (
node.body.type == "ClassDeclaration" || node.body.type == "ClassDeclaration" ||

View File

@ -0,0 +1,3 @@
{
"throws": "Function declaration not allowed in this context (1:10)"
}

View File

@ -0,0 +1 @@
while (1) foo: bar: function foo(){}

View File

@ -0,0 +1,3 @@
{
"throws": "Function declaration not allowed in this context (1:20)"
}

View File

@ -1,3 +0,0 @@
{
"throws": "Unexpected token (1:10)"
}

View File

@ -0,0 +1 @@
while (1) async function foo(){}

View File

@ -0,0 +1,3 @@
{
"throws": "Function declaration not allowed in this context (1:10)"
}

View File

@ -1616,17 +1616,8 @@ language/statements/class/syntax/early-errors/class-definition-evaluation-block-
language/statements/class/syntax/early-errors/class-definition-evaluation-scriptbody-duplicate-binding.js(default) language/statements/class/syntax/early-errors/class-definition-evaluation-scriptbody-duplicate-binding.js(default)
language/statements/class/syntax/early-errors/class-definition-evaluation-scriptbody-duplicate-binding.js(strict mode) language/statements/class/syntax/early-errors/class-definition-evaluation-scriptbody-duplicate-binding.js(strict mode)
language/statements/const/redeclaration-error-from-within-strict-mode-function-const.js(default) language/statements/const/redeclaration-error-from-within-strict-mode-function-const.js(default)
language/statements/do-while/decl-async-fun.js(default)
language/statements/do-while/decl-async-fun.js(strict mode)
language/statements/do-while/decl-async-gen.js(default)
language/statements/do-while/decl-async-gen.js(strict mode)
language/statements/do-while/labelled-fn-stmt.js(default)
language/statements/for-await-of/let-block-with-newline.js(default) language/statements/for-await-of/let-block-with-newline.js(default)
language/statements/for-await-of/let-identifier-with-newline.js(default) language/statements/for-await-of/let-identifier-with-newline.js(default)
language/statements/for-in/decl-async-fun.js(default)
language/statements/for-in/decl-async-fun.js(strict mode)
language/statements/for-in/decl-async-gen.js(default)
language/statements/for-in/decl-async-gen.js(strict mode)
language/statements/for-in/dstr/array-rest-before-elision.js(default) language/statements/for-in/dstr/array-rest-before-elision.js(default)
language/statements/for-in/dstr/array-rest-before-elision.js(strict mode) language/statements/for-in/dstr/array-rest-before-elision.js(strict mode)
language/statements/for-in/dstr/array-rest-elision-invalid.js(default) language/statements/for-in/dstr/array-rest-elision-invalid.js(default)
@ -1642,16 +1633,8 @@ language/statements/for-in/head-let-bound-names-in-stmt.js(strict mode)
language/statements/for-in/head-lhs-let.js(default) language/statements/for-in/head-lhs-let.js(default)
language/statements/for-in/head-var-bound-names-let.js(default) language/statements/for-in/head-var-bound-names-let.js(default)
language/statements/for-in/identifier-let-allowed-as-lefthandside-expression-not-strict.js(default) language/statements/for-in/identifier-let-allowed-as-lefthandside-expression-not-strict.js(default)
language/statements/for-in/labelled-fn-stmt-const.js(default)
language/statements/for-in/labelled-fn-stmt-let.js(default)
language/statements/for-in/labelled-fn-stmt-lhs.js(default)
language/statements/for-in/labelled-fn-stmt-var.js(default)
language/statements/for-in/let-block-with-newline.js(default) language/statements/for-in/let-block-with-newline.js(default)
language/statements/for-in/let-identifier-with-newline.js(default) language/statements/for-in/let-identifier-with-newline.js(default)
language/statements/for-of/decl-async-fun.js(default)
language/statements/for-of/decl-async-fun.js(strict mode)
language/statements/for-of/decl-async-gen.js(default)
language/statements/for-of/decl-async-gen.js(strict mode)
language/statements/for-of/dstr/array-rest-before-elision.js(default) language/statements/for-of/dstr/array-rest-before-elision.js(default)
language/statements/for-of/dstr/array-rest-before-elision.js(strict mode) language/statements/for-of/dstr/array-rest-before-elision.js(strict mode)
language/statements/for-of/dstr/array-rest-elision-invalid.js(default) language/statements/for-of/dstr/array-rest-elision-invalid.js(default)
@ -1672,45 +1655,15 @@ language/statements/for-of/head-let-bound-names-in-stmt.js(strict mode)
language/statements/for-of/head-var-bound-names-let.js(default) language/statements/for-of/head-var-bound-names-let.js(default)
language/statements/for-of/head-var-no-expr.js(default) language/statements/for-of/head-var-no-expr.js(default)
language/statements/for-of/head-var-no-expr.js(strict mode) language/statements/for-of/head-var-no-expr.js(strict mode)
language/statements/for-of/labelled-fn-stmt-const.js(default)
language/statements/for-of/labelled-fn-stmt-let.js(default)
language/statements/for-of/labelled-fn-stmt-lhs.js(default)
language/statements/for-of/labelled-fn-stmt-var.js(default)
language/statements/for-of/let-block-with-newline.js(default) language/statements/for-of/let-block-with-newline.js(default)
language/statements/for-of/let-identifier-with-newline.js(default) language/statements/for-of/let-identifier-with-newline.js(default)
language/statements/for/decl-async-fun.js(default)
language/statements/for/decl-async-fun.js(strict mode)
language/statements/for/decl-async-gen.js(default)
language/statements/for/decl-async-gen.js(strict mode)
language/statements/for/head-let-bound-names-in-stmt.js(default) language/statements/for/head-let-bound-names-in-stmt.js(default)
language/statements/for/head-let-bound-names-in-stmt.js(strict mode) language/statements/for/head-let-bound-names-in-stmt.js(strict mode)
language/statements/for/head-lhs-let.js(default) language/statements/for/head-lhs-let.js(default)
language/statements/for/labelled-fn-stmt-expr.js(default)
language/statements/for/labelled-fn-stmt-let.js(default)
language/statements/for/labelled-fn-stmt-var.js(default)
language/statements/for/let-block-with-newline.js(default) language/statements/for/let-block-with-newline.js(default)
language/statements/for/let-identifier-with-newline.js(default) language/statements/for/let-identifier-with-newline.js(default)
language/statements/function/dflt-params-duplicates.js(default) language/statements/function/dflt-params-duplicates.js(default)
language/statements/generators/dflt-params-duplicates.js(default) language/statements/generators/dflt-params-duplicates.js(default)
language/statements/if/if-async-fun-else-async-fun.js(default)
language/statements/if/if-async-fun-else-async-fun.js(strict mode)
language/statements/if/if-async-fun-else-stmt.js(default)
language/statements/if/if-async-fun-else-stmt.js(strict mode)
language/statements/if/if-async-fun-no-else.js(default)
language/statements/if/if-async-fun-no-else.js(strict mode)
language/statements/if/if-async-gen-else-async-gen.js(default)
language/statements/if/if-async-gen-else-async-gen.js(strict mode)
language/statements/if/if-async-gen-else-stmt.js(default)
language/statements/if/if-async-gen-else-stmt.js(strict mode)
language/statements/if/if-async-gen-no-else.js(default)
language/statements/if/if-async-gen-no-else.js(strict mode)
language/statements/if/if-stmt-else-async-fun.js(default)
language/statements/if/if-stmt-else-async-fun.js(strict mode)
language/statements/if/if-stmt-else-async-gen.js(default)
language/statements/if/if-stmt-else-async-gen.js(strict mode)
language/statements/if/labelled-fn-stmt-first.js(default)
language/statements/if/labelled-fn-stmt-lone.js(default)
language/statements/if/labelled-fn-stmt-second.js(default)
language/statements/if/let-block-with-newline.js(default) language/statements/if/let-block-with-newline.js(default)
language/statements/if/let-identifier-with-newline.js(default) language/statements/if/let-identifier-with-newline.js(default)
language/statements/labeled/let-block-with-newline.js(default) language/statements/labeled/let-block-with-newline.js(default)
@ -1850,15 +1803,7 @@ language/statements/try/early-catch-lex.js(default)
language/statements/try/early-catch-lex.js(strict mode) language/statements/try/early-catch-lex.js(strict mode)
language/statements/try/early-catch-var.js(default) language/statements/try/early-catch-var.js(default)
language/statements/try/early-catch-var.js(strict mode) language/statements/try/early-catch-var.js(strict mode)
language/statements/while/decl-async-fun.js(default)
language/statements/while/decl-async-fun.js(strict mode)
language/statements/while/decl-async-gen.js(default)
language/statements/while/decl-async-gen.js(strict mode)
language/statements/while/labelled-fn-stmt.js(default)
language/statements/while/let-block-with-newline.js(default) language/statements/while/let-block-with-newline.js(default)
language/statements/while/let-identifier-with-newline.js(default) language/statements/while/let-identifier-with-newline.js(default)
language/statements/with/decl-async-fun.js(default)
language/statements/with/decl-async-gen.js(default)
language/statements/with/labelled-fn-stmt.js(default)
language/statements/with/let-block-with-newline.js(default) language/statements/with/let-block-with-newline.js(default)
language/statements/with/let-identifier-with-newline.js(default) language/statements/with/let-identifier-with-newline.js(default)