From 0c66c4780ab69d94a9b9b62f146c8b827e5018a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hu=C3=A1ng=20J=C3=B9nli=C3=A0ng?= Date: Mon, 30 Dec 2019 21:09:26 -0500 Subject: [PATCH] fix: add SCOPE_ASYNC to program scope when topLevelAwait is enable --- packages/babel-parser/src/parser/expression.js | 11 +++++++++-- packages/babel-parser/src/parser/index.js | 8 ++++++-- .../top-level-await/inside-class-property/input.js | 3 +++ .../inside-class-property/options.json | 8 ++++++++ .../module-namespace/top-level-await/input.ts | 3 +++ .../module-namespace/top-level-await/options.json | 8 ++++++++ 6 files changed, 37 insertions(+), 4 deletions(-) create mode 100644 packages/babel-parser/test/fixtures/experimental/top-level-await/inside-class-property/input.js create mode 100644 packages/babel-parser/test/fixtures/experimental/top-level-await/inside-class-property/options.json create mode 100644 packages/babel-parser/test/fixtures/typescript/module-namespace/top-level-await/input.ts create mode 100644 packages/babel-parser/test/fixtures/typescript/module-namespace/top-level-await/options.json diff --git a/packages/babel-parser/src/parser/expression.js b/packages/babel-parser/src/parser/expression.js index 1ef6fcf82f96..b4f1d89c06c5 100644 --- a/packages/babel-parser/src/parser/expression.js +++ b/packages/babel-parser/src/parser/expression.js @@ -39,6 +39,7 @@ import { SCOPE_DIRECT_SUPER, SCOPE_SUPER, SCOPE_PROGRAM, + SCOPE_ASYNC, } from "../util/scopeflags"; export default class ExpressionParser extends LValParser { @@ -96,7 +97,11 @@ export default class ExpressionParser extends LValParser { // Convenience method to parse an Expression only getExpression(): N.Expression { - this.scope.enter(SCOPE_PROGRAM); + let scopeFlags = SCOPE_PROGRAM; + if (this.hasPlugin("topLevelAwait") && this.inModule) { + scopeFlags |= SCOPE_ASYNC; + } + this.scope.enter(scopeFlags); this.nextToken(); const expr = this.parseExpression(); if (!this.match(tt.eof)) { @@ -2186,7 +2191,9 @@ export default class ExpressionParser extends LValParser { isAwaitAllowed(): boolean { if (this.scope.inFunction) return this.scope.inAsync; if (this.options.allowAwaitOutsideFunction) return true; - if (this.hasPlugin("topLevelAwait")) return this.inModule; + if (this.hasPlugin("topLevelAwait")) { + return this.inModule && this.scope.inAsync; + } return false; } diff --git a/packages/babel-parser/src/parser/index.js b/packages/babel-parser/src/parser/index.js index 2c96336f1c13..681de32d0560 100644 --- a/packages/babel-parser/src/parser/index.js +++ b/packages/babel-parser/src/parser/index.js @@ -5,7 +5,7 @@ import type { File, JSXOpeningElement } from "../types"; import type { PluginList } from "../plugin-utils"; import { getOptions } from "../options"; import StatementParser from "./statement"; -import { SCOPE_PROGRAM } from "../util/scopeflags"; +import { SCOPE_ASYNC, SCOPE_PROGRAM } from "../util/scopeflags"; import ScopeHandler from "../util/scope"; export type PluginsMap = Map; @@ -35,7 +35,11 @@ export default class Parser extends StatementParser { } parse(): File { - this.scope.enter(SCOPE_PROGRAM); + let scopeFlags = SCOPE_PROGRAM; + if (this.hasPlugin("topLevelAwait") && this.inModule) { + scopeFlags |= SCOPE_ASYNC; + } + this.scope.enter(scopeFlags); const file = this.startNode(); const program = this.startNode(); this.nextToken(); diff --git a/packages/babel-parser/test/fixtures/experimental/top-level-await/inside-class-property/input.js b/packages/babel-parser/test/fixtures/experimental/top-level-await/inside-class-property/input.js new file mode 100644 index 000000000000..d17e57ee1081 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/top-level-await/inside-class-property/input.js @@ -0,0 +1,3 @@ +export class C { + p = await 0; +} diff --git a/packages/babel-parser/test/fixtures/experimental/top-level-await/inside-class-property/options.json b/packages/babel-parser/test/fixtures/experimental/top-level-await/inside-class-property/options.json new file mode 100644 index 000000000000..0688c012b357 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/top-level-await/inside-class-property/options.json @@ -0,0 +1,8 @@ +{ + "plugins": [ + "topLevelAwait", + "classProperties" + ], + "sourceType": "module", + "throws": "Unexpected token, expected \";\" (2:12)" +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/typescript/module-namespace/top-level-await/input.ts b/packages/babel-parser/test/fixtures/typescript/module-namespace/top-level-await/input.ts new file mode 100644 index 000000000000..9302309c5933 --- /dev/null +++ b/packages/babel-parser/test/fixtures/typescript/module-namespace/top-level-await/input.ts @@ -0,0 +1,3 @@ +namespace N { + const x = await 42; +} diff --git a/packages/babel-parser/test/fixtures/typescript/module-namespace/top-level-await/options.json b/packages/babel-parser/test/fixtures/typescript/module-namespace/top-level-await/options.json new file mode 100644 index 000000000000..ba579946562a --- /dev/null +++ b/packages/babel-parser/test/fixtures/typescript/module-namespace/top-level-await/options.json @@ -0,0 +1,8 @@ +{ + "sourceType": "module", + "plugins": [ + "typescript", + "topLevelAwait" + ], + "throws": "Unexpected token, expected \";\" (2:20)" +} \ No newline at end of file