diff --git a/packages/babel-parser/src/parser/expression.js b/packages/babel-parser/src/parser/expression.js index 5e9adfaddb18..c92bfd217e79 100644 --- a/packages/babel-parser/src/parser/expression.js +++ b/packages/babel-parser/src/parser/expression.js @@ -42,6 +42,7 @@ import { } from "../util/scopeflags"; import { PARAM_AWAIT, + PARAM_RETURN, PARAM, functionFlags, } from "../util/production-parameter"; @@ -1967,7 +1968,11 @@ export default class ExpressionParser extends LValParser { allowExpression, !oldStrict && useStrict, ); + // FunctionBody[Yield, Await]: + // StatementList[?Yield, ?Await, +Return] opt + this.prodParam.enter(this.prodParam.currentFlags() | PARAM_RETURN); node.body = this.parseBlock(true, false); + this.prodParam.exit(); this.state.labels = oldLabels; } diff --git a/packages/babel-parser/src/parser/statement.js b/packages/babel-parser/src/parser/statement.js index adc23de4cace..4708c583251a 100644 --- a/packages/babel-parser/src/parser/statement.js +++ b/packages/babel-parser/src/parser/statement.js @@ -569,7 +569,7 @@ export default class StatementParser extends ExpressionParser { } parseReturnStatement(node: N.ReturnStatement): N.ReturnStatement { - if (!this.scope.inFunction && !this.options.allowReturnOutsideFunction) { + if (!this.prodParam.hasReturn && !this.options.allowReturnOutsideFunction) { this.raise(this.state.start, "'return' outside of function"); } diff --git a/packages/babel-parser/src/util/production-parameter.js b/packages/babel-parser/src/util/production-parameter.js index 9f468addc3d6..6460e8d35fda 100644 --- a/packages/babel-parser/src/util/production-parameter.js +++ b/packages/babel-parser/src/util/production-parameter.js @@ -1,7 +1,8 @@ // @flow -export const PARAM = 0b00, // Initial Parameter flags - PARAM_YIELD = 0b01, // track [Await] production parameter - PARAM_AWAIT = 0b10; // track [Yield] production parameter +export const PARAM = 0b000, // Initial Parameter flags + PARAM_YIELD = 0b001, // track [Yield] production parameter + PARAM_AWAIT = 0b010, // track [Await] production parameter + PARAM_RETURN = 0b100; // track [Return] production parameter // ProductionParameterHandler is a stack fashioned production parameter tracker // https://tc39.es/ecma262/#sec-grammar-notation @@ -48,6 +49,10 @@ export default class ProductionParameterHandler { get hasYield(): boolean { return (this.currentFlags() & PARAM_YIELD) > 0; } + + get hasReturn(): boolean { + return (this.currentFlags() & PARAM_RETURN) > 0; + } } export function functionFlags(