Fix: TopLevelAwait should respect await identifiers defined in… (#10947)

This commit is contained in:
Huáng Jùnliàng 2020-01-03 17:07:11 -05:00 committed by Nicolò Ribaudo
parent e5048053aa
commit 6ee8c97e6a
6 changed files with 37 additions and 4 deletions

View File

@ -39,6 +39,7 @@ import {
SCOPE_DIRECT_SUPER, SCOPE_DIRECT_SUPER,
SCOPE_SUPER, SCOPE_SUPER,
SCOPE_PROGRAM, SCOPE_PROGRAM,
SCOPE_ASYNC,
} from "../util/scopeflags"; } from "../util/scopeflags";
export default class ExpressionParser extends LValParser { export default class ExpressionParser extends LValParser {
@ -96,7 +97,11 @@ export default class ExpressionParser extends LValParser {
// Convenience method to parse an Expression only // Convenience method to parse an Expression only
getExpression(): N.Expression { 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(); this.nextToken();
const expr = this.parseExpression(); const expr = this.parseExpression();
if (!this.match(tt.eof)) { if (!this.match(tt.eof)) {
@ -2186,7 +2191,9 @@ export default class ExpressionParser extends LValParser {
isAwaitAllowed(): boolean { isAwaitAllowed(): boolean {
if (this.scope.inFunction) return this.scope.inAsync; if (this.scope.inFunction) return this.scope.inAsync;
if (this.options.allowAwaitOutsideFunction) return true; 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; return false;
} }

View File

@ -5,7 +5,7 @@ import type { File, JSXOpeningElement } from "../types";
import type { PluginList } from "../plugin-utils"; import type { PluginList } from "../plugin-utils";
import { getOptions } from "../options"; import { getOptions } from "../options";
import StatementParser from "./statement"; import StatementParser from "./statement";
import { SCOPE_PROGRAM } from "../util/scopeflags"; import { SCOPE_ASYNC, SCOPE_PROGRAM } from "../util/scopeflags";
import ScopeHandler from "../util/scope"; import ScopeHandler from "../util/scope";
export type PluginsMap = Map<string, { [string]: any }>; export type PluginsMap = Map<string, { [string]: any }>;
@ -35,7 +35,11 @@ export default class Parser extends StatementParser {
} }
parse(): File { 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 file = this.startNode();
const program = this.startNode(); const program = this.startNode();
this.nextToken(); this.nextToken();

View File

@ -0,0 +1,3 @@
export class C {
p = await 0;
}

View File

@ -0,0 +1,8 @@
{
"plugins": [
"topLevelAwait",
"classProperties"
],
"sourceType": "module",
"throws": "Unexpected token, expected \";\" (2:12)"
}

View File

@ -0,0 +1,3 @@
namespace N {
const x = await 42;
}

View File

@ -0,0 +1,8 @@
{
"sourceType": "module",
"plugins": [
"typescript",
"topLevelAwait"
],
"throws": "Unexpected token, expected \";\" (2:20)"
}