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 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 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 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 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 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 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 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 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 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 let mut maybe_using_decl = init.is_ident_ref_to("using");
409 let mut maybe_await_using_decl = false;
410
411 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 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 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 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 crate::maybe_grow(256 * 1024, 1024 * 1024, || {
599 self.do_outside_of_context(
604 Context::IgnoreElseClause.union(Context::TopLevel),
605 Self::parse_stmt,
606 )
607 .map(Box::new)
608 })?
609 };
610
611 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 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 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 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 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 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 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 expect!(self, Token::RBrace);
974
975 Ok(SwitchStmt {
976 span: self.span(switch_start),
977 discriminant,
978 cases,
979 }
980 .into())
981 }
982
983 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 #[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 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 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 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 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 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 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}