Skip to content

Commit 9e365f7

Browse files
committed
Further refine handling of await in class fields
FIX: Properly allow await inside an async arrow function inside a class field initializer. Issue #1338
1 parent b6a98df commit 9e365f7

File tree

4 files changed

+15
-9
lines changed

4 files changed

+15
-9
lines changed

acorn/src/expression.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1043,7 +1043,7 @@ pp.checkUnreserved = function({start, end, name}) {
10431043
this.raiseRecoverable(start, "Cannot use 'yield' as identifier inside a generator")
10441044
if (this.inAsync && name === "await")
10451045
this.raiseRecoverable(start, "Cannot use 'await' as identifier inside an async function")
1046-
if (this.currentThisScope().inClassFieldInit && name === "arguments")
1046+
if (this.currentScope().inClassFieldInit && name === "arguments")
10471047
this.raiseRecoverable(start, "Cannot use 'arguments' in class field initializer")
10481048
if (this.inClassStaticBlock && (name === "arguments" || name === "await"))
10491049
this.raise(start, `Cannot use ${name} in class static initialization block`)

acorn/src/state.js

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -99,15 +99,14 @@ export class Parser {
9999

100100
get inFunction() { return (this.currentVarScope().flags & SCOPE_FUNCTION) > 0 }
101101

102-
get inGenerator() { return (this.currentVarScope().flags & SCOPE_GENERATOR) > 0 && !this.currentVarScope().inClassFieldInit }
102+
get inGenerator() { return (this.currentVarScope().flags & SCOPE_GENERATOR) > 0 && !this.currentScope().inClassFieldInit }
103103

104-
get inAsync() { return (this.currentVarScope().flags & SCOPE_ASYNC) > 0 && !this.currentVarScope().inClassFieldInit }
104+
get inAsync() { return (this.currentScope().flags & SCOPE_ASYNC) > 0 && !this.currentScope().inClassFieldInit }
105105

106106
get canAwait() {
107-
if (this.currentThisScope().inClassFieldInit) return false
108107
for (let i = this.scopeStack.length - 1; i >= 0; i--) {
109108
let scope = this.scopeStack[i]
110-
if (scope.flags & SCOPE_CLASS_STATIC_BLOCK) return false
109+
if (scope.flags & SCOPE_CLASS_STATIC_BLOCK || scope.inClassFieldInit) return false
111110
if (scope.flags & SCOPE_FUNCTION) return (scope.flags & SCOPE_ASYNC) > 0
112111
}
113112
return (this.inModule && this.options.ecmaVersion >= 13) || this.options.allowAwaitOutsideFunction
@@ -123,8 +122,8 @@ export class Parser {
123122
get treatFunctionsAsVar() { return this.treatFunctionsAsVarInScope(this.currentScope()) }
124123

125124
get allowNewDotTarget() {
126-
const {flags, inClassFieldInit} = this.currentThisScope()
127-
return (flags & (SCOPE_FUNCTION | SCOPE_CLASS_STATIC_BLOCK)) > 0 || inClassFieldInit
125+
const {flags} = this.currentThisScope()
126+
return (flags & (SCOPE_FUNCTION | SCOPE_CLASS_STATIC_BLOCK)) > 0 || this.currentScope().inClassFieldInit
128127
}
129128

130129
get inClassStaticBlock() {

acorn/src/statement.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -742,7 +742,7 @@ pp.parseClassField = function(field) {
742742

743743
if (this.eat(tt.eq)) {
744744
// To raise SyntaxError if 'arguments' exists in the initializer.
745-
const scope = this.currentThisScope()
745+
const scope = this.currentScope()
746746
const inClassFieldInit = scope.inClassFieldInit
747747
scope.inClassFieldInit = true
748748
field.value = this.parseMaybeAssign()

test/tests-asyncawait.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3541,4 +3541,11 @@ testFail("4 + async() => 2", "Unexpected token (1:12)", {ecmaVersion: 8, loose:
35413541

35423542
testFail("async function𝐬 f() {}", "Unexpected token (1:17)", {ecmaVersion: 8})
35433543

3544-
testFail("async () => class { x = await 1 }", "Cannot use 'await' as identifier inside an async function (1:24)", {ecmaVersion: 2024})
3544+
testFail("async () => class { x = await 1 }", "Unexpected token (1:30)", {ecmaVersion: 2024})
3545+
3546+
test("async () => class { x = async () => await 1 }", {}, {ecmaVersion: 2024})
3547+
3548+
test("async () => class { x = await }", {}, {ecmaVersion: 2024})
3549+
3550+
testFail("async () => class { x = await }", "Cannot use keyword 'await' outside an async function (1:24)",
3551+
{ecmaVersion: 2024, sourceType: "module"})

0 commit comments

Comments
 (0)