Skip to content

Commit 157c52a

Browse files
authored
fix(es/parser): Parser a program as a module with TLA in non-expression statement (#10287)
fixes: #10109 1. Lift `top_level` flag to parser context 2. Add checks before parsing `await` in unary expr.
1 parent 7028457 commit 157c52a

File tree

10 files changed

+99
-53
lines changed

10 files changed

+99
-53
lines changed

.changeset/honest-sloths-flash.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
swc_ecma_parser: major
3+
---
4+
5+
fix(parser): parse program as module with TLA in non-expression statement

crates/swc_ecma_parser/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,8 @@ pub struct Context {
432432
disallow_conditional_types: bool,
433433

434434
allow_using_decl: bool,
435+
436+
top_level: bool,
435437
}
436438

437439
#[derive(Debug, Clone, Copy, Default)]

crates/swc_ecma_parser/src/parser/class_and_fn.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1417,6 +1417,7 @@ impl<I: Tokens> Parser<I> {
14171417
in_static_block: false,
14181418
is_break_allowed: false,
14191419
is_continue_allowed: false,
1420+
top_level: false,
14201421
..self.ctx()
14211422
};
14221423
let state = State {

crates/swc_ecma_parser/src/parser/expr/ops.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,14 @@ impl<I: Tokens> Parser<I> {
397397
return Ok(Ident::new_no_ctxt("await".into(), span).into());
398398
}
399399

400+
// This has been checked if start_of_await_token == true,
401+
if start_of_await_token.is_none() && ctx.top_level {
402+
self.state.found_module_item = true;
403+
if !ctx.can_be_module {
404+
self.emit_err(await_token, SyntaxError::TopLevelAwaitInScript);
405+
}
406+
}
407+
400408
if ctx.in_function && !ctx.in_async {
401409
self.emit_err(await_token, SyntaxError::AwaitInFunction);
402410
}

crates/swc_ecma_parser/src/parser/expr/tests.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ fn member_expr(s: &'static str) -> Box<Expr> {
2727

2828
fn expr(s: &'static str) -> Box<Expr> {
2929
test_parser(s, syntax(), |p| {
30-
p.parse_stmt(true).map(|stmt| match stmt {
30+
p.parse_stmt().map(|stmt| match stmt {
3131
Stmt::Expr(expr) => expr.expr,
3232
_ => unreachable!(),
3333
})
@@ -368,7 +368,7 @@ fn issue_319_1() {
368368
fn issue_328() {
369369
assert_eq_ignore_span!(
370370
test_parser("import('test')", Syntax::Es(Default::default()), |p| {
371-
p.parse_stmt(true)
371+
p.parse_stmt()
372372
}),
373373
Stmt::Expr(ExprStmt {
374374
span,

crates/swc_ecma_parser/src/parser/mod.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ impl<I: Tokens> Parser<I> {
7777
let in_declare = false;
7878
let ctx = Context {
7979
in_declare,
80+
top_level: true,
8081
..input.ctx()
8182
};
8283
input.set_ctx(ctx);
@@ -100,6 +101,7 @@ impl<I: Tokens> Parser<I> {
100101

101102
let ctx = Context {
102103
module: false,
104+
top_level: true,
103105
..self.ctx()
104106
};
105107
self.set_ctx(ctx);
@@ -108,7 +110,7 @@ impl<I: Tokens> Parser<I> {
108110

109111
let shebang = self.parse_shebang()?;
110112

111-
self.parse_block_body(true, true, None).map(|body| Script {
113+
self.parse_block_body(true, None).map(|body| Script {
112114
span: span!(self, start),
113115
body,
114116
shebang,
@@ -124,6 +126,7 @@ impl<I: Tokens> Parser<I> {
124126
let ctx = Context {
125127
module: true,
126128
strict: false,
129+
top_level: true,
127130
..self.ctx()
128131
};
129132
// Module code is always in strict mode
@@ -132,7 +135,7 @@ impl<I: Tokens> Parser<I> {
132135
let start = cur_pos!(self);
133136
let shebang = self.parse_shebang()?;
134137

135-
self.parse_block_body(true, true, None).map(|body| Module {
138+
self.parse_block_body(true, None).map(|body| Module {
136139
span: span!(self, start),
137140
body,
138141
shebang,
@@ -149,10 +152,11 @@ impl<I: Tokens> Parser<I> {
149152
let shebang = self.parse_shebang()?;
150153
let ctx = Context {
151154
can_be_module: true,
155+
top_level: true,
152156
..self.ctx()
153157
};
154158

155-
let body: Vec<ModuleItem> = self.with_ctx(ctx).parse_block_body(true, true, None)?;
159+
let body: Vec<ModuleItem> = self.with_ctx(ctx).parse_block_body(true, None)?;
156160
let has_module_item = self.state.found_module_item
157161
|| body
158162
.iter()
@@ -162,6 +166,7 @@ impl<I: Tokens> Parser<I> {
162166
module: true,
163167
can_be_module: true,
164168
strict: true,
169+
top_level: true,
165170
..self.ctx()
166171
};
167172
// Emit buffered strict mode / module code violations
@@ -195,6 +200,7 @@ impl<I: Tokens> Parser<I> {
195200
module: true,
196201
can_be_module: true,
197202
strict: true,
203+
top_level: true,
198204
..self.ctx()
199205
};
200206
// Module code is always in strict mode
@@ -203,7 +209,7 @@ impl<I: Tokens> Parser<I> {
203209
let start = cur_pos!(self);
204210
let shebang = self.parse_shebang()?;
205211

206-
self.parse_block_body(true, true, None).map(|body| Module {
212+
self.parse_block_body(true, None).map(|body| Module {
207213
span: span!(self, start),
208214
body,
209215
shebang,

0 commit comments

Comments
 (0)