swc_ecma_parser/parser/
stmt.rs

1use swc_common::Spanned;
2
3use super::*;
4use crate::parser::{pat::PatType, Parser};
5
6#[allow(clippy::enum_variant_names)]
7enum TempForHead {
8    For {
9        init: Option<VarDeclOrExpr>,
10        test: Option<Box<Expr>>,
11        update: Option<Box<Expr>>,
12    },
13    ForIn {
14        left: ForHead,
15        right: Box<Expr>,
16    },
17    ForOf {
18        left: ForHead,
19        right: Box<Expr>,
20    },
21}
22
23impl<I: Tokens> Parser<I> {
24    fn parse_normal_for_head(&mut self, init: Option<VarDeclOrExpr>) -> PResult<TempForHead> {
25        let test = if self.input_mut().eat(Token::Semi) {
26            None
27        } else {
28            let test = self.allow_in_expr(|p| p.parse_expr()).map(Some)?;
29            self.input_mut().eat(Token::Semi);
30            test
31        };
32
33        let update = if self.input().is(Token::RParen) {
34            None
35        } else {
36            self.allow_in_expr(|p| p.parse_expr()).map(Some)?
37        };
38
39        Ok(TempForHead::For { init, test, update })
40    }
41
42    fn parse_for_each_head(&mut self, left: ForHead) -> PResult<TempForHead> {
43        let is_of = self.input().cur() == Token::Of;
44        self.bump();
45        if is_of {
46            let right = self.allow_in_expr(Self::parse_assignment_expr)?;
47            Ok(TempForHead::ForOf { left, right })
48        } else {
49            if let ForHead::UsingDecl(d) = &left {
50                self.emit_err(d.span, SyntaxError::UsingDeclNotAllowedForForInLoop)
51            }
52            let right = self.allow_in_expr(|p| p.parse_expr())?;
53            Ok(TempForHead::ForIn { left, right })
54        }
55    }
56
57    fn parse_return_stmt(&mut self) -> PResult<Stmt> {
58        let start = self.cur_pos();
59
60        self.assert_and_bump(Token::Return);
61
62        let arg = if self.is_general_semi() {
63            None
64        } else {
65            self.allow_in_expr(|p| p.parse_expr()).map(Some)?
66        };
67        self.expect_general_semi()?;
68        let stmt = Ok(ReturnStmt {
69            span: self.span(start),
70            arg,
71        }
72        .into());
73
74        if !self.ctx().contains(Context::InFunction)
75            && !self.input().syntax().allow_return_outside_function()
76        {
77            self.emit_err(self.span(start), SyntaxError::ReturnNotAllowed);
78        }
79
80        stmt
81    }
82
83    fn parse_var_declarator(
84        &mut self,
85        for_loop: bool,
86        kind: VarDeclKind,
87    ) -> PResult<VarDeclarator> {
88        let start = self.cur_pos();
89
90        let is_let_or_const = matches!(kind, VarDeclKind::Let | VarDeclKind::Const);
91
92        let mut name = self.parse_binding_pat_or_ident(is_let_or_const)?;
93
94        let definite = if self.input().syntax().typescript() {
95            match name {
96                Pat::Ident(..) => self.input_mut().eat(Token::Bang),
97                _ => false,
98            }
99        } else {
100            false
101        };
102
103        // Typescript extension
104        if self.input().syntax().typescript() && self.input().is(Token::Colon) {
105            let type_annotation = self.try_parse_ts_type_ann()?;
106            match name {
107                Pat::Array(ArrayPat {
108                    ref mut type_ann, ..
109                })
110                | Pat::Ident(BindingIdent {
111                    ref mut type_ann, ..
112                })
113                | Pat::Object(ObjectPat {
114                    ref mut type_ann, ..
115                })
116                | Pat::Rest(RestPat {
117                    ref mut type_ann, ..
118                }) => {
119                    *type_ann = type_annotation;
120                }
121                _ => unreachable!("invalid syntax: Pat: {:?}", name),
122            }
123        }
124
125        //FIXME: This is wrong. Should check in/of only on first looself.
126        let cur = self.input().cur();
127        let init = if !for_loop || !(cur == Token::In || cur == Token::Of) {
128            if self.input_mut().eat(Token::Eq) {
129                let expr = self.parse_assignment_expr()?;
130                let expr = self.verify_expr(expr)?;
131
132                Some(expr)
133            } else {
134                // Destructuring bindings require initializers, but
135                // typescript allows `declare` vars not to have initializers.
136                if self.ctx().contains(Context::InDeclare) {
137                    None
138                } else if kind == VarDeclKind::Const
139                    && !for_loop
140                    && !self.ctx().contains(Context::InDeclare)
141                {
142                    self.emit_err(
143                        self.span(start),
144                        SyntaxError::ConstDeclarationsRequireInitialization,
145                    );
146
147                    None
148                } else {
149                    match name {
150                        Pat::Ident(..) => None,
151                        _ => {
152                            syntax_error!(self, self.span(start), SyntaxError::PatVarWithoutInit)
153                        }
154                    }
155                }
156            }
157        } else {
158            // e.g. for(let a;;)
159            None
160        };
161
162        Ok(VarDeclarator {
163            span: self.span(start),
164            name,
165            init,
166            definite,
167        })
168    }
169
170    pub(crate) fn parse_var_stmt(&mut self, for_loop: bool) -> PResult<Box<VarDecl>> {
171        let start = self.cur_pos();
172        let t = self.input().cur();
173        let kind = if t == Token::Const {
174            VarDeclKind::Const
175        } else if t == Token::Let {
176            VarDeclKind::Let
177        } else if t == Token::Var {
178            VarDeclKind::Var
179        } else {
180            unreachable!()
181        };
182        self.bump();
183        let var_span = self.span(start);
184        let should_include_in = kind != VarDeclKind::Var || !for_loop;
185
186        if self.syntax().typescript() && for_loop {
187            let cur = self.input().cur();
188            let res: PResult<bool> = if cur == Token::In || cur == Token::Of {
189                self.ts_look_ahead(|p| {
190                    //
191                    if !p.input_mut().eat(Token::Of) && !p.input_mut().eat(Token::In) {
192                        return Ok(false);
193                    }
194
195                    p.parse_assignment_expr()?;
196                    expect!(p, Token::RParen);
197
198                    Ok(true)
199                })
200            } else {
201                Ok(false)
202            };
203
204            match res {
205                Ok(true) => {
206                    let pos = var_span.hi();
207                    let span = Span::new_with_checked(pos, pos);
208                    self.emit_err(span, SyntaxError::TS1123);
209
210                    return Ok(Box::new(VarDecl {
211                        span: self.span(start),
212                        kind,
213                        declare: false,
214                        decls: Vec::new(),
215                        ..Default::default()
216                    }));
217                }
218                Err(..) => {}
219                _ => {}
220            }
221        }
222
223        let mut decls = Vec::with_capacity(4);
224        loop {
225            // Handle
226            //      var a,;
227            //
228            // NewLine is ok
229            if self.input().is(Token::Semi) {
230                let prev_span = self.input().prev_span();
231                let span = if prev_span == var_span {
232                    Span::new_with_checked(prev_span.hi, prev_span.hi)
233                } else {
234                    prev_span
235                };
236                self.emit_err(span, SyntaxError::TS1009);
237                break;
238            }
239
240            let decl = if should_include_in {
241                self.do_inside_of_context(Context::IncludeInExpr, |p| {
242                    p.parse_var_declarator(for_loop, kind)
243                })
244            } else {
245                self.parse_var_declarator(for_loop, kind)
246            }?;
247
248            decls.push(decl);
249
250            if !self.input_mut().eat(Token::Comma) {
251                break;
252            }
253        }
254
255        if !for_loop && !self.eat_general_semi() {
256            self.emit_err(self.input().cur_span(), SyntaxError::TS1005);
257
258            let _ = self.parse_expr();
259
260            while !self.eat_general_semi() {
261                self.bump();
262
263                if self.input().cur() == Token::Error {
264                    break;
265                }
266            }
267        }
268
269        Ok(Box::new(VarDecl {
270            span: self.span(start),
271            declare: false,
272            kind,
273            decls,
274            ..Default::default()
275        }))
276    }
277
278    fn parse_using_decl(
279        &mut self,
280        start: BytePos,
281        is_await: bool,
282    ) -> PResult<Option<Box<UsingDecl>>> {
283        // using
284        // reader = init()
285
286        // is two statements
287        if self.input_mut().has_linebreak_between_cur_and_peeked() {
288            return Ok(None);
289        }
290
291        if !self.peek_is_ident_ref() {
292            return Ok(None);
293        }
294
295        self.assert_and_bump(Token::Using);
296
297        let mut decls = Vec::new();
298        loop {
299            // Handle
300            //      var a,;
301            //
302            // NewLine is ok
303            if self.input().is(Token::Semi) {
304                let span = self.input().prev_span();
305                self.emit_err(span, SyntaxError::TS1009);
306                break;
307            }
308
309            decls.push(self.parse_var_declarator(false, VarDeclKind::Var)?);
310            if !self.input_mut().eat(Token::Comma) {
311                break;
312            }
313        }
314
315        if !self.syntax().explicit_resource_management() {
316            self.emit_err(self.span(start), SyntaxError::UsingDeclNotEnabled);
317        }
318
319        if !self.ctx().contains(Context::AllowUsingDecl) {
320            self.emit_err(self.span(start), SyntaxError::UsingDeclNotAllowed);
321        }
322
323        for decl in &decls {
324            match decl.name {
325                Pat::Ident(..) => {}
326                _ => {
327                    self.emit_err(self.span(start), SyntaxError::InvalidNameInUsingDecl);
328                }
329            }
330
331            if decl.init.is_none() {
332                self.emit_err(self.span(start), SyntaxError::InitRequiredForUsingDecl);
333            }
334        }
335
336        self.expect_general_semi()?;
337
338        Ok(Some(Box::new(UsingDecl {
339            span: self.span(start),
340            is_await,
341            decls,
342        })))
343    }
344
345    fn parse_for_head(&mut self) -> PResult<TempForHead> {
346        // let strict = self.ctx().contains(Context::Strict);
347
348        let cur = self.input().cur();
349        if cur == Token::Const
350            || cur == Token::Var
351            || (self.input().is(Token::Let)
352                && peek!(self).map_or(false, |v| v.follows_keyword_let()))
353        {
354            let decl = self.parse_var_stmt(true)?;
355
356            let cur = self.input().cur();
357            if cur == Token::Of || cur == Token::In {
358                if decl.decls.len() != 1 {
359                    for d in decl.decls.iter().skip(1) {
360                        self.emit_err(d.name.span(), SyntaxError::TooManyVarInForInHead);
361                    }
362                } else {
363                    if (self.ctx().contains(Context::Strict) || self.input().is(Token::Of))
364                        && decl.decls[0].init.is_some()
365                    {
366                        self.emit_err(
367                            decl.decls[0].name.span(),
368                            SyntaxError::VarInitializerInForInHead,
369                        );
370                    }
371
372                    if self.syntax().typescript() {
373                        let type_ann = match decl.decls[0].name {
374                            Pat::Ident(ref v) => Some(&v.type_ann),
375                            Pat::Array(ref v) => Some(&v.type_ann),
376                            Pat::Rest(ref v) => Some(&v.type_ann),
377                            Pat::Object(ref v) => Some(&v.type_ann),
378                            _ => None,
379                        };
380
381                        if let Some(type_ann) = type_ann {
382                            if type_ann.is_some() {
383                                self.emit_err(decl.decls[0].name.span(), SyntaxError::TS2483);
384                            }
385                        }
386                    }
387                }
388
389                return self.parse_for_each_head(ForHead::VarDecl(decl));
390            }
391
392            expect!(self, Token::Semi);
393            return self.parse_normal_for_head(Some(VarDeclOrExpr::VarDecl(decl)));
394        }
395
396        if self.input_mut().eat(Token::Semi) {
397            return self.parse_normal_for_head(None);
398        }
399
400        let start = self.cur_pos();
401        let init = self.disallow_in_expr(Self::parse_for_head_prefix)?;
402
403        let mut is_using_decl = false;
404        let mut is_await_using_decl = false;
405
406        if self.input().syntax().explicit_resource_management() {
407            // using foo
408            let mut maybe_using_decl = init.is_ident_ref_to("using");
409            let mut maybe_await_using_decl = false;
410
411            // await using foo
412            if !maybe_using_decl
413                && init
414                    .as_await_expr()
415                    .filter(|e| e.arg.is_ident_ref_to("using"))
416                    .is_some()
417            {
418                maybe_using_decl = true;
419                maybe_await_using_decl = true;
420            }
421
422            if maybe_using_decl
423                && !self.input().is(Token::Of)
424                && (peek!(self).is_some_and(|peek| peek == Token::Of || peek == Token::In))
425            {
426                is_using_decl = maybe_using_decl;
427                is_await_using_decl = maybe_await_using_decl;
428            }
429        }
430
431        if is_using_decl {
432            let name = self.parse_binding_ident(false)?;
433            let decl = VarDeclarator {
434                name: name.into(),
435                span: self.span(start),
436                init: None,
437                definite: false,
438            };
439
440            let pat = Box::new(UsingDecl {
441                span: self.span(start),
442                is_await: is_await_using_decl,
443                decls: vec![decl],
444            });
445
446            let cur = self.input().cur();
447            if cur == Token::Error {
448                let err = self.input_mut().expect_error_token_and_bump();
449                return Err(err);
450            } else if cur == Token::Eof {
451                return Err(self.eof_error());
452            }
453
454            return self.parse_for_each_head(ForHead::UsingDecl(pat));
455        }
456
457        // for (a of b)
458        let cur = self.input().cur();
459        if cur == Token::Of || cur == Token::In {
460            let is_in = self.input().is(Token::In);
461
462            let pat = self.reparse_expr_as_pat(PatType::AssignPat, init)?;
463
464            // for ({} in foo) is invalid
465            if self.input().syntax().typescript() && is_in {
466                match pat {
467                    Pat::Ident(..) => {}
468                    Pat::Expr(..) => {}
469                    ref v => self.emit_err(v.span(), SyntaxError::TS2491),
470                }
471            }
472
473            return self.parse_for_each_head(ForHead::Pat(Box::new(pat)));
474        }
475
476        expect!(self, Token::Semi);
477
478        let init = self.verify_expr(init)?;
479        self.parse_normal_for_head(Some(VarDeclOrExpr::Expr(init)))
480    }
481
482    fn parse_for_stmt(&mut self) -> PResult<Stmt> {
483        let start = self.cur_pos();
484
485        self.assert_and_bump(Token::For);
486        let await_start = self.cur_pos();
487        let await_token = if self.input_mut().eat(Token::Await) {
488            Some(self.span(await_start))
489        } else {
490            None
491        };
492        expect!(self, Token::LParen);
493
494        let head = self.do_inside_of_context(Context::ForLoopInit, |p| {
495            if await_token.is_some() {
496                p.do_inside_of_context(Context::ForAwaitLoopInit, Self::parse_for_head)
497            } else {
498                p.do_outside_of_context(Context::ForAwaitLoopInit, Self::parse_for_head)
499            }
500        })?;
501
502        expect!(self, Token::RParen);
503
504        let body = self
505            .do_inside_of_context(
506                Context::IsBreakAllowed.union(Context::IsContinueAllowed),
507                |p| p.do_outside_of_context(Context::TopLevel, Self::parse_stmt),
508            )
509            .map(Box::new)?;
510
511        let span = self.span(start);
512        Ok(match head {
513            TempForHead::For { init, test, update } => {
514                if let Some(await_token) = await_token {
515                    syntax_error!(self, await_token, SyntaxError::AwaitForStmt);
516                }
517
518                ForStmt {
519                    span,
520                    init,
521                    test,
522                    update,
523                    body,
524                }
525                .into()
526            }
527            TempForHead::ForIn { left, right } => {
528                if let Some(await_token) = await_token {
529                    syntax_error!(self, await_token, SyntaxError::AwaitForStmt);
530                }
531
532                ForInStmt {
533                    span,
534                    left,
535                    right,
536                    body,
537                }
538                .into()
539            }
540            TempForHead::ForOf { left, right } => ForOfStmt {
541                span,
542                is_await: await_token.is_some(),
543                left,
544                right,
545                body,
546            }
547            .into(),
548        })
549    }
550
551    pub fn parse_stmt(&mut self) -> PResult<Stmt> {
552        trace_cur!(self, parse_stmt);
553        self.parse_stmt_like(false, handle_import_export)
554    }
555
556    /// Utility function used to parse large if else statements iteratively.
557    ///
558    /// THis function is recursive, but it is very cheap so stack overflow will
559    /// not occur.
560    fn adjust_if_else_clause(&mut self, cur: &mut IfStmt, alt: Box<Stmt>) {
561        cur.span = self.span(cur.span.lo);
562
563        if let Some(Stmt::If(prev_alt)) = cur.alt.as_deref_mut() {
564            self.adjust_if_else_clause(prev_alt, alt)
565        } else {
566            debug_assert_eq!(cur.alt, None);
567            cur.alt = Some(alt);
568        }
569    }
570
571    fn parse_if_stmt(&mut self) -> PResult<IfStmt> {
572        let start = self.cur_pos();
573
574        self.assert_and_bump(Token::If);
575        let if_token = self.input().prev_span();
576
577        expect!(self, Token::LParen);
578
579        let test = self
580            .do_outside_of_context(Context::IgnoreElseClause, |p| {
581                p.allow_in_expr(|p| p.parse_expr())
582            })
583            .map_err(|err| {
584                Error::new(
585                    err.span(),
586                    SyntaxError::WithLabel {
587                        inner: Box::new(err),
588                        span: if_token,
589                        note: "Tried to parse the condition for an if statement",
590                    },
591                )
592            })?;
593
594        expect!(self, Token::RParen);
595
596        let cons = {
597            // Prevent stack overflow
598            crate::maybe_grow(256 * 1024, 1024 * 1024, || {
599                // // Annex B
600                // if !self.ctx().contains(Context::Strict) && self.input().is(Token::FUNCTION)
601                // {     // TODO: report error?
602                // }
603                self.do_outside_of_context(
604                    Context::IgnoreElseClause.union(Context::TopLevel),
605                    Self::parse_stmt,
606                )
607                .map(Box::new)
608            })?
609        };
610
611        // We parse `else` branch iteratively, to avoid stack overflow
612        // See https://github.com/swc-project/swc/pull/3961
613
614        let alt = if self.ctx().contains(Context::IgnoreElseClause) {
615            None
616        } else {
617            let mut cur = None;
618
619            let last = loop {
620                if !self.input_mut().eat(Token::Else) {
621                    break None;
622                }
623
624                if !self.input().is(Token::If) {
625                    // As we eat `else` above, we need to parse statement once.
626                    let last = self.do_outside_of_context(
627                        Context::IgnoreElseClause.union(Context::TopLevel),
628                        Self::parse_stmt,
629                    )?;
630                    break Some(last);
631                }
632
633                // We encountered `else if`
634
635                let alt =
636                    self.do_inside_of_context(Context::IgnoreElseClause, Self::parse_if_stmt)?;
637
638                match &mut cur {
639                    Some(cur) => {
640                        self.adjust_if_else_clause(cur, Box::new(alt.into()));
641                    }
642                    _ => {
643                        cur = Some(alt);
644                    }
645                }
646            };
647
648            match cur {
649                Some(mut cur) => {
650                    if let Some(last) = last {
651                        self.adjust_if_else_clause(&mut cur, Box::new(last));
652                    }
653                    Some(cur.into())
654                }
655                _ => last,
656            }
657        }
658        .map(Box::new);
659
660        let span = self.span(start);
661        Ok(IfStmt {
662            span,
663            test,
664            cons,
665            alt,
666        })
667    }
668
669    fn parse_throw_stmt(&mut self) -> PResult<Stmt> {
670        let start = self.cur_pos();
671
672        self.assert_and_bump(Token::Throw);
673
674        if self.input().had_line_break_before_cur() {
675            // TODO: Suggest throw arg;
676            syntax_error!(self, SyntaxError::LineBreakInThrow);
677        }
678
679        let arg = self.allow_in_expr(|p| p.parse_expr())?;
680        self.expect_general_semi()?;
681
682        let span = self.span(start);
683        Ok(ThrowStmt { span, arg }.into())
684    }
685
686    fn parse_with_stmt(&mut self) -> PResult<Stmt> {
687        if self.syntax().typescript() {
688            let span = self.input().cur_span();
689            self.emit_err(span, SyntaxError::TS2410);
690        }
691
692        {
693            let span = self.input().cur_span();
694            self.emit_strict_mode_err(span, SyntaxError::WithInStrict);
695        }
696
697        let start = self.cur_pos();
698
699        self.assert_and_bump(Token::With);
700
701        expect!(self, Token::LParen);
702        let obj = self.allow_in_expr(|p| p.parse_expr())?;
703        expect!(self, Token::RParen);
704
705        let body = self
706            .do_inside_of_context(Context::InFunction, |p| {
707                p.do_outside_of_context(Context::TopLevel, Self::parse_stmt)
708            })
709            .map(Box::new)?;
710
711        let span = self.span(start);
712        Ok(WithStmt { span, obj, body }.into())
713    }
714
715    fn parse_while_stmt(&mut self) -> PResult<Stmt> {
716        let start = self.cur_pos();
717
718        self.assert_and_bump(Token::While);
719
720        expect!(self, Token::LParen);
721        let test = self.allow_in_expr(|p| p.parse_expr())?;
722        expect!(self, Token::RParen);
723
724        let body = self
725            .do_inside_of_context(
726                Context::IsBreakAllowed.union(Context::IsContinueAllowed),
727                |p| p.do_outside_of_context(Context::TopLevel, Self::parse_stmt),
728            )
729            .map(Box::new)?;
730
731        let span = self.span(start);
732        Ok(WhileStmt { span, test, body }.into())
733    }
734
735    /// It's optional since es2019
736    fn parse_catch_param(&mut self) -> PResult<Option<Pat>> {
737        if self.input_mut().eat(Token::LParen) {
738            let mut pat = self.parse_binding_pat_or_ident(false)?;
739
740            let type_ann_start = self.cur_pos();
741
742            if self.syntax().typescript() && self.input_mut().eat(Token::Colon) {
743                let ty = self.do_inside_of_context(Context::InType, Self::parse_ts_type)?;
744                // self.emit_err(ty.span(), SyntaxError::TS1196);
745
746                match &mut pat {
747                    Pat::Ident(BindingIdent { type_ann, .. })
748                    | Pat::Array(ArrayPat { type_ann, .. })
749                    | Pat::Rest(RestPat { type_ann, .. })
750                    | Pat::Object(ObjectPat { type_ann, .. }) => {
751                        *type_ann = Some(Box::new(TsTypeAnn {
752                            span: self.span(type_ann_start),
753                            type_ann: ty,
754                        }));
755                    }
756                    Pat::Assign(..) => {}
757                    Pat::Invalid(_) => {}
758                    Pat::Expr(_) => {}
759                    #[cfg(swc_ast_unknown)]
760                    _ => unreachable!(),
761                }
762            }
763            expect!(self, Token::RParen);
764            Ok(Some(pat))
765        } else {
766            Ok(None)
767        }
768    }
769
770    fn parse_do_stmt(&mut self) -> PResult<Stmt> {
771        let start = self.cur_pos();
772
773        self.assert_and_bump(Token::Do);
774
775        let body = self
776            .do_inside_of_context(
777                Context::IsBreakAllowed.union(Context::IsContinueAllowed),
778                |p| p.do_outside_of_context(Context::TopLevel, Self::parse_stmt),
779            )
780            .map(Box::new)?;
781
782        expect!(self, Token::While);
783        expect!(self, Token::LParen);
784
785        let test = self.allow_in_expr(|p| p.parse_expr())?;
786
787        expect!(self, Token::RParen);
788
789        // We *may* eat semicolon.
790        let _ = self.eat_general_semi();
791
792        let span = self.span(start);
793
794        Ok(DoWhileStmt { span, test, body }.into())
795    }
796
797    fn parse_labelled_stmt(&mut self, l: Ident) -> PResult<Stmt> {
798        self.do_inside_of_context(Context::IsBreakAllowed, |p| {
799            p.do_outside_of_context(Context::AllowUsingDecl, |p| {
800                let start = l.span.lo();
801
802                let mut errors = Vec::new();
803                for lb in &p.state().labels {
804                    if l.sym == *lb {
805                        errors.push(Error::new(
806                            l.span,
807                            SyntaxError::DuplicateLabel(l.sym.clone()),
808                        ));
809                    }
810                }
811                p.state_mut().labels.push(l.sym.clone());
812
813                let body = Box::new(if p.input().is(Token::Function) {
814                    let f = p.parse_fn_decl(Vec::new())?;
815                    if let Decl::Fn(FnDecl { function, .. }) = &f {
816                        if p.ctx().contains(Context::Strict) {
817                            p.emit_err(function.span, SyntaxError::LabelledFunctionInStrict)
818                        }
819                        if function.is_generator || function.is_async {
820                            p.emit_err(function.span, SyntaxError::LabelledGeneratorOrAsync)
821                        }
822                    }
823
824                    f.into()
825                } else {
826                    p.do_outside_of_context(Context::TopLevel, Self::parse_stmt)?
827                });
828
829                for err in errors {
830                    p.emit_error(err);
831                }
832
833                {
834                    let pos = p.state().labels.iter().position(|v| v == &l.sym);
835                    if let Some(pos) = pos {
836                        p.state_mut().labels.remove(pos);
837                    }
838                }
839
840                Ok(LabeledStmt {
841                    span: p.span(start),
842                    label: l,
843                    body,
844                }
845                .into())
846            })
847        })
848    }
849
850    pub(crate) fn parse_block(&mut self, allow_directives: bool) -> PResult<BlockStmt> {
851        let start = self.cur_pos();
852
853        expect!(self, Token::LBrace);
854
855        let stmts = self.do_outside_of_context(Context::TopLevel, |p| {
856            p.parse_stmt_block_body(allow_directives, Some(Token::RBrace))
857        })?;
858
859        let span = self.span(start);
860        Ok(BlockStmt {
861            span,
862            stmts,
863            ctxt: Default::default(),
864        })
865    }
866
867    fn parse_finally_block(&mut self) -> PResult<Option<BlockStmt>> {
868        Ok(if self.input_mut().eat(Token::Finally) {
869            self.parse_block(false).map(Some)?
870        } else {
871            None
872        })
873    }
874
875    fn parse_catch_clause(&mut self) -> PResult<Option<CatchClause>> {
876        let start = self.cur_pos();
877        Ok(if self.input_mut().eat(Token::Catch) {
878            let param = self.parse_catch_param()?;
879            self.parse_block(false)
880                .map(|body| CatchClause {
881                    span: self.span(start),
882                    param,
883                    body,
884                })
885                .map(Some)?
886        } else {
887            None
888        })
889    }
890
891    fn parse_try_stmt(&mut self) -> PResult<Stmt> {
892        let start = self.cur_pos();
893        self.assert_and_bump(Token::Try);
894
895        let block = self.parse_block(false)?;
896
897        let catch_start = self.cur_pos();
898        let handler = self.parse_catch_clause()?;
899        let finalizer = self.parse_finally_block()?;
900
901        if handler.is_none() && finalizer.is_none() {
902            self.emit_err(
903                Span::new_with_checked(catch_start, catch_start),
904                SyntaxError::TS1005,
905            );
906        }
907
908        let span = self.span(start);
909        Ok(TryStmt {
910            span,
911            block,
912            handler,
913            finalizer,
914        }
915        .into())
916    }
917
918    fn parse_switch_stmt(&mut self) -> PResult<Stmt> {
919        let switch_start = self.cur_pos();
920
921        self.assert_and_bump(Token::Switch);
922
923        expect!(self, Token::LParen);
924        let discriminant = self.allow_in_expr(|p| p.parse_expr())?;
925        expect!(self, Token::RParen);
926
927        let mut cases = Vec::new();
928        let mut span_of_previous_default = None;
929
930        expect!(self, Token::LBrace);
931
932        self.do_inside_of_context(Context::IsBreakAllowed, |p| {
933            while {
934                let cur = p.input().cur();
935                cur == Token::Case || cur == Token::Default
936            } {
937                let mut cons = Vec::new();
938                let is_case = p.input().is(Token::Case);
939                let case_start = p.cur_pos();
940                p.bump();
941                let test = if is_case {
942                    p.allow_in_expr(|p| p.parse_expr()).map(Some)?
943                } else {
944                    if let Some(previous) = span_of_previous_default {
945                        syntax_error!(p, SyntaxError::MultipleDefault { previous });
946                    }
947                    span_of_previous_default = Some(p.span(case_start));
948
949                    None
950                };
951                expect!(p, Token::Colon);
952
953                while {
954                    let cur = p.input().cur();
955                    !(cur == Token::Case || cur == Token::Default || cur == Token::RBrace)
956                } {
957                    cons.push(
958                        p.do_outside_of_context(Context::TopLevel, Self::parse_stmt_list_item)?,
959                    );
960                }
961
962                cases.push(SwitchCase {
963                    span: Span::new_with_checked(case_start, p.input().prev_span().hi),
964                    test,
965                    cons,
966                });
967            }
968
969            Ok(())
970        })?;
971
972        // eof or rbrace
973        expect!(self, Token::RBrace);
974
975        Ok(SwitchStmt {
976            span: self.span(switch_start),
977            discriminant,
978            cases,
979        }
980        .into())
981    }
982
983    /// Parse a statement and maybe a declaration.
984    pub fn parse_stmt_list_item(&mut self) -> PResult<Stmt> {
985        trace_cur!(self, parse_stmt_list_item);
986        self.parse_stmt_like(true, handle_import_export)
987    }
988
989    /// Parse a statement, declaration or module item.
990    #[inline(always)]
991    pub(crate) fn parse_stmt_like<Type: From<Stmt>>(
992        &mut self,
993        include_decl: bool,
994        handle_import_export: impl Fn(&mut Self, Vec<Decorator>) -> PResult<Type>,
995    ) -> PResult<Type> {
996        trace_cur!(self, parse_stmt_like);
997
998        debug_tracing!(self, "parse_stmt_like");
999
1000        let start = self.cur_pos();
1001        let decorators = if self.input().get_cur().token == Token::At {
1002            self.parse_decorators(true)?
1003        } else {
1004            vec![]
1005        };
1006
1007        let cur = self.input().cur();
1008        if cur == Token::Import || cur == Token::Export {
1009            return handle_import_export(self, decorators);
1010        }
1011
1012        self.do_outside_of_context(Context::WillExpectColonForCond, |p| {
1013            p.do_inside_of_context(Context::AllowUsingDecl, |p| {
1014                p.parse_stmt_internal(start, include_decl, decorators)
1015            })
1016        })
1017        .map(From::from)
1018    }
1019
1020    /// `parseStatementContent`
1021    fn parse_stmt_internal(
1022        &mut self,
1023        start: BytePos,
1024        include_decl: bool,
1025        decorators: Vec<Decorator>,
1026    ) -> PResult<Stmt> {
1027        trace_cur!(self, parse_stmt_internal);
1028
1029        let is_typescript = self.input().syntax().typescript();
1030
1031        if is_typescript
1032            && self.input().is(Token::Const)
1033            && peek!(self).is_some_and(|peek| peek == Token::Enum)
1034        {
1035            self.assert_and_bump(Token::Const);
1036            self.assert_and_bump(Token::Enum);
1037            return self
1038                .parse_ts_enum_decl(start, true)
1039                .map(Decl::from)
1040                .map(Stmt::from);
1041        }
1042
1043        let top_level = self.ctx().contains(Context::TopLevel);
1044
1045        let cur = self.input().cur();
1046
1047        if cur == Token::Await && (include_decl || top_level) {
1048            if top_level {
1049                self.mark_found_module_item();
1050                if !self.ctx().contains(Context::CanBeModule) {
1051                    self.emit_err(self.input().cur_span(), SyntaxError::TopLevelAwaitInScript);
1052                }
1053            }
1054
1055            if peek!(self).is_some_and(|peek| peek == Token::Using) {
1056                let eaten_await = Some(self.input().cur_pos());
1057                self.assert_and_bump(Token::Await);
1058                let v = self.parse_using_decl(start, true)?;
1059                if let Some(v) = v {
1060                    return Ok(v.into());
1061                }
1062
1063                let expr = self.parse_await_expr(eaten_await)?;
1064                let expr = self.allow_in_expr(|p| p.parse_bin_op_recursively(expr, 0))?;
1065                self.eat_general_semi();
1066
1067                let span = self.span(start);
1068                return Ok(ExprStmt { span, expr }.into());
1069            }
1070        } else if cur == Token::Break || cur == Token::Continue {
1071            let is_break = self.input().is(Token::Break);
1072            self.bump();
1073            let label = if self.eat_general_semi() {
1074                None
1075            } else {
1076                let i = self.parse_label_ident().map(Some)?;
1077                self.expect_general_semi()?;
1078                i
1079            };
1080            let span = self.span(start);
1081            if is_break {
1082                if label.is_some() && !self.state().labels.contains(&label.as_ref().unwrap().sym) {
1083                    self.emit_err(span, SyntaxError::TS1116);
1084                } else if !self.ctx().contains(Context::IsBreakAllowed) {
1085                    self.emit_err(span, SyntaxError::TS1105);
1086                }
1087            } else if !self.ctx().contains(Context::IsContinueAllowed) {
1088                self.emit_err(span, SyntaxError::TS1115);
1089            } else if label.is_some() && !self.state().labels.contains(&label.as_ref().unwrap().sym)
1090            {
1091                self.emit_err(span, SyntaxError::TS1107);
1092            }
1093            return Ok(if is_break {
1094                BreakStmt { span, label }.into()
1095            } else {
1096                ContinueStmt { span, label }.into()
1097            });
1098        } else if cur == Token::Debugger {
1099            self.bump();
1100            self.expect_general_semi()?;
1101            return Ok(DebuggerStmt {
1102                span: self.span(start),
1103            }
1104            .into());
1105        } else if cur == Token::Do {
1106            return self.parse_do_stmt();
1107        } else if cur == Token::For {
1108            return self.parse_for_stmt();
1109        } else if cur == Token::Function {
1110            if !include_decl {
1111                self.emit_err(self.input().cur_span(), SyntaxError::DeclNotAllowed);
1112            }
1113            return self.parse_fn_decl(decorators).map(Stmt::from);
1114        } else if cur == Token::Class {
1115            if !include_decl {
1116                self.emit_err(self.input().cur_span(), SyntaxError::DeclNotAllowed);
1117            }
1118            return self
1119                .parse_class_decl(start, start, decorators, false)
1120                .map(Stmt::from);
1121        } else if cur == Token::If {
1122            return self.parse_if_stmt().map(Stmt::If);
1123        } else if cur == Token::Return {
1124            return self.parse_return_stmt();
1125        } else if cur == Token::Switch {
1126            return self.parse_switch_stmt();
1127        } else if cur == Token::Throw {
1128            return self.parse_throw_stmt();
1129        } else if cur == Token::Catch {
1130            // Error recovery
1131            let span = self.input().cur_span();
1132            self.emit_err(span, SyntaxError::TS1005);
1133
1134            let _ = self.parse_catch_clause();
1135            let _ = self.parse_finally_block();
1136
1137            return Ok(ExprStmt {
1138                span,
1139                expr: Invalid { span }.into(),
1140            }
1141            .into());
1142        } else if cur == Token::Finally {
1143            // Error recovery
1144            let span = self.input().cur_span();
1145            self.emit_err(span, SyntaxError::TS1005);
1146
1147            let _ = self.parse_finally_block();
1148
1149            return Ok(ExprStmt {
1150                span,
1151                expr: Invalid { span }.into(),
1152            }
1153            .into());
1154        } else if cur == Token::Try {
1155            return self.parse_try_stmt();
1156        } else if cur == Token::With {
1157            return self.parse_with_stmt();
1158        } else if cur == Token::While {
1159            return self.parse_while_stmt();
1160        } else if cur == Token::Var || (cur == Token::Const && include_decl) {
1161            let v = self.parse_var_stmt(false)?;
1162            return Ok(v.into());
1163        } else if cur == Token::Let && include_decl {
1164            // 'let' can start an identifier reference.
1165            let is_keyword = match peek!(self) {
1166                Some(t) => t.follows_keyword_let(),
1167                _ => false,
1168            };
1169
1170            if is_keyword {
1171                let v = self.parse_var_stmt(false)?;
1172                return Ok(v.into());
1173            }
1174        } else if cur == Token::Using && include_decl {
1175            let v = self.parse_using_decl(start, false)?;
1176            if let Some(v) = v {
1177                return Ok(v.into());
1178            }
1179        } else if cur == Token::Interface
1180            && is_typescript
1181            && peek!(self).is_some_and(|peek| peek.is_word())
1182            && !self.input_mut().has_linebreak_between_cur_and_peeked()
1183        {
1184            let start = self.input().cur_pos();
1185            self.bump();
1186            return Ok(self.parse_ts_interface_decl(start)?.into());
1187        } else if cur == Token::Type
1188            && is_typescript
1189            && peek!(self).is_some_and(|peek| peek.is_word())
1190            && !self.input_mut().has_linebreak_between_cur_and_peeked()
1191        {
1192            let start = self.input().cur_pos();
1193            self.bump();
1194            return Ok(self.parse_ts_type_alias_decl(start)?.into());
1195        } else if cur == Token::Enum
1196            && is_typescript
1197            && peek!(self).is_some_and(|peek| peek.is_word())
1198            && !self.input_mut().has_linebreak_between_cur_and_peeked()
1199        {
1200            let start = self.input().cur_pos();
1201            self.bump();
1202            return Ok(self.parse_ts_enum_decl(start, false)?.into());
1203        } else if cur == Token::LBrace {
1204            return self
1205                .do_inside_of_context(Context::AllowUsingDecl, |p| p.parse_block(false))
1206                .map(Stmt::Block);
1207        } else if cur == Token::Semi {
1208            self.bump();
1209            return Ok(EmptyStmt {
1210                span: self.span(start),
1211            }
1212            .into());
1213        }
1214
1215        // Handle async function foo() {}
1216        if self.input().is(Token::Async)
1217            && peek!(self).is_some_and(|peek| peek == Token::Function)
1218            && !self.input_mut().has_linebreak_between_cur_and_peeked()
1219        {
1220            return self.parse_async_fn_decl(decorators).map(From::from);
1221        }
1222
1223        // If the statement does not start with a statement keyword or a
1224        // brace, it's an ExpressionStatement or LabeledStatement. We
1225        // simply start parsing an expression, and afterwards, if the
1226        // next token is a colon and the expression was a simple
1227        // Identifier node, we switch to interpreting it as a label.
1228        let expr = self.allow_in_expr(|p| p.parse_expr())?;
1229
1230        let expr = match *expr {
1231            Expr::Ident(ident) => {
1232                if self.input_mut().eat(Token::Colon) {
1233                    return self.parse_labelled_stmt(ident);
1234                }
1235                ident.into()
1236            }
1237            _ => self.verify_expr(expr)?,
1238        };
1239        if let Expr::Ident(ref ident) = *expr {
1240            if &*ident.sym == "interface" && self.input().had_line_break_before_cur() {
1241                self.emit_strict_mode_err(
1242                    ident.span,
1243                    SyntaxError::InvalidIdentInStrict(ident.sym.clone()),
1244                );
1245
1246                self.eat_general_semi();
1247
1248                return Ok(ExprStmt {
1249                    span: self.span(start),
1250                    expr,
1251                }
1252                .into());
1253            }
1254
1255            if self.input().syntax().typescript() {
1256                if let Some(decl) = self.parse_ts_expr_stmt(decorators, ident.clone())? {
1257                    return Ok(decl.into());
1258                }
1259            }
1260        }
1261
1262        if self.syntax().typescript() {
1263            if let Expr::Ident(ref i) = *expr {
1264                match &*i.sym {
1265                    "public" | "static" | "abstract" => {
1266                        if self.input_mut().eat(Token::Interface) {
1267                            self.emit_err(i.span, SyntaxError::TS2427);
1268                            return self
1269                                .parse_ts_interface_decl(start)
1270                                .map(Decl::from)
1271                                .map(Stmt::from);
1272                        }
1273                    }
1274                    _ => {}
1275                }
1276            }
1277        }
1278
1279        if self.eat_general_semi() {
1280            Ok(ExprStmt {
1281                span: self.span(start),
1282                expr,
1283            }
1284            .into())
1285        } else {
1286            let cur = self.input().cur();
1287            if cur.is_bin_op() {
1288                self.emit_err(self.input().cur_span(), SyntaxError::TS1005);
1289                let expr = self.parse_bin_op_recursively(expr, 0)?;
1290                return Ok(ExprStmt {
1291                    span: self.span(start),
1292                    expr,
1293                }
1294                .into());
1295            }
1296
1297            syntax_error!(
1298                self,
1299                SyntaxError::ExpectedSemiForExprStmt { expr: expr.span() }
1300            );
1301        }
1302    }
1303
1304    pub(crate) fn parse_stmt_block_body(
1305        &mut self,
1306        allow_directives: bool,
1307        end: Option<Token>,
1308    ) -> PResult<Vec<Stmt>> {
1309        self.parse_block_body(allow_directives, end, handle_import_export)
1310    }
1311
1312    pub(crate) fn parse_block_body<Type: From<Stmt>>(
1313        &mut self,
1314        allow_directives: bool,
1315        end: Option<Token>,
1316        handle_import_export: impl Fn(&mut Self, Vec<Decorator>) -> PResult<Type>,
1317    ) -> PResult<Vec<Type>> {
1318        trace_cur!(self, parse_block_body);
1319
1320        let mut stmts = Vec::with_capacity(8);
1321
1322        let has_strict_directive = allow_directives
1323            && (self
1324                .input()
1325                .cur()
1326                .is_str_raw_content("\"use strict\"", self.input())
1327                || self
1328                    .input()
1329                    .cur()
1330                    .is_str_raw_content("'use strict'", self.input()));
1331
1332        let parse_stmts = |p: &mut Self, stmts: &mut Vec<Type>| -> PResult<()> {
1333            let is_stmt_start = |p: &mut Self| {
1334                let cur = p.input().cur();
1335                match end {
1336                    Some(end) => {
1337                        if cur == Token::Eof {
1338                            let eof_text = p.input_mut().dump_cur();
1339                            p.emit_err(
1340                                p.input().cur_span(),
1341                                SyntaxError::Expected(format!("{end:?}"), eof_text),
1342                            );
1343                            false
1344                        } else {
1345                            cur != end
1346                        }
1347                    }
1348                    None => cur != Token::Eof,
1349                }
1350            };
1351            while is_stmt_start(p) {
1352                let stmt = p.parse_stmt_like(true, &handle_import_export)?;
1353                stmts.push(stmt);
1354            }
1355            Ok(())
1356        };
1357
1358        if has_strict_directive {
1359            self.do_inside_of_context(Context::Strict, |p| parse_stmts(p, &mut stmts))?;
1360        } else {
1361            parse_stmts(self, &mut stmts)?;
1362        };
1363
1364        if self.input().cur() != Token::Eof && end.is_some() {
1365            self.bump();
1366        }
1367
1368        Ok(stmts)
1369    }
1370}
1371
1372fn handle_import_export<I: Tokens>(p: &mut Parser<I>, _: Vec<Decorator>) -> PResult<Stmt> {
1373    let start = p.cur_pos();
1374    if p.input().is(Token::Import) && peek!(p).is_some_and(|peek| peek == Token::LParen) {
1375        let expr = p.parse_expr()?;
1376
1377        p.eat_general_semi();
1378
1379        return Ok(ExprStmt {
1380            span: p.span(start),
1381            expr,
1382        }
1383        .into());
1384    }
1385
1386    if p.input().is(Token::Import) && peek!(p).is_some_and(|peek| peek == Token::Dot) {
1387        let expr = p.parse_expr()?;
1388
1389        p.eat_general_semi();
1390
1391        return Ok(ExprStmt {
1392            span: p.span(start),
1393            expr,
1394        }
1395        .into());
1396    }
1397
1398    syntax_error!(p, SyntaxError::ImportExportInScript);
1399}
1400
1401#[cfg(test)]
1402mod tests {
1403    use swc_atoms::atom;
1404    use swc_common::{comments::SingleThreadedComments, DUMMY_SP as span};
1405    use swc_ecma_visit::assert_eq_ignore_span;
1406
1407    use super::*;
1408    use crate::{EsSyntax, TsSyntax};
1409
1410    fn stmt(s: &'static str) -> Stmt {
1411        test_parser(s, Syntax::default(), |p| p.parse_stmt())
1412    }
1413
1414    fn module_item(s: &'static str) -> ModuleItem {
1415        test_parser(s, Syntax::default(), |p| p.parse_module_item())
1416    }
1417    fn expr(s: &'static str) -> Box<Expr> {
1418        test_parser(s, Syntax::default(), |p| p.parse_expr())
1419    }
1420
1421    #[test]
1422    fn expr_stmt() {
1423        assert_eq_ignore_span!(
1424            stmt("a + b + c"),
1425            Stmt::Expr(ExprStmt {
1426                span,
1427                expr: expr("a + b + c")
1428            })
1429        )
1430    }
1431
1432    #[test]
1433    fn catch_rest_pat() {
1434        assert_eq_ignore_span!(
1435            stmt("try {} catch({ ...a34 }) {}"),
1436            Stmt::Try(Box::new(TryStmt {
1437                span,
1438                block: BlockStmt {
1439                    span,
1440                    ..Default::default()
1441                },
1442                handler: Some(CatchClause {
1443                    span,
1444                    param: Pat::Object(ObjectPat {
1445                        span,
1446                        optional: false,
1447                        props: vec![ObjectPatProp::Rest(RestPat {
1448                            span,
1449                            dot3_token: span,
1450                            arg: Box::new(Pat::Ident(
1451                                Ident::new_no_ctxt(atom!("a34"), span).into()
1452                            )),
1453                            type_ann: None
1454                        })],
1455                        type_ann: None,
1456                    })
1457                    .into(),
1458                    body: BlockStmt {
1459                        span,
1460                        ..Default::default()
1461                    }
1462                }),
1463                finalizer: None
1464            }))
1465        );
1466    }
1467
1468    #[test]
1469    fn throw_this() {
1470        assert_eq_ignore_span!(
1471            stmt("throw this"),
1472            Stmt::Throw(ThrowStmt {
1473                span,
1474                arg: expr("this"),
1475            })
1476        )
1477    }
1478
1479    #[test]
1480    fn await_for_of() {
1481        assert_eq_ignore_span!(
1482            stmt("for await (const a of b) ;"),
1483            Stmt::ForOf(ForOfStmt {
1484                span,
1485                is_await: true,
1486                left: ForHead::VarDecl(Box::new(VarDecl {
1487                    span,
1488                    kind: VarDeclKind::Const,
1489                    decls: vec![VarDeclarator {
1490                        span,
1491                        init: None,
1492                        name: Pat::Ident(Ident::new_no_ctxt(atom!("a"), span).into()),
1493                        definite: false,
1494                    }],
1495                    ..Default::default()
1496                })),
1497                right: Box::new(Expr::Ident(Ident::new_no_ctxt(atom!("b"), span))),
1498
1499                body: Box::new(Stmt::Empty(EmptyStmt { span })),
1500            })
1501        )
1502    }
1503
1504    #[test]
1505    fn no_empty_without_semi() {
1506        assert_eq_ignore_span!(
1507            stmt("(function foo() { return 1 })"),
1508            stmt(
1509                "(function foo () {
1510                return 1
1511            })"
1512            )
1513        );
1514
1515        assert_eq_ignore_span!(
1516            stmt("{ 1; }"),
1517            Stmt::Block(BlockStmt {
1518                span,
1519                stmts: vec![stmt("1")],
1520                ..Default::default()
1521            })
1522        );
1523    }
1524
1525    #[test]
1526    fn if_else() {
1527        assert_eq_ignore_span!(
1528            stmt("if (a) b; else c"),
1529            Stmt::If(IfStmt {
1530                span,
1531                test: expr("a"),
1532                cons: Box::new(stmt("b;")),
1533                alt: Some(Box::new(stmt("c"))),
1534            })
1535        );
1536    }
1537
1538    #[test]
1539    fn class_decorator() {
1540        assert_eq_ignore_span!(
1541            test_parser(
1542                "
1543            @decorator
1544            @dec2
1545            class Foo {}
1546            ",
1547                Syntax::Es(EsSyntax {
1548                    decorators: true,
1549                    ..Default::default()
1550                }),
1551                |p| p.parse_stmt_list_item(),
1552            ),
1553            Stmt::Decl(Decl::Class(ClassDecl {
1554                ident: Ident::new_no_ctxt(atom!("Foo"), span),
1555                class: Box::new(Class {
1556                    span,
1557                    decorators: vec![
1558                        Decorator {
1559                            span,
1560                            expr: expr("decorator")
1561                        },
1562                        Decorator {
1563                            span,
1564                            expr: expr("dec2")
1565                        }
1566                    ],
1567                    super_class: None,
1568                    body: Vec::new(),
1569                    is_abstract: false,
1570                    ..Default::default()
1571                }),
1572                declare: false,
1573            }))
1574        );
1575    }
1576
1577    #[test]
1578    fn example() {
1579        let src = r#"
1580import React from 'react'
1581import ReactDOM from 'react-dom'
1582
1583function App() {
1584  return <h1>JSX is working!</h1>
1585}
1586
1587ReactDOM.render(<App />, document.getElementById('root'))
1588
1589"#;
1590        test_parser(
1591            src,
1592            Syntax::Es(EsSyntax {
1593                jsx: true,
1594                ..Default::default()
1595            }),
1596            |p| p.parse_module(),
1597        );
1598    }
1599
1600    #[test]
1601    fn ice() {
1602        let src = r#"import React from "react"
1603
1604function App() {
1605  return <h1>works</h1>
1606}
1607
1608export default App"#;
1609        test_parser(
1610            src,
1611            Syntax::Es(EsSyntax {
1612                jsx: true,
1613                ..Default::default()
1614            }),
1615            |p| p.parse_module(),
1616        );
1617    }
1618
1619    #[test]
1620    fn export_default() {
1621        let src = "export v, { x, y as w } from 'mod';";
1622        test_parser(
1623            src,
1624            Syntax::Es(EsSyntax {
1625                export_default_from: true,
1626                ..Default::default()
1627            }),
1628            |p| p.parse_module(),
1629        );
1630    }
1631
1632    #[test]
1633    fn export_default_2() {
1634        let src = "export foo from 'bar';";
1635        test_parser(
1636            src,
1637            Syntax::Es(EsSyntax {
1638                export_default_from: true,
1639                ..Default::default()
1640            }),
1641            |p| p.parse_module(),
1642        );
1643    }
1644
1645    #[test]
1646    fn export_default_3() {
1647        let src = "export default from 'bar';";
1648        test_parser(
1649            src,
1650            Syntax::Es(EsSyntax {
1651                export_default_from: true,
1652                ..Default::default()
1653            }),
1654            |p| p.parse_module(),
1655        );
1656    }
1657
1658    #[test]
1659    fn export_default_4() {
1660        let src = "export default, {foo} from 'bar';";
1661        test_parser(
1662            src,
1663            Syntax::Es(EsSyntax {
1664                export_default_from: true,
1665                ..Default::default()
1666            }),
1667            |p| p.parse_module(),
1668        );
1669    }
1670
1671    #[test]
1672    fn shebang_01() {
1673        let src = "#!/usr/bin/env node";
1674        test_parser(src, Syntax::Es(Default::default()), |p| p.parse_module());
1675    }
1676
1677    #[test]
1678    fn shebang_02() {
1679        let src = "#!/usr/bin/env node
1680let x = 4";
1681        test_parser(src, Syntax::Es(Default::default()), |p| p.parse_module());
1682    }
1683
1684    #[test]
1685    fn empty() {
1686        test_parser("", Syntax::Es(Default::default()), |p| p.parse_module());
1687    }
1688
1689    #[test]
1690    fn issue_226() {
1691        test_parser(
1692            "export * as Foo from 'bar';",
1693            Syntax::Es(EsSyntax {
1694                export_default_from: true,
1695                ..Default::default()
1696            }),
1697            |p| p.parse_module(),
1698        );
1699    }
1700
1701    #[test]
1702    #[should_panic(expected = "Expected 'from', got ','")]
1703    fn issue_4369_1() {
1704        test_parser(
1705            r#"export * as foo, { bar } from "mod""#,
1706            Syntax::Es(EsSyntax {
1707                export_default_from: false,
1708                ..Default::default()
1709            }),
1710            |p| p.parse_module(),
1711        );
1712    }
1713
1714    #[test]
1715    fn issue_4369_2() {
1716        test_parser(
1717            r#"export foo, * as bar, { baz } from "mod""#,
1718            Syntax::Es(EsSyntax {
1719                export_default_from: true,
1720                ..Default::default()
1721            }),
1722            |p| p.parse_module(),
1723        );
1724    }
1725
1726    #[test]
1727    fn issue_4369_3() {
1728        test_parser(
1729            r#"export foo, * as bar from "mod""#,
1730            Syntax::Es(EsSyntax {
1731                export_default_from: true,
1732                ..Default::default()
1733            }),
1734            |p| p.parse_module(),
1735        );
1736    }
1737
1738    #[test]
1739    fn issue_4369_4() {
1740        test_parser(
1741            r#"export * as bar, { baz } from "mod""#,
1742            Syntax::Es(EsSyntax {
1743                export_default_from: true,
1744                ..Default::default()
1745            }),
1746            |p| p.parse_module(),
1747        );
1748    }
1749
1750    #[test]
1751    fn issue_4369_5() {
1752        test_parser(
1753            r#"export foo, { baz } from "mod""#,
1754            Syntax::Es(EsSyntax {
1755                export_default_from: true,
1756                ..Default::default()
1757            }),
1758            |p| p.parse_module(),
1759        );
1760    }
1761
1762    #[test]
1763    fn issue_257_var() {
1764        test_parser(
1765            "
1766export default function waitUntil(callback, options = {}) {
1767  var timeout = 'timeout' in options ? options.timeout : 1000;
1768}",
1769            Default::default(),
1770            |p| p.parse_module(),
1771        );
1772    }
1773
1774    #[test]
1775    fn issue_257_let() {
1776        test_parser(
1777            "
1778export default function waitUntil(callback, options = {}) {
1779  let timeout = 'timeout' in options ? options.timeout : 1000;
1780}",
1781            Default::default(),
1782            |p| p.parse_module(),
1783        );
1784    }
1785
1786    #[test]
1787    fn issue_269() {
1788        test_parser(
1789            ";(function() {})(window, window.lib || (window.lib = {}))",
1790            Default::default(),
1791            |p| p.parse_module(),
1792        );
1793    }
1794
1795    #[test]
1796    fn issue_319_2() {
1797        module_item(
1798            "export default obj({
1799    async f() {
1800        await g();
1801    }
1802});",
1803        );
1804    }
1805
1806    #[test]
1807    fn issue_340_fn() {
1808        test_parser("export default function(){};", Default::default(), |p| {
1809            p.parse_module()
1810        });
1811    }
1812
1813    #[test]
1814    fn issue_340_async_fn() {
1815        test_parser(
1816            "export default async function(){};",
1817            Default::default(),
1818            |p| p.parse_module(),
1819        );
1820    }
1821
1822    #[test]
1823    fn issue_340_generator_fn() {
1824        test_parser("export default function*(){};", Default::default(), |p| {
1825            p.parse_module()
1826        });
1827    }
1828
1829    #[test]
1830    fn issue_340_class() {
1831        test_parser("export default class {};", Default::default(), |p| {
1832            p.parse_module()
1833        });
1834    }
1835
1836    #[test]
1837    fn issue_360() {
1838        test_parser(
1839            "var IS_IE11 = !global.ActiveXObject && 'ActiveXObject' in global;",
1840            Default::default(),
1841            |p| p.parse_module(),
1842        );
1843    }
1844
1845    #[test]
1846    fn issue_380_1() {
1847        test_parser(
1848            "import(filePath).then(bar => {})",
1849            Syntax::Es(Default::default()),
1850            |p| p.parse_module(),
1851        );
1852    }
1853
1854    #[test]
1855    fn issue_380_2() {
1856        test_parser(
1857            "class Foo {
1858                componentDidMount() {
1859                    const filePath = '../foo/bar'
1860                    import(filePath).then(bar => {})
1861                }
1862            }",
1863            Syntax::Es(Default::default()),
1864            |p| p.parse_module(),
1865        );
1866    }
1867
1868    #[test]
1869    fn issue_411() {
1870        test_parser(
1871            "try {
1872} catch {}",
1873            Syntax::Es(Default::default()),
1874            |p| p.parse_module(),
1875        );
1876    }
1877
1878    #[test]
1879    fn top_level_await() {
1880        test_parser("await foo", Syntax::Es(Default::default()), |p| {
1881            p.parse_module()
1882        });
1883    }
1884
1885    #[test]
1886    fn issue_856() {
1887        let c = SingleThreadedComments::default();
1888        let s = "class Foo {
1889    static _extensions: {
1890        // eslint-disable-next-line @typescript-eslint/no-explicit-any
1891        [key: string]: (module: Module, filename: string) => any;
1892    } = Object.create(null);
1893}
1894";
1895        let _ = test_parser_comment(&c, s, Syntax::Typescript(Default::default()), |p| {
1896            p.parse_typescript_module()
1897        });
1898
1899        let (leading, trailing) = c.take_all();
1900        assert!(trailing.borrow().is_empty());
1901        assert_eq!(leading.borrow().len(), 1);
1902    }
1903
1904    #[test]
1905    fn issue_856_2() {
1906        let c = SingleThreadedComments::default();
1907        let s = "type ConsoleExamineFunc = (
1908  // eslint-disable-next-line @typescript-eslint/no-explicit-any
1909  csl: any,
1910  out: StringBuffer,
1911  err?: StringBuffer,
1912  both?: StringBuffer
1913) => void;";
1914
1915        let _ = test_parser_comment(&c, s, Syntax::Typescript(Default::default()), |p| {
1916            p.parse_typescript_module()
1917        });
1918
1919        let (leading, trailing) = c.take_all();
1920        assert!(trailing.borrow().is_empty());
1921        assert_eq!(leading.borrow().len(), 1);
1922    }
1923
1924    #[test]
1925    fn issue_856_3() {
1926        let c = SingleThreadedComments::default();
1927        let s = "type RequireWrapper = (
1928  // eslint-disable-next-line @typescript-eslint/no-explicit-any
1929  exports: any,
1930  // eslint-disable-next-line @typescript-eslint/no-explicit-any
1931  require: any,
1932  module: Module,
1933  __filename: string,
1934  __dirname: string
1935) => void;";
1936
1937        let _ = test_parser_comment(&c, s, Syntax::Typescript(Default::default()), |p| {
1938            p.parse_typescript_module()
1939        });
1940
1941        let (leading, trailing) = c.take_all();
1942        assert!(trailing.borrow().is_empty());
1943        assert_eq!(leading.borrow().len(), 2);
1944    }
1945
1946    #[test]
1947    fn issue_856_4() {
1948        let c = SingleThreadedComments::default();
1949        let s = "const _extensions: {
1950    // eslint-disable-next-line @typescript-eslint/no-explicit-any
1951    [key: string]: (module: Module, filename: string) => any;
1952  } = Object.create(null);";
1953
1954        let _ = test_parser_comment(&c, s, Syntax::Typescript(Default::default()), |p| {
1955            p.parse_typescript_module()
1956        });
1957
1958        let (leading, trailing) = c.take_all();
1959        assert!(trailing.borrow().is_empty());
1960        assert_eq!(leading.borrow().len(), 1);
1961    }
1962
1963    fn parse_for_head(str: &'static str) -> TempForHead {
1964        test_parser(str, Syntax::default(), |p| p.parse_for_head())
1965    }
1966
1967    #[test]
1968    fn for_array_binding_pattern() {
1969        match parse_for_head("let [, , t] = simple_array; t < 10; t++") {
1970            TempForHead::For { init: Some(v), .. } => assert_eq_ignore_span!(
1971                v,
1972                VarDeclOrExpr::VarDecl(Box::new(VarDecl {
1973                    span,
1974                    declare: false,
1975                    kind: VarDeclKind::Let,
1976                    decls: vec![VarDeclarator {
1977                        span,
1978                        name: Pat::Array(ArrayPat {
1979                            span,
1980                            type_ann: None,
1981                            optional: false,
1982                            elems: vec![
1983                                None,
1984                                None,
1985                                Some(Pat::Ident(Ident::new_no_ctxt(atom!("t"), span).into()))
1986                            ]
1987                        }),
1988                        init: Some(Box::new(Expr::Ident(Ident::new_no_ctxt(
1989                            atom!("simple_array"),
1990                            span
1991                        )))),
1992                        definite: false
1993                    }],
1994                    ..Default::default()
1995                }))
1996            ),
1997            _ => unreachable!(),
1998        }
1999    }
2000    #[test]
2001    fn for_object_binding_pattern() {
2002        match parse_for_head("let {num} = obj; num < 11; num++") {
2003            TempForHead::For { init: Some(v), .. } => assert_eq_ignore_span!(
2004                v,
2005                VarDeclOrExpr::VarDecl(Box::new(VarDecl {
2006                    span,
2007                    kind: VarDeclKind::Let,
2008                    decls: vec![VarDeclarator {
2009                        span,
2010                        name: Pat::Object(ObjectPat {
2011                            optional: false,
2012                            type_ann: None,
2013                            span,
2014                            props: vec![ObjectPatProp::Assign(AssignPatProp {
2015                                span,
2016                                key: Ident::new_no_ctxt(atom!("num"), span).into(),
2017                                value: None
2018                            })]
2019                        }),
2020                        init: Some(Box::new(Expr::Ident(Ident::new_no_ctxt(
2021                            atom!("obj"),
2022                            span
2023                        )))),
2024                        definite: false
2025                    }],
2026                    ..Default::default()
2027                }))
2028            ),
2029            _ => unreachable!(),
2030        }
2031    }
2032
2033    #[test]
2034    #[should_panic(expected = "'import.meta' cannot be used outside of module code.")]
2035    fn import_meta_in_script() {
2036        let src = "const foo = import.meta.url;";
2037        test_parser(src, Syntax::Es(Default::default()), |p| p.parse_script());
2038    }
2039
2040    #[test]
2041    fn import_meta_in_program() {
2042        let src = "const foo = import.meta.url;";
2043        test_parser(src, Syntax::Es(Default::default()), |p| p.parse_program());
2044    }
2045
2046    #[test]
2047    #[should_panic(expected = "'import', and 'export' cannot be used outside of module code")]
2048    fn import_statement_in_script() {
2049        let src = "import 'foo';";
2050        test_parser(src, Syntax::Es(Default::default()), |p| p.parse_script());
2051    }
2052
2053    #[test]
2054    #[should_panic(expected = "top level await is only allowed in module")]
2055    fn top_level_await_in_script() {
2056        let src = "await promise";
2057        test_parser(src, Syntax::Es(Default::default()), |p| p.parse_script());
2058    }
2059
2060    #[test]
2061    fn top_level_await_in_program() {
2062        let src = "await promise";
2063        test_parser(src, Syntax::Es(Default::default()), |p| p.parse_program());
2064    }
2065
2066    #[test]
2067    fn for_of_head_lhs_async_dot() {
2068        let src = "for (async.x of [1]) ;";
2069        test_parser(src, Syntax::Es(Default::default()), |p| p.parse_module());
2070    }
2071
2072    #[test]
2073    fn for_head_init_async_of() {
2074        let src = "for (async of => {}; i < 10; ++i) { ++counter; }";
2075        test_parser(src, Syntax::Es(Default::default()), |p| p.parse_module());
2076    }
2077
2078    #[test]
2079    #[should_panic(expected = "await isn't allowed in non-async function")]
2080    fn await_in_function_in_module() {
2081        let src = "function foo (p) { await p; }";
2082        test_parser(src, Syntax::Es(Default::default()), |p| p.parse_module());
2083    }
2084
2085    #[test]
2086    #[should_panic(expected = "await isn't allowed in non-async function")]
2087    fn await_in_function_in_script() {
2088        let src = "function foo (p) { await p; }";
2089        test_parser(src, Syntax::Es(Default::default()), |p| p.parse_script());
2090    }
2091
2092    #[test]
2093    #[should_panic(expected = "await isn't allowed in non-async function")]
2094    fn await_in_function_in_program() {
2095        let src = "function foo (p) { await p; }";
2096        test_parser(src, Syntax::Es(Default::default()), |p| p.parse_program());
2097    }
2098
2099    #[test]
2100    #[should_panic(expected = "`await` cannot be used as an identifier in an async context")]
2101    fn await_in_nested_async_function_in_module() {
2102        let src = "async function foo () { function bar(x = await) {} }";
2103        test_parser(src, Syntax::Es(Default::default()), |p| p.parse_module());
2104    }
2105
2106    #[test]
2107    fn await_in_nested_async_function_in_script() {
2108        let src = "async function foo () { function bar(x = await) {} }";
2109        test_parser(src, Syntax::Es(Default::default()), |p| p.parse_script());
2110    }
2111
2112    #[test]
2113    fn await_in_nested_async_function_in_program() {
2114        let src = "async function foo () { function bar(x = await) {} }";
2115        test_parser(src, Syntax::Es(Default::default()), |p| p.parse_program());
2116    }
2117
2118    #[test]
2119    #[should_panic(expected = "`await` cannot be used as an identifier in an async context")]
2120    fn await_as_param_ident_in_module() {
2121        let src = "function foo (x = await) { }";
2122        test_parser(src, Syntax::Es(Default::default()), |p| p.parse_module());
2123    }
2124
2125    #[test]
2126    fn await_as_param_ident_in_script() {
2127        let src = "function foo (x = await) { }";
2128        test_parser(src, Syntax::Es(Default::default()), |p| p.parse_script());
2129    }
2130
2131    #[test]
2132    #[should_panic(expected = "`await` cannot be used as an identifier in an async context")]
2133    fn await_as_ident_in_module() {
2134        let src = "let await = 1";
2135        test_parser(src, Syntax::Es(Default::default()), |p| p.parse_module());
2136    }
2137
2138    #[test]
2139    fn await_as_ident_in_script() {
2140        let src = "let await = 1";
2141        test_parser(src, Syntax::Es(Default::default()), |p| p.parse_script());
2142    }
2143
2144    #[test]
2145    #[should_panic(expected = "`await` cannot be used as an identifier in an async context")]
2146    fn await_as_ident_in_async() {
2147        let src = "async function foo() { let await = 1; }";
2148        test_parser(src, Syntax::Es(Default::default()), |p| p.parse_script());
2149    }
2150
2151    #[test]
2152    fn top_level_await_in_block() {
2153        let src = "if (true) { await promise; }";
2154        test_parser(src, Syntax::Es(Default::default()), |p| p.parse_module());
2155    }
2156
2157    #[test]
2158    fn top_level_await_in_decl() {
2159        test_parser(r#"const t = await test();"#, Default::default(), |p| {
2160            let program = p.parse_program()?;
2161            assert!(program.is_module());
2162            Ok(program)
2163        });
2164    }
2165
2166    #[test]
2167    fn class_static_blocks() {
2168        let src = "class Foo { static { 1 + 1; } }";
2169        assert_eq_ignore_span!(
2170            test_parser(src, Syntax::Es(Default::default()), |p| p.parse_expr()),
2171            Box::new(Expr::Class(ClassExpr {
2172                ident: Some(Ident {
2173                    span,
2174                    sym: atom!("Foo"),
2175                    ..Default::default()
2176                }),
2177                class: Box::new(Class {
2178                    span,
2179                    decorators: Vec::new(),
2180                    super_class: None,
2181                    type_params: None,
2182                    super_type_params: None,
2183                    is_abstract: false,
2184                    implements: Vec::new(),
2185                    body: vec!(ClassMember::StaticBlock(StaticBlock {
2186                        span,
2187                        body: BlockStmt {
2188                            span,
2189                            stmts: vec!(stmt("1 + 1;")),
2190                            ..Default::default()
2191                        }
2192                    })),
2193                    ..Default::default()
2194                })
2195            }))
2196        );
2197    }
2198
2199    #[test]
2200    fn multiple_class_static_blocks() {
2201        let src = "class Foo { static { 1 + 1; } static { 1 + 1; } }";
2202        assert_eq_ignore_span!(
2203            test_parser(src, Syntax::Es(Default::default()), |p| p.parse_expr()),
2204            Box::new(Expr::Class(ClassExpr {
2205                ident: Some(Ident {
2206                    span,
2207                    sym: atom!("Foo"),
2208                    ..Default::default()
2209                }),
2210                class: Box::new(Class {
2211                    span,
2212                    decorators: Vec::new(),
2213                    super_class: None,
2214                    is_abstract: false,
2215                    body: vec!(
2216                        ClassMember::StaticBlock(StaticBlock {
2217                            span,
2218                            body: BlockStmt {
2219                                span,
2220                                stmts: vec!(stmt("1 + 1;")),
2221                                ..Default::default()
2222                            },
2223                        }),
2224                        ClassMember::StaticBlock(StaticBlock {
2225                            span,
2226                            body: BlockStmt {
2227                                span,
2228                                stmts: vec!(stmt("1 + 1;")),
2229                                ..Default::default()
2230                            },
2231                        })
2232                    ),
2233                    ..Default::default()
2234                })
2235            }))
2236        );
2237    }
2238
2239    #[test]
2240    fn class_static_blocks_with_line_breaks_01() {
2241        let src = "class Foo {
2242            static
2243            {
2244                1 + 1;
2245            }
2246        }";
2247        assert_eq_ignore_span!(
2248            test_parser(src, Syntax::Es(Default::default()), |p| p.parse_expr()),
2249            Box::new(Expr::Class(ClassExpr {
2250                ident: Some(Ident {
2251                    span,
2252                    sym: atom!("Foo"),
2253                    ..Default::default()
2254                }),
2255                class: Box::new(Class {
2256                    span,
2257                    is_abstract: false,
2258                    body: vec!(ClassMember::StaticBlock(StaticBlock {
2259                        span,
2260                        body: BlockStmt {
2261                            span,
2262                            stmts: vec!(stmt("1 + 1;")),
2263                            ..Default::default()
2264                        }
2265                    })),
2266                    ..Default::default()
2267                })
2268            }))
2269        );
2270    }
2271
2272    #[test]
2273    fn class_static_blocks_with_line_breaks_02() {
2274        let src = "class Foo {
2275            static
2276            {}
2277        }";
2278        assert_eq_ignore_span!(
2279            test_parser(src, Syntax::Es(Default::default()), |p| p.parse_expr()),
2280            Box::new(Expr::Class(ClassExpr {
2281                ident: Some(Ident {
2282                    span,
2283                    sym: atom!("Foo"),
2284                    ..Default::default()
2285                }),
2286                class: Box::new(Class {
2287                    span,
2288                    is_abstract: false,
2289                    body: vec!(ClassMember::StaticBlock(StaticBlock {
2290                        span,
2291                        body: BlockStmt {
2292                            span,
2293                            stmts: Vec::new(),
2294                            ..Default::default()
2295                        }
2296                    })),
2297                    ..Default::default()
2298                })
2299            }))
2300        );
2301    }
2302
2303    #[test]
2304    fn class_static_blocks_in_ts() {
2305        let src = "class Foo { static { 1 + 1 }; }";
2306        test_parser(src, Syntax::Typescript(Default::default()), |p| {
2307            p.parse_expr()
2308        });
2309    }
2310
2311    #[test]
2312    fn class_static_blocks_with_line_breaks_in_ts_01() {
2313        let src = "class Foo {
2314            static
2315            {
2316                1 + 1;
2317            }
2318        }";
2319        test_parser(src, Syntax::Typescript(Default::default()), |p| {
2320            p.parse_expr()
2321        });
2322    }
2323
2324    #[test]
2325    fn class_static_blocks_with_line_breaks_in_ts_02() {
2326        let src = "class Foo {
2327            static
2328            {}
2329        }";
2330        test_parser(src, Syntax::Typescript(Default::default()), |p| {
2331            p.parse_expr()
2332        });
2333    }
2334
2335    #[test]
2336    #[should_panic(expected = "Expected ident")]
2337    fn class_static_blocks_with_await() {
2338        let src = "class Foo{
2339            static {
2340                var await = 'bar';
2341            }
2342        }";
2343        test_parser(src, Syntax::Es(Default::default()), |p| p.parse_expr());
2344    }
2345
2346    #[test]
2347    #[should_panic(expected = "Expected ident")]
2348    fn class_static_blocks_with_await_in_nested_class() {
2349        let src = "class Foo{
2350            static {
2351                function foo() {
2352                    class Foo {
2353                        static {
2354                            var await = 'bar';
2355                        }
2356                    }
2357                }
2358            }
2359        }";
2360        test_parser(src, Syntax::Es(Default::default()), |p| p.parse_expr());
2361    }
2362
2363    #[test]
2364    fn class_static_blocks_with_await_in_fn() {
2365        let src = "class Foo{
2366            static {
2367                function foo() {
2368                    var await = 'bar';
2369                }
2370            }
2371        }";
2372        test_parser(src, Syntax::Es(Default::default()), |p| p.parse_expr());
2373    }
2374
2375    #[test]
2376    #[should_panic(expected = "Modifiers cannot appear here")]
2377    fn class_static_blocks_in_ts_with_invalid_modifier_01() {
2378        let src = "class Foo { abstract static { 1 + 1 }; }";
2379        test_parser(src, Syntax::Typescript(Default::default()), |p| {
2380            p.parse_expr()
2381        });
2382    }
2383
2384    #[test]
2385    #[should_panic(expected = "Modifiers cannot appear here")]
2386    fn class_static_blocks_in_ts_with_invalid_modifier_02() {
2387        let src = "class Foo { static static { 1 + 1 }; }";
2388        test_parser(src, Syntax::Typescript(Default::default()), |p| {
2389            p.parse_expr()
2390        });
2391    }
2392
2393    #[test]
2394    #[should_panic(expected = "Modifiers cannot appear here")]
2395    fn class_static_blocks_in_ts_with_invalid_modifier_03() {
2396        let src = "class Foo { declare static { 1 + 1 }; }";
2397        test_parser(src, Syntax::Typescript(Default::default()), |p| {
2398            p.parse_expr()
2399        });
2400    }
2401
2402    #[test]
2403    #[should_panic(expected = "Modifiers cannot appear here")]
2404    fn class_static_blocks_in_ts_with_invalid_modifier_04() {
2405        let src = "class Foo { private static { 1 + 1 }; }";
2406        test_parser(src, Syntax::Typescript(Default::default()), |p| {
2407            p.parse_expr()
2408        });
2409    }
2410
2411    #[ignore = "see https://github.com/swc-project/swc/pull/3018#issuecomment-991947907"]
2412    #[test]
2413    #[should_panic(expected = "Trailing comma is disallowed inside import(...) arguments")]
2414    fn error_for_trailing_comma_inside_dynamic_import() {
2415        let src = "import('foo',)";
2416        test_parser(src, Syntax::Es(Default::default()), |p| p.parse_expr());
2417    }
2418
2419    #[test]
2420    fn no_error_for_trailing_comma_inside_dynamic_import_with_import_assertions() {
2421        let src = "import('foo',)";
2422        test_parser(
2423            src,
2424            Syntax::Es(EsSyntax {
2425                import_attributes: true,
2426                ..Default::default()
2427            }),
2428            |p| p.parse_expr(),
2429        );
2430    }
2431
2432    #[test]
2433    fn type_only_star_exports_with_name() {
2434        let src = "export type * as bar from 'mod'";
2435        test_parser(src, Syntax::Typescript(Default::default()), |p| {
2436            p.parse_module()
2437        });
2438    }
2439
2440    #[test]
2441    fn type_only_star_exports_without_name() {
2442        let src = "export type * from 'mod'";
2443        test_parser(src, Syntax::Typescript(Default::default()), |p| {
2444            p.parse_module()
2445        });
2446    }
2447
2448    #[test]
2449    #[should_panic(expected = "A string literal cannot be used as an imported binding.")]
2450    fn error_for_string_literal_is_import_binding() {
2451        let src = "import { \"str\" } from \"mod\"";
2452        test_parser(src, Syntax::Es(Default::default()), |p| p.parse_module());
2453    }
2454
2455    #[test]
2456    #[should_panic(
2457        expected = "A string literal cannot be used as an exported binding without `from`."
2458    )]
2459    fn error_for_string_literal_is_export_binding() {
2460        let src = "export { 'foo' };";
2461        test_parser(src, Syntax::Es(Default::default()), |p| p.parse_module());
2462    }
2463
2464    #[test]
2465    #[should_panic(expected = "'const' declarations must be initialized")]
2466    fn ts_error_for_const_declaration_not_initialized() {
2467        let src = r#"
2468"use strict";
2469const foo;"#;
2470
2471        test_parser(src, Syntax::Typescript(Default::default()), |p| {
2472            p.parse_script()
2473        });
2474    }
2475
2476    #[test]
2477    #[should_panic(expected = "'const' declarations must be initialized")]
2478    fn es_error_for_const_declaration_not_initialized() {
2479        let src = r#"
2480"use strict";
2481const foo;"#;
2482
2483        test_parser(src, Syntax::Es(Default::default()), |p| p.parse_script());
2484    }
2485
2486    #[test]
2487    fn issue_5557_expr_follow_class() {
2488        let src = "foo * class {} / bar;";
2489
2490        test_parser(src, Default::default(), |p| p.parse_script());
2491    }
2492
2493    #[test]
2494    fn issue_5722_class_keyword_in_tpl() {
2495        let src = "console.log(`${toStr({class: fn})}`)";
2496
2497        test_parser(src, Default::default(), |p| p.parse_script());
2498    }
2499
2500    #[test]
2501    fn issue_6301_await_expr_stmt() {
2502        let src = "try { await; } catch { console.log('caught'); }";
2503
2504        test_parser(src, Default::default(), |p| p.parse_script());
2505    }
2506
2507    #[test]
2508    fn issue_6301_await_expr_stmt_1() {
2509        let src = "try { await, await; } catch { console.log('caught'); }";
2510
2511        test_parser(src, Default::default(), |p| p.parse_script());
2512    }
2513
2514    #[test]
2515    fn issue_6301_await_expr_stmt_2() {
2516        let src = "function test() { await; }";
2517
2518        test_parser(src, Default::default(), |p| p.parse_script());
2519    }
2520
2521    #[test]
2522    fn issue_6301_await_expr_stmt_3() {
2523        let src = "function test() { await, await; }";
2524
2525        test_parser(src, Default::default(), |p| p.parse_script());
2526    }
2527
2528    #[test]
2529    fn issue_6301_await_expr_stmt_4() {
2530        let src = "function test() { [await]; }";
2531
2532        test_parser(src, Default::default(), |p| p.parse_script());
2533    }
2534
2535    #[test]
2536    fn issue_6301_await_expr_stmt_5() {
2537        let src = "function test() { (await); }";
2538
2539        test_parser(src, Default::default(), |p| p.parse_script());
2540    }
2541
2542    #[test]
2543    fn issue_6322() {
2544        let src = "for ( ; { } / 1 ; ) ;";
2545
2546        test_parser(src, Default::default(), |p| p.parse_script());
2547    }
2548
2549    #[test]
2550    fn issue_6323() {
2551        let src = "let x = 0 < { } / 0 ;";
2552
2553        test_parser(src, Default::default(), |p| p.parse_script());
2554    }
2555
2556    #[test]
2557    fn issue_10797_0() {
2558        let src = "
2559// var b = delete ANY1;
2560
2561module A {
2562    export const a = 1
2563}";
2564        test_parser(src, Syntax::Typescript(TsSyntax::default()), |p| {
2565            p.parse_script()
2566        });
2567    }
2568
2569    #[test]
2570    fn issue_10797_1() {
2571        let src = "
2572module A {
2573    export const a = 1
2574}
2575
2576var b = delete ANY1;";
2577        test_parser(src, Syntax::Typescript(TsSyntax::default()), |p| {
2578            p.parse_script()
2579        });
2580    }
2581}