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