1use either::Either;
2use rustc_hash::FxHashMap;
3use swc_common::{ast_node, util::take::Take, Spanned};
4
5use super::{pat::PatType, util::ExprExt, *};
6use crate::{lexer::TokenContext, parser::class_and_fn::IsSimpleParameterList};
7
8mod ops;
9#[cfg(test)]
10mod tests;
11mod verifier;
12
13impl<I: Tokens> Parser<I> {
14 pub fn parse_expr(&mut self) -> PResult<Box<Expr>> {
15 trace_cur!(self, parse_expr);
16
17 let _tracing = debug_tracing!(self, "parse_expr");
18
19 let expr = self.parse_assignment_expr()?;
20 let start = expr.span_lo();
21
22 if is!(self, ',') {
23 let mut exprs = vec![expr];
24 while eat!(self, ',') {
25 exprs.push(self.parse_assignment_expr()?);
26 }
27
28 return Ok(SeqExpr {
29 span: span!(self, start),
30 exprs,
31 }
32 .into());
33 }
34
35 Ok(expr)
36 }
37
38 #[cfg_attr(feature = "tracing-spans", tracing::instrument(skip_all))]
40 pub(super) fn parse_assignment_expr(&mut self) -> PResult<Box<Expr>> {
41 trace_cur!(self, parse_assignment_expr);
42
43 if self.input.syntax().typescript() && is!(self, JSXTagStart) {
44 let cur_context = self.input.token_context().current();
48 debug_assert_eq!(cur_context, Some(TokenContext::JSXOpeningTag));
49 debug_assert_eq!(
51 self.input.token_context().0[self.input.token_context().len() - 2],
52 TokenContext::JSXExpr
53 );
54
55 let res = self.try_parse_ts(|p| p.parse_assignment_expr_base().map(Some));
56 if let Some(res) = res {
57 return Ok(res);
58 } else {
59 debug_assert_eq!(
60 self.input.token_context().current(),
61 Some(TokenContext::JSXOpeningTag)
62 );
63 self.input.token_context_mut().pop();
64 debug_assert_eq!(
65 self.input.token_context().current(),
66 Some(TokenContext::JSXExpr)
67 );
68 self.input.token_context_mut().pop();
69 }
70 }
71
72 self.parse_assignment_expr_base()
73 }
74
75 #[cfg_attr(feature = "tracing-spans", tracing::instrument(skip_all))]
80 fn parse_assignment_expr_base(&mut self) -> PResult<Box<Expr>> {
81 trace_cur!(self, parse_assignment_expr_base);
82 let start = self.input.cur_span();
83
84 if self.input.syntax().typescript()
85 && (is_one_of!(self, '<', JSXTagStart))
86 && (peeked_is!(self, IdentName) || peeked_is!(self, JSXName))
87 {
88 let ctx = Context {
89 will_expect_colon_for_cond: false,
90 ..self.ctx()
91 };
92 let res = self.with_ctx(ctx).try_parse_ts(|p| {
93 if is!(p, JSXTagStart) {
94 if let Some(TokenContext::JSXOpeningTag) = p.input.token_context().current() {
95 p.input.token_context_mut().pop();
96
97 debug_assert_eq!(
98 p.input.token_context().current(),
99 Some(TokenContext::JSXExpr)
100 );
101 p.input.token_context_mut().pop();
102 }
103 }
104
105 let type_parameters = p.parse_ts_type_params(false, true)?;
106 let mut arrow = p.parse_assignment_expr_base()?;
107 match *arrow {
108 Expr::Arrow(ArrowExpr {
109 ref mut span,
110 ref mut type_params,
111 ..
112 }) => {
113 *span = Span::new(type_parameters.span.lo, span.hi);
114 *type_params = Some(type_parameters);
115 }
116 _ => unexpected!(p, "("),
117 }
118 Ok(Some(arrow))
119 });
120 if let Some(res) = res {
121 if self.input.syntax().disallow_ambiguous_jsx_like() {
122 self.emit_err(start, SyntaxError::ReservedArrowTypeParam);
123 }
124 return Ok(res);
125 }
126 }
127
128 if self.ctx().in_generator && is!(self, "yield") {
129 return self.parse_yield_expr();
130 }
131
132 self.state.potential_arrow_start = match *cur!(self, true) {
133 Word(Word::Ident(..)) | tok!('(') | tok!("yield") => Some(cur_pos!(self)),
134 _ => None,
135 };
136
137 let start = cur_pos!(self);
138
139 let cond = self.parse_cond_expr()?;
141
142 return_if_arrow!(self, cond);
143
144 match *cond {
145 Expr::Cond(..) | Expr::Bin(..) | Expr::Unary(..) | Expr::Update(..) => return Ok(cond),
148 _ => {}
149 }
150
151 self.finish_assignment_expr(start, cond)
152 }
153
154 fn finish_assignment_expr(&mut self, start: BytePos, cond: Box<Expr>) -> PResult<Box<Expr>> {
155 trace_cur!(self, finish_assignment_expr);
156
157 match self.input.cur() {
158 Some(&Token::AssignOp(op)) => {
159 let left = if op == AssignOp::Assign {
160 match AssignTarget::try_from(
161 self.reparse_expr_as_pat(PatType::AssignPat, cond)?,
162 ) {
163 Ok(pat) => pat,
164 Err(expr) => {
165 syntax_error!(self, expr.span(), SyntaxError::InvalidAssignTarget)
166 }
167 }
168 } else {
169 if !cond.is_valid_simple_assignment_target(self.ctx().strict) {
172 if self.input.syntax().typescript() {
173 self.emit_err(cond.span(), SyntaxError::TS2406);
174 } else {
175 self.emit_err(cond.span(), SyntaxError::NotSimpleAssign)
176 }
177 }
178 if self.input.syntax().typescript()
179 && cond
180 .as_ident()
181 .map(|i| i.is_reserved_in_strict_bind())
182 .unwrap_or(false)
183 {
184 self.emit_strict_mode_err(cond.span(), SyntaxError::TS1100);
185 }
186
187 match AssignTarget::try_from(cond) {
189 Ok(v) => v,
190 Err(v) => {
191 syntax_error!(self, v.span(), SyntaxError::InvalidAssignTarget);
192 }
193 }
194 };
195
196 bump!(self);
197 let right = self.parse_assignment_expr()?;
198 Ok(AssignExpr {
199 span: span!(self, start),
200 op,
201 left,
203 right,
204 }
205 .into())
206 }
207 _ => Ok(cond),
208 }
209 }
210
211 #[cfg_attr(feature = "tracing-spans", tracing::instrument(skip_all))]
213 fn parse_cond_expr(&mut self) -> PResult<Box<Expr>> {
214 trace_cur!(self, parse_cond_expr);
215
216 let start = cur_pos!(self);
217
218 let test = self.parse_bin_expr()?;
219 return_if_arrow!(self, test);
220
221 if eat!(self, '?') {
222 let ctx = Context {
223 in_cond_expr: true,
224 will_expect_colon_for_cond: true,
225 include_in_expr: true,
226 ..self.ctx()
227 };
228 let cons = self.with_ctx(ctx).parse_assignment_expr()?;
229 expect!(self, ':');
230 let ctx = Context {
231 in_cond_expr: true,
232 will_expect_colon_for_cond: false,
233 ..self.ctx()
234 };
235 let alt = self.with_ctx(ctx).parse_assignment_expr()?;
236 let span = Span::new(start, alt.span_hi());
237 Ok(CondExpr {
238 span,
239 test,
240 cons,
241 alt,
242 }
243 .into())
244 } else {
245 Ok(test)
246 }
247 }
248
249 #[cfg_attr(feature = "tracing-spans", tracing::instrument(skip_all))]
251 pub(super) fn parse_primary_expr(&mut self) -> PResult<Box<Expr>> {
252 trace_cur!(self, parse_primary_expr);
253
254 let _ = self.input.cur();
255 let start = cur_pos!(self);
256
257 let can_be_arrow = self
258 .state
259 .potential_arrow_start
260 .map(|s| s == start)
261 .unwrap_or(false);
262
263 if let Some(tok) = self.input.cur() {
264 match tok {
265 tok!("this") => {
266 self.input.bump();
267 return Ok(ThisExpr {
268 span: span!(self, start),
269 }
270 .into());
271 }
272
273 tok!("async") => {
274 if peeked_is!(self, "function")
275 && !self.input.has_linebreak_between_cur_and_peeked()
276 {
277 return self.parse_async_fn_expr();
279 }
280
281 if can_be_arrow && self.input.syntax().typescript() && peeked_is!(self, '<') {
282 if let Some(res) = self.try_parse_ts(|p| {
284 let start = cur_pos!(p);
285 assert_and_bump!(p, "async");
286 p.try_parse_ts_generic_async_arrow_fn(start)
287 }) {
288 return Ok(res.into());
289 }
290 }
291
292 if can_be_arrow
293 && peeked_is!(self, '(')
294 && !self.input.has_linebreak_between_cur_and_peeked()
295 {
296 expect!(self, "async");
297 let async_span = self.input.prev_span();
298 return self.parse_paren_expr_or_arrow_fn(can_be_arrow, Some(async_span));
299 }
300 }
301
302 tok!('[') => {
303 let ctx = Context {
304 will_expect_colon_for_cond: false,
305 ..self.ctx()
306 };
307 return self.with_ctx(ctx).parse_array_lit();
308 }
309
310 tok!('{') => {
311 return self.parse_object::<Expr>().map(Box::new);
312 }
313
314 tok!("function") => {
316 return self.parse_fn_expr();
317 }
318
319 tok!("null")
321 | tok!("true")
322 | tok!("false")
323 | Token::Num { .. }
324 | Token::BigInt { .. }
325 | Token::Str { .. } => {
326 return Ok(self.parse_lit()?.into());
327 }
328
329 tok!('/') | tok!("/=") => {
331 bump!(self);
332
333 self.input.set_next_regexp(Some(start));
334
335 if let Some(Token::Regex(..)) = self.input.cur() {
336 self.input.set_next_regexp(None);
337
338 match bump!(self) {
339 Token::Regex(exp, flags) => {
340 let span = span!(self, start);
341
342 let mut flags_count = flags.chars().fold(
343 FxHashMap::<char, usize>::default(),
344 |mut map, flag| {
345 let key = match flag {
346 'd' | 'g' | 'i' | 'm' | 's' | 'u' | 'v' | 'y' => flag,
348 _ => '\u{0000}', };
350 map.entry(key).and_modify(|count| *count += 1).or_insert(1);
351 map
352 },
353 );
354
355 if flags_count.remove(&'\u{0000}').is_some() {
356 self.emit_err(span, SyntaxError::UnknownRegExpFlags);
357 }
358
359 if let Some((flag, _)) =
360 flags_count.iter().find(|(_, count)| **count > 1)
361 {
362 self.emit_err(span, SyntaxError::DuplicatedRegExpFlags(*flag));
363 }
364
365 return Ok(Lit::Regex(Regex { span, exp, flags }).into());
366 }
367 _ => unreachable!(),
368 }
369 }
370 }
371
372 tok!('`') => {
373 let ctx = Context {
374 will_expect_colon_for_cond: false,
375 ..self.ctx()
376 };
377
378 return Ok(self.with_ctx(ctx).parse_tpl(false)?.into());
380 }
381
382 tok!('(') => {
383 return self.parse_paren_expr_or_arrow_fn(can_be_arrow, None);
384 }
385
386 _ => {}
387 }
388 }
389
390 let decorators = self.parse_decorators(false)?;
391
392 if is!(self, "class") {
393 return self.parse_class_expr(start, decorators);
394 }
395
396 if is!(self, "let")
397 || (self.input.syntax().typescript() && is_one_of!(self, IdentRef, "await"))
398 || is!(self, IdentRef)
399 {
400 let ctx = self.ctx();
401 let id = self.parse_ident(!ctx.in_generator, !ctx.in_async)?;
402 if id.is_reserved_in_strict_mode(self.ctx().module && !self.ctx().in_declare) {
403 self.emit_strict_mode_err(
404 self.input.prev_span(),
405 SyntaxError::InvalidIdentInStrict(id.sym.clone()),
406 );
407 }
408
409 if can_be_arrow
410 && id.sym == "async"
411 && !self.input.had_line_break_before_cur()
412 && is!(self, BindingIdent)
413 {
414 if ctx.expr_ctx.for_loop_init && is!(self, "of") && !peeked_is!(self, "=>") {
421 if !ctx.expr_ctx.for_await_loop_init {
427 self.emit_err(self.input.prev_span(), SyntaxError::TS1106);
428 }
429
430 return Ok(id.into());
431 }
432
433 let ident = self.parse_binding_ident(false)?;
434 if self.input.syntax().typescript() && ident.sym == "as" && !is!(self, "=>") {
435 let type_ann = self.in_type().parse_with(|p| p.parse_ts_type())?;
437 return Ok(TsAsExpr {
438 span: span!(self, start),
439 expr: Box::new(id.into()),
440 type_ann,
441 }
442 .into());
443 }
444
445 let arg = ident.into();
447 let params = vec![arg];
448 expect!(self, "=>");
449 let body =
450 self.parse_fn_body(true, false, true, params.is_simple_parameter_list())?;
451
452 return Ok(ArrowExpr {
453 span: span!(self, start),
454 body,
455 params,
456 is_async: true,
457 is_generator: false,
458 ..Default::default()
459 }
460 .into());
461 } else if can_be_arrow && !self.input.had_line_break_before_cur() && eat!(self, "=>") {
462 if self.ctx().strict && id.is_reserved_in_strict_bind() {
463 self.emit_strict_mode_err(id.span, SyntaxError::EvalAndArgumentsInStrict)
464 }
465 let params = vec![id.into()];
466 let body =
467 self.parse_fn_body(false, false, true, params.is_simple_parameter_list())?;
468
469 return Ok(ArrowExpr {
470 span: span!(self, start),
471 body,
472 params,
473 is_async: false,
474 is_generator: false,
475 ..Default::default()
476 }
477 .into());
478 } else {
479 return Ok(id.into());
480 }
481 }
482
483 if eat!(self, '#') {
484 let id = self.parse_ident_name()?;
485 return Ok(PrivateName {
486 span: span!(self, start),
487 name: id.sym,
488 }
489 .into());
490 }
491
492 syntax_error!(self, self.input.cur_span(), SyntaxError::TS1109)
493 }
494
495 #[cfg_attr(feature = "tracing-spans", tracing::instrument(skip_all))]
496 fn parse_array_lit(&mut self) -> PResult<Box<Expr>> {
497 trace_cur!(self, parse_array_lit);
498
499 let start = cur_pos!(self);
500
501 assert_and_bump!(self, '[');
502 let mut elems = Vec::new();
503
504 while !eof!(self) && !is!(self, ']') {
505 if is!(self, ',') {
506 expect!(self, ',');
507 elems.push(None);
508 continue;
509 }
510 elems.push(
511 self.include_in_expr(true)
512 .parse_expr_or_spread()
513 .map(Some)?,
514 );
515 if !is!(self, ']') {
516 expect!(self, ',');
517 if is!(self, ']') {
518 self.state
519 .trailing_commas
520 .insert(start, self.input.prev_span());
521 }
522 }
523 }
524
525 expect!(self, ']');
526
527 let span = span!(self, start);
528 Ok(ArrayLit { span, elems }.into())
529 }
530
531 #[allow(dead_code)]
532 fn parse_member_expr(&mut self) -> PResult<Box<Expr>> {
533 self.parse_member_expr_or_new_expr(false)
534 }
535
536 #[cfg_attr(feature = "tracing-spans", tracing::instrument(skip_all))]
538 fn parse_member_expr_or_new_expr(&mut self, is_new_expr: bool) -> PResult<Box<Expr>> {
539 let ctx = Context {
540 should_not_lex_lt_or_gt_as_type: true,
541 ..self.ctx()
542 };
543 self.with_ctx(ctx)
544 .parse_member_expr_or_new_expr_inner(is_new_expr)
545 }
546
547 fn parse_member_expr_or_new_expr_inner(&mut self, is_new_expr: bool) -> PResult<Box<Expr>> {
548 trace_cur!(self, parse_member_expr_or_new_expr);
549
550 let start = cur_pos!(self);
551 if eat!(self, "new") {
552 if eat!(self, '.') {
553 if eat!(self, "target") {
554 let span = span!(self, start);
555 let expr = MetaPropExpr {
556 span,
557 kind: MetaPropKind::NewTarget,
558 }
559 .into();
560
561 let ctx = self.ctx();
562 if (!ctx.inside_non_arrow_function_scope) && !ctx.in_parameters && !ctx.in_class
563 {
564 self.emit_err(span, SyntaxError::InvalidNewTarget);
565 }
566
567 return self.parse_subscripts(Callee::Expr(expr), true, false);
568 }
569
570 unexpected!(self, "target")
571 }
572
573 let callee = self.parse_member_expr_or_new_expr(is_new_expr)?;
575 return_if_arrow!(self, callee);
576
577 if is_new_expr {
578 match *callee {
579 Expr::OptChain(OptChainExpr {
580 span,
581 optional: true,
582 ..
583 }) => {
584 syntax_error!(self, span, SyntaxError::OptChainCannotFollowConstructorCall)
585 }
586 Expr::Member(MemberExpr { ref obj, .. }) => {
587 if let Expr::OptChain(OptChainExpr {
588 span,
589 optional: true,
590 ..
591 }) = **obj
592 {
593 syntax_error!(
594 self,
595 span,
596 SyntaxError::OptChainCannotFollowConstructorCall
597 )
598 }
599 }
600 _ => {}
601 }
602 }
603
604 let type_args = if self.input.syntax().typescript() && is_one_of!(self, '<', "<<") {
605 self.try_parse_ts(|p| {
606 let ctx = Context {
607 should_not_lex_lt_or_gt_as_type: false,
608 ..p.ctx()
609 };
610
611 let args = p.with_ctx(ctx).parse_ts_type_args()?;
612 if !is!(p, '(') {
613 expect!(p, '(');
615 }
616 Ok(Some(args))
617 })
618 } else {
619 None
620 };
621
622 if !is_new_expr || is!(self, '(') {
623 let args = self.parse_args(false).map(Some)?;
625
626 let new_expr = Callee::Expr(
627 NewExpr {
628 span: span!(self, start),
629 callee,
630 args,
631 type_args,
632 ..Default::default()
633 }
634 .into(),
635 );
636
637 return self.parse_subscripts(new_expr, true, false);
640 }
641
642 return Ok(NewExpr {
645 span: span!(self, start),
646 callee,
647 args: None,
648 type_args,
649 ..Default::default()
650 }
651 .into());
652 }
653
654 if eat!(self, "super") {
655 let base = Callee::Super(Super {
656 span: span!(self, start),
657 });
658 return self.parse_subscripts(base, true, false);
659 }
660 if eat!(self, "import") {
661 return self.parse_dynamic_import_or_import_meta(start, true);
662 }
663 let obj = self.parse_primary_expr()?;
664 return_if_arrow!(self, obj);
665
666 let type_args = if self.syntax().typescript() && is!(self, '<') {
667 self.try_parse_ts_type_args()
668 } else {
669 None
670 };
671 let obj = if let Some(type_args) = type_args {
672 trace_cur!(self, parse_member_expr_or_new_expr__with_type_args);
673 TsInstantiation {
674 expr: obj,
675 type_args,
676 span: span!(self, start),
677 }
678 .into()
679 } else {
680 obj
681 };
682
683 self.parse_subscripts(Callee::Expr(obj), true, false)
684 }
685
686 #[cfg_attr(feature = "tracing-spans", tracing::instrument(skip_all))]
689 pub(super) fn parse_new_expr(&mut self) -> PResult<Box<Expr>> {
690 trace_cur!(self, parse_new_expr);
691
692 self.parse_member_expr_or_new_expr(true)
693 }
694
695 #[cfg_attr(feature = "tracing-spans", tracing::instrument(skip_all))]
697 pub(super) fn parse_args(&mut self, is_dynamic_import: bool) -> PResult<Vec<ExprOrSpread>> {
698 trace_cur!(self, parse_args);
699
700 let ctx = Context {
701 will_expect_colon_for_cond: false,
702 ..self.ctx()
703 };
704
705 self.with_ctx(ctx).parse_with(|p| {
706 let start = cur_pos!(p);
707 expect!(p, '(');
708
709 let mut first = true;
710 let mut expr_or_spreads = Vec::with_capacity(2);
711
712 while !eof!(p) && !is!(p, ')') {
713 if first {
714 first = false;
715 } else {
716 expect!(p, ',');
717 if is!(p, ')') {
719 if is_dynamic_import && !p.input.syntax().import_attributes() {
720 syntax_error!(
721 p,
722 span!(p, start),
723 SyntaxError::TrailingCommaInsideImport
724 )
725 }
726
727 break;
728 }
729 }
730
731 expr_or_spreads.push(p.include_in_expr(true).parse_expr_or_spread()?);
732 }
733
734 expect!(p, ')');
735 Ok(expr_or_spreads)
736 })
737 }
738
739 pub(super) fn parse_expr_or_spread(&mut self) -> PResult<ExprOrSpread> {
742 trace_cur!(self, parse_expr_or_spread);
743
744 let start = cur_pos!(self);
745
746 if eat!(self, "...") {
747 let spread_span = span!(self, start);
748 let spread = Some(spread_span);
749 self.include_in_expr(true)
750 .parse_assignment_expr()
751 .map_err(|err| {
752 Error::new(
753 err.span(),
754 SyntaxError::WithLabel {
755 inner: Box::new(err),
756 span: spread_span,
757 note: "An expression should follow '...'",
758 },
759 )
760 })
761 .map(|expr| ExprOrSpread { spread, expr })
762 } else {
763 self.parse_assignment_expr()
764 .map(|expr| ExprOrSpread { spread: None, expr })
765 }
766 }
767
768 #[cfg_attr(feature = "tracing-spans", tracing::instrument(skip_all))]
770 fn parse_paren_expr_or_arrow_fn(
771 &mut self,
772 can_be_arrow: bool,
773 async_span: Option<Span>,
774 ) -> PResult<Box<Expr>> {
775 trace_cur!(self, parse_paren_expr_or_arrow_fn);
776
777 let expr_start = async_span.map(|x| x.lo()).unwrap_or_else(|| cur_pos!(self));
778
779 let ctx = Context {
785 will_expect_colon_for_cond: false,
786 ..self.ctx()
787 };
788
789 let (paren_items, trailing_comma) = self
790 .with_ctx(ctx)
791 .include_in_expr(true)
792 .parse_args_or_pats()?;
793
794 let has_pattern = paren_items
795 .iter()
796 .any(|item| matches!(item, AssignTargetOrSpread::Pat(..)));
797
798 let will_expect_colon_for_cond = self.ctx().will_expect_colon_for_cond;
799 if self.syntax().typescript() && self.ctx().in_cond_expr && is!(self, ':') {
801 let items_ref = &paren_items;
803 if let Some(expr) = self.try_parse_ts(|p| {
804 let return_type = p.parse_ts_type_or_type_predicate_ann(&tok!(':'))?;
805
806 expect!(p, "=>");
807
808 let params: Vec<Pat> = p
809 .parse_paren_items_as_params(items_ref.clone(), trailing_comma)?
810 .into_iter()
811 .collect();
812
813 let body: Box<BlockStmtOrExpr> = p.parse_fn_body(
814 async_span.is_some(),
815 false,
816 true,
817 params.is_simple_parameter_list(),
818 )?;
819
820 if will_expect_colon_for_cond && !is!(p, ':') {
821 trace_cur!(p, parse_arrow_in_cond__fail);
822 unexpected!(p, "fail")
823 }
824
825 Ok(Some(
826 ArrowExpr {
827 span: span!(p, expr_start),
828 is_async: async_span.is_some(),
829 is_generator: false,
830 params,
831 body,
832 return_type: Some(return_type),
833 ..Default::default()
834 }
835 .into(),
836 ))
837 }) {
838 return Ok(expr);
839 }
840 }
841
842 let return_type = if !self.ctx().will_expect_colon_for_cond
843 && self.input.syntax().typescript()
844 && is!(self, ':')
845 {
846 self.try_parse_ts(|p| {
847 let return_type = p.parse_ts_type_or_type_predicate_ann(&tok!(':'))?;
848
849 if !is!(p, "=>") {
850 unexpected!(p, "fail")
851 }
852
853 Ok(Some(return_type))
854 })
855 } else {
856 None
857 };
858
859 if has_pattern || return_type.is_some() || is!(self, "=>") {
861 if self.input.had_line_break_before_cur() {
862 syntax_error!(
863 self,
864 span!(self, expr_start),
865 SyntaxError::LineBreakBeforeArrow
866 );
867 }
868
869 if !can_be_arrow {
870 syntax_error!(self, span!(self, expr_start), SyntaxError::ArrowNotAllowed);
871 }
872 expect!(self, "=>");
873
874 let params: Vec<Pat> = self
875 .parse_paren_items_as_params(paren_items, trailing_comma)?
876 .into_iter()
877 .collect();
878
879 let body: Box<BlockStmtOrExpr> = self.parse_fn_body(
880 async_span.is_some(),
881 false,
882 true,
883 params.is_simple_parameter_list(),
884 )?;
885 let arrow_expr = ArrowExpr {
886 span: span!(self, expr_start),
887 is_async: async_span.is_some(),
888 is_generator: false,
889 params,
890 body,
891 return_type,
892 ..Default::default()
893 };
894 if let BlockStmtOrExpr::BlockStmt(..) = &*arrow_expr.body {
895 if let Some(&Token::BinOp(..)) = self.input.cur() {
896 self.emit_err(self.input.cur_span(), SyntaxError::TS1005);
898 let errorred_expr =
899 self.parse_bin_op_recursively(Box::new(arrow_expr.into()), 0)?;
900
901 if !is!(self, ';') {
902 self.emit_err(self.input.cur_span(), SyntaxError::TS1005);
904 }
905
906 return Ok(errorred_expr);
907 }
908 }
909 return Ok(arrow_expr.into());
910 } else {
911 for expr_or_spread in paren_items.iter() {
915 if let AssignTargetOrSpread::ExprOrSpread(e) = expr_or_spread {
916 if let Expr::Object(o) = &*e.expr {
917 for p in o.props.iter() {
918 if let PropOrSpread::Prop(prop) = p {
919 if let Prop::Assign(..) = **prop {
920 self.emit_err(prop.span(), SyntaxError::AssignProperty);
921 }
922 }
923 }
924 }
925 }
926 }
927 }
928
929 let expr_or_spreads = paren_items
930 .into_iter()
931 .map(|item| -> PResult<_> {
932 match item {
933 AssignTargetOrSpread::ExprOrSpread(e) => Ok(e),
934 _ => syntax_error!(self, item.span(), SyntaxError::InvalidExpr),
935 }
936 })
937 .collect::<Result<Vec<_>, _>>()?;
938 if let Some(async_span) = async_span {
939 return Ok(CallExpr {
941 span: span!(self, async_span.lo()),
942 callee: Callee::Expr(Box::new(
943 Ident::new_no_ctxt("async".into(), async_span).into(),
944 )),
945 args: expr_or_spreads,
946 ..Default::default()
947 }
948 .into());
949 }
950
951 if expr_or_spreads.is_empty() {
954 syntax_error!(
955 self,
956 Span::new(expr_start, last_pos!(self),),
957 SyntaxError::EmptyParenExpr
958 );
959 }
960
961 if expr_or_spreads.len() == 1 {
965 let expr = match expr_or_spreads.into_iter().next().unwrap() {
966 ExprOrSpread {
967 spread: Some(..),
968 ref expr,
969 } => syntax_error!(self, expr.span(), SyntaxError::SpreadInParenExpr),
970 ExprOrSpread { expr, .. } => expr,
971 };
972 Ok(ParenExpr {
973 span: span!(self, expr_start),
974 expr,
975 }
976 .into())
977 } else {
978 debug_assert!(expr_or_spreads.len() >= 2);
979
980 let mut exprs = Vec::with_capacity(expr_or_spreads.len());
981 for expr in expr_or_spreads {
982 match expr {
983 ExprOrSpread {
984 spread: Some(..),
985 ref expr,
986 } => syntax_error!(self, expr.span(), SyntaxError::SpreadInParenExpr),
987 ExprOrSpread { expr, .. } => exprs.push(expr),
988 }
989 }
990 debug_assert!(exprs.len() >= 2);
991
992 let seq_expr = SeqExpr {
994 span: Span::new(
995 exprs.first().unwrap().span_lo(),
996 exprs.last().unwrap().span_hi(),
997 ),
998 exprs,
999 }
1000 .into();
1001 Ok(ParenExpr {
1002 span: span!(self, expr_start),
1003 expr: seq_expr,
1004 }
1005 .into())
1006 }
1007 }
1008
1009 fn parse_tpl_elements(
1010 &mut self,
1011 is_tagged_tpl: bool,
1012 ) -> PResult<(Vec<Box<Expr>>, Vec<TplElement>)> {
1013 trace_cur!(self, parse_tpl_elements);
1014
1015 let mut exprs = Vec::new();
1016
1017 let cur_elem = self.parse_tpl_element(is_tagged_tpl)?;
1018 let mut is_tail = cur_elem.tail;
1019 let mut quasis = vec![cur_elem];
1020
1021 while !is_tail {
1022 expect!(self, "${");
1023 exprs.push(self.include_in_expr(true).parse_expr()?);
1024 expect!(self, '}');
1025 let elem = self.parse_tpl_element(is_tagged_tpl)?;
1026 is_tail = elem.tail;
1027 quasis.push(elem);
1028 }
1029
1030 Ok((exprs, quasis))
1031 }
1032
1033 fn parse_tagged_tpl(
1034 &mut self,
1035 tag: Box<Expr>,
1036 type_params: Option<Box<TsTypeParamInstantiation>>,
1037 ) -> PResult<TaggedTpl> {
1038 let tagged_tpl_start = tag.span_lo();
1039 trace_cur!(self, parse_tagged_tpl);
1040
1041 let tpl = Box::new(self.parse_tpl(true)?);
1042
1043 let span = span!(self, tagged_tpl_start);
1044
1045 if tag.is_opt_chain() {
1046 self.emit_err(span, SyntaxError::TaggedTplInOptChain);
1047 }
1048
1049 Ok(TaggedTpl {
1050 span,
1051 tag,
1052 type_params,
1053 tpl,
1054 ..Default::default()
1055 })
1056 }
1057
1058 pub(super) fn parse_tpl(&mut self, is_tagged_tpl: bool) -> PResult<Tpl> {
1059 trace_cur!(self, parse_tpl);
1060 let start = cur_pos!(self);
1061
1062 assert_and_bump!(self, '`');
1063
1064 let (exprs, quasis) = self.parse_tpl_elements(is_tagged_tpl)?;
1065
1066 expect!(self, '`');
1067
1068 let span = span!(self, start);
1069 Ok(Tpl {
1070 span,
1071 exprs,
1072 quasis,
1073 })
1074 }
1075
1076 pub(super) fn parse_tpl_element(&mut self, is_tagged_tpl: bool) -> PResult<TplElement> {
1077 let start = cur_pos!(self);
1078
1079 let (raw, cooked) = match *cur!(self, true) {
1080 Token::Template { .. } => match bump!(self) {
1081 Token::Template { raw, cooked, .. } => match cooked {
1082 Ok(cooked) => (raw, Some(cooked)),
1083 Err(err) => {
1084 if is_tagged_tpl {
1085 (raw, None)
1086 } else {
1087 return Err(err);
1088 }
1089 }
1090 },
1091 _ => unreachable!(),
1092 },
1093 _ => unexpected!(self, "template token"),
1094 };
1095
1096 let tail = is!(self, '`');
1097
1098 Ok(TplElement {
1099 span: span!(self, start),
1100 raw,
1101 tail,
1102
1103 cooked,
1104 })
1105 }
1106
1107 #[cfg_attr(feature = "tracing-spans", tracing::instrument(skip_all))]
1108 pub(super) fn parse_subscripts(
1109 &mut self,
1110 mut obj: Callee,
1111 no_call: bool,
1112 no_computed_member: bool,
1113 ) -> PResult<Box<Expr>> {
1114 let start = obj.span().lo;
1115 loop {
1116 obj = match self.parse_subscript(start, obj, no_call, no_computed_member)? {
1117 (expr, false) => return Ok(expr),
1118 (expr, true) => Callee::Expr(expr),
1119 }
1120 }
1121 }
1122
1123 #[cfg_attr(feature = "tracing-spans", tracing::instrument(skip_all))]
1125 fn parse_subscript(
1126 &mut self,
1127 start: BytePos,
1128 mut obj: Callee,
1129 no_call: bool,
1130 no_computed_member: bool,
1131 ) -> PResult<(Box<Expr>, bool)> {
1132 trace_cur!(self, parse_subscript);
1133 let _ = cur!(self, false);
1134
1135 if self.input.syntax().typescript() {
1136 if !self.input.had_line_break_before_cur() && is!(self, '!') {
1137 self.input.set_expr_allowed(false);
1138 assert_and_bump!(self, '!');
1139
1140 let expr = match obj {
1141 Callee::Super(..) => {
1142 syntax_error!(
1143 self,
1144 self.input.cur_span(),
1145 SyntaxError::TsNonNullAssertionNotAllowed("super".into())
1146 )
1147 }
1148 Callee::Import(..) => {
1149 syntax_error!(
1150 self,
1151 self.input.cur_span(),
1152 SyntaxError::TsNonNullAssertionNotAllowed("import".into())
1153 )
1154 }
1155 Callee::Expr(expr) => expr,
1156 };
1157 return Ok((
1158 TsNonNullExpr {
1159 span: span!(self, start),
1160 expr,
1161 }
1162 .into(),
1163 true,
1164 ));
1165 }
1166
1167 if matches!(obj, Callee::Expr(..)) && is!(self, '<') {
1168 let is_dynamic_import = obj.is_import();
1169
1170 let mut obj_opt = Some(obj);
1171 let mut_obj_opt = &mut obj_opt;
1177
1178 let ctx: Context = Context {
1179 should_not_lex_lt_or_gt_as_type: true,
1180 ..self.ctx()
1181 };
1182 let result = self.with_ctx(ctx).try_parse_ts(|p| {
1183 if !no_call
1184 && p.at_possible_async(match &mut_obj_opt {
1185 Some(Callee::Expr(ref expr)) => expr,
1186 _ => unreachable!(),
1187 })?
1188 {
1189 let async_arrow_fn = p.try_parse_ts_generic_async_arrow_fn(start)?;
1192 if let Some(async_arrow_fn) = async_arrow_fn {
1193 return Ok(Some((async_arrow_fn.into(), true)));
1194 }
1195 }
1196
1197 let type_args = p.parse_ts_type_args()?;
1198
1199 if !no_call && is!(p, '(') {
1200 let args = p.parse_args(is_dynamic_import)?;
1203
1204 let obj = mut_obj_opt.take().unwrap();
1205
1206 if let Callee::Expr(callee) = &obj {
1207 if let Expr::OptChain(..) = &**callee {
1208 return Ok(Some((
1209 OptChainExpr {
1210 span: span!(p, start),
1211 base: Box::new(OptChainBase::Call(OptCall {
1212 span: span!(p, start),
1213 callee: obj.expect_expr(),
1214 type_args: Some(type_args),
1215 args,
1216 ..Default::default()
1217 })),
1218 optional: false,
1219 }
1220 .into(),
1221 true,
1222 )));
1223 }
1224 }
1225
1226 Ok(Some((
1227 CallExpr {
1228 span: span!(p, start),
1229 callee: obj,
1230 type_args: Some(type_args),
1231 args,
1232 ..Default::default()
1233 }
1234 .into(),
1235 true,
1236 )))
1237 } else if is!(p, '`') {
1238 p.parse_tagged_tpl(
1239 match mut_obj_opt {
1240 Some(Callee::Expr(obj)) => obj.take(),
1241 _ => unreachable!(),
1242 },
1243 Some(type_args),
1244 )
1245 .map(|expr| (expr.into(), true))
1246 .map(Some)
1247 } else if is_one_of!(p, '=', "as", "satisfies") {
1248 Ok(Some((
1249 TsInstantiation {
1250 span: span!(p, start),
1251 expr: match mut_obj_opt {
1252 Some(Callee::Expr(obj)) => obj.take(),
1253 _ => unreachable!(),
1254 },
1255 type_args,
1256 }
1257 .into(),
1258 false,
1259 )))
1260 } else if no_call {
1261 unexpected!(p, "`")
1262 } else {
1263 unexpected!(p, "( or `")
1264 }
1265 });
1266 if let Some(result) = result {
1267 return Ok(result);
1268 }
1269
1270 obj = obj_opt.unwrap();
1271 }
1272 }
1273
1274 let type_args = if self.syntax().typescript() && is!(self, '<') {
1275 self.try_parse_ts_type_args()
1276 } else {
1277 None
1278 };
1279
1280 if obj.is_import() && !is_one_of!(self, '.', '(') {
1281 unexpected!(self, "`.` or `(`")
1282 }
1283
1284 let question_dot_token = if is!(self, '?') && peeked_is!(self, '.') {
1285 let start = cur_pos!(self);
1286 eat!(self, '?');
1287 Some(span!(self, start))
1288 } else {
1289 None
1290 };
1291
1292 if !no_computed_member
1294 && ((question_dot_token.is_some()
1295 && is!(self, '.')
1296 && peeked_is!(self, '[')
1297 && eat!(self, '.')
1298 && eat!(self, '['))
1299 || eat!(self, '['))
1300 {
1301 let bracket_lo = self.input.prev_span().lo;
1302 let prop = self.include_in_expr(true).parse_expr()?;
1303 expect!(self, ']');
1304 let span = Span::new(obj.span_lo(), self.input.last_pos());
1305 debug_assert_eq!(obj.span_lo(), span.lo());
1306 let prop = ComputedPropName {
1307 span: Span::new(bracket_lo, self.input.last_pos()),
1308 expr: prop,
1309 };
1310
1311 let type_args = if self.syntax().typescript() && is!(self, '<') {
1312 self.try_parse_ts_type_args()
1313 } else {
1314 None
1315 };
1316
1317 return Ok((
1318 Box::new(match obj {
1319 Callee::Import(..) => unreachable!(),
1320 Callee::Super(obj) => {
1321 if !self.ctx().allow_direct_super
1322 && !self.input.syntax().allow_super_outside_method()
1323 {
1324 syntax_error!(self, self.input.cur_span(), SyntaxError::InvalidSuper);
1325 } else if question_dot_token.is_some() {
1326 if no_call {
1327 syntax_error!(
1328 self,
1329 self.input.cur_span(),
1330 SyntaxError::InvalidSuperCall
1331 );
1332 }
1333 syntax_error!(self, self.input.cur_span(), SyntaxError::InvalidSuper);
1334 } else {
1335 SuperPropExpr {
1336 span,
1337 obj,
1338 prop: SuperProp::Computed(prop),
1339 }
1340 .into()
1341 }
1342 }
1343 Callee::Expr(obj) => {
1344 let is_opt_chain = unwrap_ts_non_null(&obj).is_opt_chain();
1345 let expr = MemberExpr {
1346 span,
1347 obj,
1348 prop: MemberProp::Computed(prop),
1349 };
1350 let expr = if is_opt_chain || question_dot_token.is_some() {
1351 OptChainExpr {
1352 span,
1353 optional: question_dot_token.is_some(),
1354 base: Box::new(OptChainBase::Member(expr)),
1355 }
1356 .into()
1357 } else {
1358 expr.into()
1359 };
1360
1361 if let Some(type_args) = type_args {
1362 TsInstantiation {
1363 expr: Box::new(expr),
1364 type_args,
1365 span: span!(self, start),
1366 }
1367 .into()
1368 } else {
1369 expr
1370 }
1371 }
1372 }),
1373 true,
1374 ));
1375 }
1376
1377 if (question_dot_token.is_some()
1378 && is!(self, '.')
1379 && (peeked_is!(self, '(') || (self.syntax().typescript() && peeked_is!(self, '<')))
1380 && eat!(self, '.'))
1381 || (!no_call && (is!(self, '(')))
1382 {
1383 let type_args = if self.syntax().typescript() && is!(self, '<') {
1384 self.parse_ts_type_args().map(Some)?
1385 } else {
1386 None
1387 };
1388 let args = self.parse_args(obj.is_import())?;
1389 let span = span!(self, start);
1390 return if question_dot_token.is_some()
1391 || match &obj {
1392 Callee::Expr(obj) => unwrap_ts_non_null(obj).is_opt_chain(),
1393 _ => false,
1394 } {
1395 match obj {
1396 Callee::Super(_) | Callee::Import(_) => {
1397 syntax_error!(self, self.input.cur_span(), SyntaxError::SuperCallOptional)
1398 }
1399 Callee::Expr(callee) => Ok((
1400 OptChainExpr {
1401 span,
1402 optional: question_dot_token.is_some(),
1403 base: Box::new(OptChainBase::Call(OptCall {
1404 span: span!(self, start),
1405 callee,
1406 args,
1407 type_args,
1408 ..Default::default()
1409 })),
1410 }
1411 .into(),
1412 true,
1413 )),
1414 }
1415 } else {
1416 Ok((
1417 CallExpr {
1418 span: span!(self, start),
1419 callee: obj,
1420 args,
1421 ..Default::default()
1422 }
1423 .into(),
1424 true,
1425 ))
1426 };
1427 }
1428
1429 if eat!(self, '.') {
1432 let prop = self.parse_maybe_private_name().map(|e| match e {
1433 Either::Left(p) => MemberProp::PrivateName(p),
1434 Either::Right(i) => MemberProp::Ident(i),
1435 })?;
1436 let span = span!(self, obj.span_lo());
1437 debug_assert_eq!(obj.span_lo(), span.lo());
1438 debug_assert_eq!(prop.span_hi(), span.hi());
1439
1440 let type_args = if self.syntax().typescript() && is!(self, '<') {
1441 self.try_parse_ts_type_args()
1442 } else {
1443 None
1444 };
1445
1446 return Ok((
1447 Box::new(match obj {
1448 callee @ Callee::Import(_) => match prop {
1449 MemberProp::Ident(IdentName { sym, .. }) => {
1450 if !self.ctx().can_be_module {
1451 let span = span!(self, start);
1452 self.emit_err(span, SyntaxError::ImportMetaInScript);
1453 }
1454 match &*sym {
1455 "meta" => MetaPropExpr {
1456 span,
1457 kind: MetaPropKind::ImportMeta,
1458 }
1459 .into(),
1460 _ => {
1461 let args = self.parse_args(true)?;
1462
1463 CallExpr {
1464 span,
1465 callee,
1466 args,
1467 type_args: None,
1468 ..Default::default()
1469 }
1470 .into()
1471 }
1472 }
1473 }
1474 _ => {
1475 unexpected!(self, "meta");
1476 }
1477 },
1478 Callee::Super(obj) => {
1479 if !self.ctx().allow_direct_super
1480 && !self.input.syntax().allow_super_outside_method()
1481 {
1482 syntax_error!(self, self.input.cur_span(), SyntaxError::InvalidSuper);
1483 } else if question_dot_token.is_some() {
1484 if no_call {
1485 syntax_error!(
1486 self,
1487 self.input.cur_span(),
1488 SyntaxError::InvalidSuperCall
1489 );
1490 }
1491 syntax_error!(self, self.input.cur_span(), SyntaxError::InvalidSuper);
1492 } else {
1493 match prop {
1494 MemberProp::Ident(ident) => SuperPropExpr {
1495 span,
1496 obj,
1497 prop: SuperProp::Ident(ident),
1498 }
1499 .into(),
1500 MemberProp::PrivateName(..) => syntax_error!(
1501 self,
1502 self.input.cur_span(),
1503 SyntaxError::InvalidSuperCall
1504 ),
1505 MemberProp::Computed(..) => unreachable!(),
1506 }
1507 }
1508 }
1509 Callee::Expr(obj) => {
1510 let expr = MemberExpr { span, obj, prop };
1511 let expr = if unwrap_ts_non_null(&expr.obj).is_opt_chain()
1512 || question_dot_token.is_some()
1513 {
1514 OptChainExpr {
1515 span: span!(self, start),
1516 optional: question_dot_token.is_some(),
1517 base: Box::new(OptChainBase::Member(expr)),
1518 }
1519 .into()
1520 } else {
1521 expr.into()
1522 };
1523 if let Some(type_args) = type_args {
1524 TsInstantiation {
1525 expr: Box::new(expr),
1526 type_args,
1527 span: span!(self, start),
1528 }
1529 .into()
1530 } else {
1531 expr
1532 }
1533 }
1534 }),
1535 true,
1536 ));
1537 }
1538
1539 match obj {
1540 Callee::Expr(expr) => {
1541 let expr = if let Some(type_args) = type_args {
1542 TsInstantiation {
1543 expr,
1544 type_args,
1545 span: span!(self, start),
1546 }
1547 .into()
1548 } else {
1549 expr
1550 };
1551
1552 if is!(self, '`') {
1554 let ctx = Context {
1555 will_expect_colon_for_cond: false,
1556 ..self.ctx()
1557 };
1558
1559 let tpl = self.with_ctx(ctx).parse_tagged_tpl(expr, None)?;
1560 return Ok((tpl.into(), true));
1561 }
1562
1563 Ok((expr, false))
1564 }
1565 Callee::Super(..) => {
1566 if no_call {
1567 syntax_error!(self, self.input.cur_span(), SyntaxError::InvalidSuperCall);
1568 }
1569 syntax_error!(self, self.input.cur_span(), SyntaxError::InvalidSuper);
1570 }
1571 Callee::Import(..) => {
1572 syntax_error!(self, self.input.cur_span(), SyntaxError::InvalidImport);
1573 }
1574 }
1575 }
1576
1577 #[cfg_attr(feature = "tracing-spans", tracing::instrument(skip_all))]
1579 pub(super) fn parse_lhs_expr(&mut self) -> PResult<Box<Expr>> {
1580 trace_cur!(self, parse_lhs_expr);
1581
1582 let start = cur_pos!(self);
1583
1584 if self.input.syntax().jsx() {
1586 fn into_expr(e: Either<JSXFragment, JSXElement>) -> Box<Expr> {
1587 match e {
1588 Either::Left(l) => l.into(),
1589 Either::Right(r) => r.into(),
1590 }
1591 }
1592 match *cur!(self, true) {
1593 Token::JSXText { .. } => {
1594 return self
1595 .parse_jsx_text()
1596 .map(Lit::JSXText)
1597 .map(Expr::Lit)
1598 .map(Box::new);
1599 }
1600 Token::JSXTagStart => {
1601 return self.parse_jsx_element().map(into_expr);
1602 }
1603 _ => {}
1604 }
1605
1606 if is!(self, '<') && !peeked_is!(self, '!') {
1607 return self.parse_jsx_element().map(into_expr);
1614 }
1615 }
1616
1617 if eat!(self, "super") {
1619 let obj = Callee::Super(Super {
1620 span: span!(self, start),
1621 });
1622 return self.parse_subscripts(obj, false, false);
1623 }
1624 if eat!(self, "import") {
1625 return self.parse_dynamic_import_or_import_meta(start, false);
1626 }
1627
1628 let callee = self.parse_new_expr()?;
1629 return_if_arrow!(self, callee);
1630
1631 let type_args = if self.input.syntax().typescript() && is_one_of!(self, '<', "<<") {
1632 self.try_parse_ts(|p| {
1633 let type_args = p.parse_ts_type_args()?;
1634 if is!(p, '(') {
1635 Ok(Some(type_args))
1636 } else {
1637 Ok(None)
1638 }
1639 })
1640 } else {
1641 None
1642 };
1643
1644 if let Expr::New(ne @ NewExpr { args: None, .. }) = *callee {
1645 if type_args.is_some() {
1648 expect!(self, '(');
1650 }
1651 debug_assert_ne!(
1652 cur!(self, false).ok(),
1653 Some(&tok!('(')),
1654 "parse_new_expr() should eat paren if it exists"
1655 );
1656 return Ok(NewExpr { type_args, ..ne }.into());
1657 }
1658 if is!(self, '(') {
1662 let (callee, is_import) = match callee {
1665 _ if callee.is_ident_ref_to("import") => (
1666 Callee::Import(Import {
1667 span: callee.span(),
1668 phase: Default::default(),
1669 }),
1670 true,
1671 ),
1672 _ => (Callee::Expr(callee), false),
1673 };
1674 let args = self.parse_args(is_import)?;
1675
1676 let call_expr = match callee {
1677 Callee::Expr(e) if unwrap_ts_non_null(&e).is_opt_chain() => OptChainExpr {
1678 span: span!(self, start),
1679 base: Box::new(OptChainBase::Call(OptCall {
1680 span: span!(self, start),
1681 callee: e,
1682 args,
1683 type_args,
1684 ..Default::default()
1685 })),
1686 optional: false,
1687 }
1688 .into(),
1689 _ => CallExpr {
1690 span: span!(self, start),
1691
1692 callee,
1693 args,
1694 type_args,
1695 ..Default::default()
1696 }
1697 .into(),
1698 };
1699
1700 return self.parse_subscripts(Callee::Expr(call_expr), false, false);
1701 }
1702 if type_args.is_some() {
1703 expect!(self, '(');
1705 }
1706
1707 Ok(callee)
1710 }
1711
1712 pub(super) fn parse_for_head_prefix(&mut self) -> PResult<Box<Expr>> {
1713 self.parse_expr()
1714 }
1715
1716 #[cfg_attr(feature = "tracing-spans", tracing::instrument(skip_all))]
1718 pub(super) fn parse_args_or_pats(
1719 &mut self,
1720 ) -> PResult<(Vec<AssignTargetOrSpread>, Option<Span>)> {
1721 self.with_ctx(Context {
1722 will_expect_colon_for_cond: false,
1723 ..self.ctx()
1724 })
1725 .parse_args_or_pats_inner()
1726 }
1727
1728 fn parse_args_or_pats_inner(&mut self) -> PResult<(Vec<AssignTargetOrSpread>, Option<Span>)> {
1729 trace_cur!(self, parse_args_or_pats);
1730
1731 expect!(self, '(');
1732
1733 let mut items = Vec::new();
1734 let mut trailing_comma = None;
1735
1736 while !eof!(self) && !is!(self, ')') {
1739 let is_async = is!(self, "async")
1741 && matches!(
1742 peek!(self),
1743 Some(tok!('(') | tok!("function") | Token::Word(..))
1744 );
1745
1746 let start = cur_pos!(self);
1747 self.state.potential_arrow_start = Some(start);
1748 let modifier_start = start;
1749
1750 let has_modifier = self.eat_any_ts_modifier()?;
1751 let pat_start = cur_pos!(self);
1752
1753 let mut arg = {
1754 if self.input.syntax().typescript()
1755 && (is!(self, IdentRef) || (is!(self, "...") && peeked_is!(self, IdentRef)))
1756 {
1757 let spread = if eat!(self, "...") {
1758 Some(self.input.prev_span())
1759 } else {
1760 None
1761 };
1762
1763 let expr = if spread.is_some() {
1766 self.include_in_expr(true).parse_bin_expr()?
1767 } else {
1768 let mut expr = self.parse_bin_expr()?;
1769
1770 if let Ok(&Token::AssignOp(..)) = cur!(self, false) {
1771 expr = self.finish_assignment_expr(start, expr)?
1772 }
1773
1774 expr
1775 };
1776
1777 ExprOrSpread { spread, expr }
1778 } else {
1779 self.include_in_expr(true).parse_expr_or_spread()?
1780 }
1781 };
1782
1783 let optional = if self.input.syntax().typescript() {
1784 if is!(self, '?') {
1785 if peeked_is!(self, ',')
1786 || peeked_is!(self, ':')
1787 || peeked_is!(self, ')')
1788 || peeked_is!(self, '=')
1789 {
1790 assert_and_bump!(self, '?');
1791 let _ = cur!(self, false);
1792 if arg.spread.is_some() {
1793 self.emit_err(self.input.prev_span(), SyntaxError::TS1047);
1794 }
1795 match *arg.expr {
1796 Expr::Ident(..) => {}
1797 _ => {
1798 syntax_error!(
1799 self,
1800 arg.span(),
1801 SyntaxError::TsBindingPatCannotBeOptional
1802 )
1803 }
1804 }
1805 true
1806 } else if matches!(arg, ExprOrSpread { spread: None, .. }) {
1807 expect!(self, '?');
1808 let test = arg.expr;
1809 let ctx = Context {
1810 in_cond_expr: true,
1811 will_expect_colon_for_cond: true,
1812 include_in_expr: true,
1813 ..self.ctx()
1814 };
1815 let cons = self.with_ctx(ctx).parse_assignment_expr()?;
1816 expect!(self, ':');
1817 let ctx = Context {
1818 in_cond_expr: true,
1819 will_expect_colon_for_cond: false,
1820 ..self.ctx()
1821 };
1822 let alt = self.with_ctx(ctx).parse_assignment_expr()?;
1823
1824 arg = ExprOrSpread {
1825 spread: None,
1826 expr: CondExpr {
1827 span: Span::new(start, alt.span_hi()),
1828
1829 test,
1830 cons,
1831 alt,
1832 }
1833 .into(),
1834 };
1835
1836 false
1837 } else {
1838 false
1839 }
1840 } else {
1841 false
1842 }
1843 } else {
1844 false
1845 };
1846
1847 if optional || (self.input.syntax().typescript() && is!(self, ':')) {
1848 let mut pat = self.reparse_expr_as_pat(PatType::BindingPat, arg.expr)?;
1855 if optional {
1856 match pat {
1857 Pat::Ident(ref mut i) => i.optional = true,
1858 _ => unreachable!(),
1859 }
1860 }
1861 if let Some(span) = arg.spread {
1862 pat = RestPat {
1863 span: span!(self, pat_start),
1864 dot3_token: span,
1865 arg: Box::new(pat),
1866 type_ann: None,
1867 }
1868 .into();
1869 }
1870 match pat {
1871 Pat::Ident(BindingIdent {
1872 id: Ident { ref mut span, .. },
1873 ref mut type_ann,
1874 ..
1875 })
1876 | Pat::Array(ArrayPat {
1877 ref mut type_ann,
1878 ref mut span,
1879 ..
1880 })
1881 | Pat::Object(ObjectPat {
1882 ref mut type_ann,
1883 ref mut span,
1884 ..
1885 })
1886 | Pat::Rest(RestPat {
1887 ref mut type_ann,
1888 ref mut span,
1889 ..
1890 }) => {
1891 let new_type_ann = self.try_parse_ts_type_ann()?;
1892 if new_type_ann.is_some() {
1893 *span = Span::new(pat_start, self.input.prev_span().hi);
1894 }
1895 *type_ann = new_type_ann;
1896 }
1897 Pat::Expr(ref expr) => unreachable!("invalid pattern: Expr({:?})", expr),
1898 Pat::Assign(..) | Pat::Invalid(..) => {
1899 }
1906 }
1907
1908 if eat!(self, '=') {
1909 let right = self.parse_assignment_expr()?;
1910 pat = AssignPat {
1911 span: span!(self, pat_start),
1912 left: Box::new(pat),
1913 right,
1914 }
1915 .into();
1916 }
1917
1918 if has_modifier {
1919 self.emit_err(span!(self, modifier_start), SyntaxError::TS2369);
1920 }
1921
1922 items.push(AssignTargetOrSpread::Pat(pat))
1923 } else {
1924 if has_modifier {
1925 self.emit_err(span!(self, modifier_start), SyntaxError::TS2369);
1926 }
1927
1928 items.push(AssignTargetOrSpread::ExprOrSpread(arg));
1929 }
1930
1931 if eat!(self, "=>") && {
1933 debug_assert_eq!(items.len(), 1);
1934 match items[0] {
1935 AssignTargetOrSpread::ExprOrSpread(ExprOrSpread { ref expr, .. })
1936 | AssignTargetOrSpread::Pat(Pat::Expr(ref expr)) => {
1937 matches!(**expr, Expr::Ident(..))
1938 }
1939 AssignTargetOrSpread::Pat(Pat::Ident(..)) => true,
1940 _ => false,
1941 }
1942 } {
1943 let params: Vec<Pat> = self
1944 .parse_paren_items_as_params(items.clone(), None)?
1945 .into_iter()
1946 .collect();
1947
1948 let body: Box<BlockStmtOrExpr> =
1949 self.parse_fn_body(false, false, true, params.is_simple_parameter_list())?;
1950 let span = span!(self, start);
1951
1952 items.push(AssignTargetOrSpread::ExprOrSpread(ExprOrSpread {
1953 expr: Box::new(
1954 ArrowExpr {
1955 span,
1956 body,
1957 is_async,
1958 is_generator: false,
1959 params,
1960 ..Default::default()
1961 }
1962 .into(),
1963 ),
1964 spread: None,
1965 }));
1966 }
1967
1968 if !is!(self, ')') {
1969 expect!(self, ',');
1970 if is!(self, ')') {
1971 trailing_comma = Some(self.input.prev_span());
1972 }
1973 }
1974 }
1975
1976 expect!(self, ')');
1977 Ok((items, trailing_comma))
1978 }
1979}
1980
1981#[ast_node]
1982pub(in crate::parser) enum AssignTargetOrSpread {
1983 #[tag("ExprOrSpread")]
1984 ExprOrSpread(ExprOrSpread),
1985 #[tag("*")]
1986 Pat(Pat),
1987}
1988
1989impl<I: Tokens> Parser<I> {
1991 fn parse_yield_expr(&mut self) -> PResult<Box<Expr>> {
1992 let start = cur_pos!(self);
1993
1994 assert_and_bump!(self, "yield");
1995 debug_assert!(self.ctx().in_generator);
1996
1997 if self.ctx().in_parameters && !self.ctx().in_function {
2002 syntax_error!(self, self.input.prev_span(), SyntaxError::YieldParamInGen)
2003 }
2004
2005 if is!(self, ';')
2006 || (!is!(self, '<')
2007 && !is!(self, '*')
2008 && !is!(self, '/')
2009 && !is!(self, "/=")
2010 && !cur!(self, false)
2011 .map(|t| t.kind().starts_expr())
2012 .unwrap_or(true))
2013 {
2014 Ok(YieldExpr {
2015 span: span!(self, start),
2016 arg: None,
2017 delegate: false,
2018 }
2019 .into())
2020 } else {
2021 let has_star = eat!(self, '*');
2022 let err_span = span!(self, start);
2023
2024 let arg = self.parse_assignment_expr().map_err(|err| {
2025 Error::new(
2026 err.span(),
2027 SyntaxError::WithLabel {
2028 inner: Box::new(err),
2029 span: err_span,
2030 note: "Tried to parse an argument of yield",
2031 },
2032 )
2033 })?;
2034
2035 Ok(YieldExpr {
2036 span: span!(self, start),
2037 arg: Some(arg),
2038 delegate: has_star,
2039 }
2040 .into())
2041 }
2042 }
2043
2044 fn at_possible_async(&mut self, expr: &Expr) -> PResult<bool> {
2045 Ok(self.state.potential_arrow_start == Some(expr.span_lo())
2048 && expr.is_ident_ref_to("async"))
2049 }
2050
2051 pub(super) fn parse_lit(&mut self) -> PResult<Lit> {
2053 let start = cur_pos!(self);
2054
2055 let v = match cur!(self, true) {
2056 Word(Word::Null) => {
2057 bump!(self);
2058 let span = span!(self, start);
2059 Lit::Null(Null { span })
2060 }
2061 Word(Word::True) | Word(Word::False) => {
2062 let value = is!(self, "true");
2063 bump!(self);
2064 let span = span!(self, start);
2065
2066 Lit::Bool(Bool { span, value })
2067 }
2068 Token::Str { .. } => match bump!(self) {
2069 Token::Str { value, raw } => Lit::Str(Str {
2070 span: span!(self, start),
2071 value,
2072 raw: Some(raw),
2073 }),
2074 _ => unreachable!(),
2075 },
2076 Token::Num { .. } => match bump!(self) {
2077 Token::Num { value, raw } => Lit::Num(Number {
2078 span: span!(self, start),
2079 value,
2080 raw: Some(raw),
2081 }),
2082 _ => unreachable!(),
2083 },
2084 Token::BigInt { .. } => match bump!(self) {
2085 Token::BigInt { value, raw } => Lit::BigInt(BigInt {
2086 span: span!(self, start),
2087 value,
2088 raw: Some(raw),
2089 }),
2090 _ => unreachable!(),
2091 },
2092 token => unreachable!("parse_lit should not be called for {:?}", token),
2093 };
2094 Ok(v)
2095 }
2096
2097 pub(super) fn parse_dynamic_import_or_import_meta(
2098 &mut self,
2099 start: BytePos,
2100 no_call: bool,
2101 ) -> PResult<Box<Expr>> {
2102 if eat!(self, '.') {
2103 self.state.found_module_item = true;
2104
2105 let ident = self.parse_ident_name()?;
2106
2107 match &*ident.sym {
2108 "meta" => {
2109 let span = span!(self, start);
2110 if !self.ctx().can_be_module {
2111 self.emit_err(span, SyntaxError::ImportMetaInScript);
2112 }
2113 let expr = MetaPropExpr {
2114 span,
2115 kind: MetaPropKind::ImportMeta,
2116 };
2117 self.parse_subscripts(Callee::Expr(expr.into()), no_call, false)
2118 }
2119 "source" => self.parse_dynamic_import_call(start, no_call, ImportPhase::Source),
2120 _ => unexpected!(self, "meta"),
2124 }
2125 } else {
2126 self.parse_dynamic_import_call(start, no_call, ImportPhase::Evaluation)
2127 }
2128 }
2129
2130 fn parse_dynamic_import_call(
2131 &mut self,
2132 start: BytePos,
2133 no_call: bool,
2134 phase: ImportPhase,
2135 ) -> PResult<Box<Expr>> {
2136 let import = Callee::Import(Import {
2137 span: span!(self, start),
2138 phase,
2139 });
2140
2141 self.parse_subscripts(import, no_call, false)
2142 }
2143
2144 pub(super) fn check_assign_target(&mut self, expr: &Expr, deny_call: bool) {
2145 if !expr.is_valid_simple_assignment_target(self.ctx().strict) {
2146 self.emit_err(expr.span(), SyntaxError::TS2406);
2147 }
2148
2149 if self.input.syntax().typescript() && self.syntax().early_errors() {
2151 let is_eval_or_arguments = match expr {
2152 Expr::Ident(i) => i.is_reserved_in_strict_bind(),
2153 _ => false,
2154 };
2155
2156 if is_eval_or_arguments {
2157 self.emit_strict_mode_err(expr.span(), SyntaxError::TS1100);
2158 }
2159
2160 fn should_deny(e: &Expr, deny_call: bool) -> bool {
2161 match e {
2162 Expr::Lit(..) => false,
2163 Expr::Call(..) => deny_call,
2164 Expr::Bin(..) => false,
2165 Expr::Paren(ref p) => should_deny(&p.expr, deny_call),
2166
2167 _ => true,
2168 }
2169 }
2170
2171 if !is_eval_or_arguments
2175 && !expr.is_valid_simple_assignment_target(self.ctx().strict)
2176 && should_deny(expr, deny_call)
2177 {
2178 self.emit_err(expr.span(), SyntaxError::TS2406);
2179 }
2180 }
2181 }
2182
2183 fn is_start_of_left_hand_side_expr(&mut self) -> PResult<bool> {
2184 Ok(is_one_of!(
2185 self, "this", "super", "null", "true", "false", Num, BigInt, Str, '`', '(', '[', '{',
2186 "function", "class", "new", Regex, IdentRef
2187 ) || (is!(self, "import")
2188 && (peeked_is!(self, '(') || peeked_is!(self, '<') || peeked_is!(self, '.'))))
2189 }
2190
2191 pub(super) fn is_start_of_expr(&mut self) -> PResult<bool> {
2192 Ok(self.is_start_of_left_hand_side_expr()?
2193 || is_one_of!(
2194 self, '+', '-', '~', '!', "delete", "typeof", "void", "++", "--", '<', "await",
2195 "yield"
2196 )
2197 || (is!(self, '#') && peeked_is!(self, IdentName)))
2198 }
2199}
2200
2201fn unwrap_ts_non_null(mut expr: &Expr) -> &Expr {
2202 while let Expr::TsNonNull(ts_non_null) = expr {
2203 expr = &ts_non_null.expr;
2204 }
2205
2206 expr
2207}