swc_ecma_parser/parser/
expr.rs

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    ///`parseMaybeAssign` (overridden)
39    #[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            // Note: When the JSX plugin is on, type assertions (`<T> x`) aren't valid
45            // syntax.
46
47            let cur_context = self.input.token_context().current();
48            debug_assert_eq!(cur_context, Some(TokenContext::JSXOpeningTag));
49            // Only time j_oTag is pushed is right after j_expr.
50            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    /// Parse an assignment expression. This includes applications of
76    /// operators like `+=`.
77    ///
78    /// `parseMaybeAssign`
79    #[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        // Try to parse conditional expression.
140        let cond = self.parse_cond_expr()?;
141
142        return_if_arrow!(self, cond);
143
144        match *cond {
145            // if cond is conditional expression but not left-hand-side expression,
146            // just return it.
147            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                    // It is an early Reference Error if IsValidSimpleAssignmentTarget of
170                    // LeftHandSideExpression is false.
171                    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                    // TODO
188                    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                    // TODO:
202                    left,
203                    right,
204                }
205                .into())
206            }
207            _ => Ok(cond),
208        }
209    }
210
211    /// Spec: 'ConditionalExpression'
212    #[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    /// Parse a primary expression or arrow function
250    #[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                        // handle `async function` expression
278                        return self.parse_async_fn_expr();
279                    }
280
281                    if can_be_arrow && self.input.syntax().typescript() && peeked_is!(self, '<') {
282                        // try parsing `async<T>() => {}`
283                        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                // Handle FunctionExpression and GeneratorExpression
315                tok!("function") => {
316                    return self.parse_fn_expr();
317                }
318
319                // Literals
320                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                // Regexp
330                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                                            // https://tc39.es/ecma262/#sec-isvalidregularexpressionliteral
347                                            'd' | 'g' | 'i' | 'm' | 's' | 'u' | 'v' | 'y' => flag,
348                                            _ => '\u{0000}', // special marker for unknown flags
349                                        };
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                    // parse template literal
379                    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                // see https://github.com/tc39/ecma262/issues/2034
415                // ```js
416                // for(async of
417                // for(async of x);
418                // for(async of =>{};;);
419                // ```
420                if ctx.expr_ctx.for_loop_init && is!(self, "of") && !peeked_is!(self, "=>") {
421                    // ```spec https://tc39.es/ecma262/#prod-ForInOfStatement
422                    // for ( [lookahead ∉ { let, async of }] LeftHandSideExpression[?Yield, ?Await] of AssignmentExpression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return]
423                    // [+Await] for await ( [lookahead ≠ let] LeftHandSideExpression[?Yield, ?Await] of AssignmentExpression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return]
424                    // ```
425
426                    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                    // async as type
436                    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                // async a => body
446                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    /// `is_new_expr`: true iff we are parsing production 'NewExpression'.
537    #[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            // 'NewExpression' allows new call without paren.
574            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                        // This will fail
614                        expect!(p, '(');
615                    }
616                    Ok(Some(args))
617                })
618            } else {
619                None
620            };
621
622            if !is_new_expr || is!(self, '(') {
623                // Parsed with 'MemberExpression' production.
624                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                // We should parse subscripts for MemberExpression.
638                // Because it's left recursive.
639                return self.parse_subscripts(new_expr, true, false);
640            }
641
642            // Parsed with 'NewExpression' production.
643
644            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    /// Parse `NewExpression`.
687    /// This includes `MemberExpression`.
688    #[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    /// Parse `Arguments[Yield, Await]`
696    #[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                    // Handle trailing comma.
718                    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    /// AssignmentExpression[+In, ?Yield, ?Await]
740    /// ...AssignmentExpression[+In, ?Yield, ?Await]
741    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    /// Parse paren expression or arrow function expression.
769    #[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        // At this point, we can't know if it's parenthesized
780        // expression or head of arrow function.
781        // But as all patterns of javascript is subset of
782        // expressions, we can parse both as expression.
783
784        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        // This is slow path. We handle arrow in conditional expression.
800        if self.syntax().typescript() && self.ctx().in_cond_expr && is!(self, ':') {
801            // TODO: Remove clone
802            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        // we parse arrow function at here, to handle it efficiently.
860        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                    // ) is required
897                    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                        // ; is required
903                        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            // If there's no arrow function, we have to check there's no
912            // AssignProp in lhs to check against assignment in object literals
913            // like (a, {b = 1});
914            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            // It's a call expression
940            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        // It was not head of arrow function.
952
953        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        // TODO: Verify that invalid expression like {a = 1} does not exists.
962
963        // ParenthesizedExpression cannot contain spread.
964        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            // span of sequence expression should not include '(', ')'
993            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    /// returned bool is true if this method should be called again.
1124    #[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                // tsTryParseAndCatch is expensive, so avoid if not necessary.
1172                // There are number of things we are going to "maybe" parse, like type arguments
1173                // on tagged template expressions. If any of them fail, walk it back and
1174                // continue.
1175
1176                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                        // Almost certainly this is a generic async function `async <T>() => ...
1190                        // But it might be a call with a type argument `async<T>();`
1191                        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                        // possibleAsync always false here, because we would have handled it
1201                        // above. (won't be any undefined arguments)
1202                        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        // $obj[name()]
1293        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        // member expression
1430        // $obj.name
1431        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                // MemberExpression[?Yield, ?Await] TemplateLiteral[?Yield, ?Await, +Tagged]
1553                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    /// Parse call, dot, and `[]`-subscript expressions.
1578    #[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        // parse jsx
1585        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                // In case we encounter an lt token here it will always be the start of
1608                // jsx as the lt sign is not allowed in places that expect an expression
1609
1610                // FIXME:
1611                // self.finishToken(tt.jsxTagStart);
1612
1613                return self.parse_jsx_element().map(into_expr);
1614            }
1615        }
1616
1617        // `super()` can't be handled from parse_new_expr()
1618        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 this is parsed using 'NewExpression' rule, just return it.
1646            // Because it's not left-recursive.
1647            if type_args.is_some() {
1648                // This fails with `expected (`
1649                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        // 'CallExpr' rule contains 'MemberExpr (...)',
1659        // and 'MemberExpr' rule contains 'new MemberExpr (...)'
1660
1661        if is!(self, '(') {
1662            // This is parsed using production MemberExpression,
1663            // which is left-recursive.
1664            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            // This fails
1704            expect!(self, '(');
1705        }
1706
1707        // This is parsed using production 'NewExpression', which contains
1708        // 'MemberExpression'
1709        Ok(callee)
1710    }
1711
1712    pub(super) fn parse_for_head_prefix(&mut self) -> PResult<Box<Expr>> {
1713        self.parse_expr()
1714    }
1715
1716    // Returns (args_or_pats, trailing_comma)
1717    #[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        // TODO(kdy1): optimize (once we parsed a pattern, we can parse everything else
1737        // as a pattern instead of reparsing)
1738        while !eof!(self) && !is!(self, ')') {
1739            // https://github.com/swc-project/swc/issues/410
1740            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                    // At here, we use parse_bin_expr() instead of parse_assignment_expr()
1764                    // because `x?: number` should not be parsed as a conditional expression
1765                    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                // TODO: `async(...args?: any[]) : any => {}`
1849                //
1850                // if self.input.syntax().typescript() && optional && arg.spread.is_some() {
1851                //     self.emit_err(self.input.prev_span(), SyntaxError::TS1047)
1852                // }
1853
1854                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                        // We don't have to panic here.
1900                        // See: https://github.com/swc-project/swc/issues/1170
1901                        //
1902                        // Also, as an exact error is added to the errors while
1903                        // creating `Invalid`, we don't have to emit a new
1904                        // error.
1905                    }
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            // https://github.com/swc-project/swc/issues/433
1932            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
1989/// simple leaf methods.
1990impl<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        // Spec says
1998        // YieldExpression cannot be used within the FormalParameters of a generator
1999        // function because any expressions that are part of FormalParameters are
2000        // evaluated before the resulting generator object is in a resumable state.
2001        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        // TODO(kdy1): !this.state.containsEsc &&
2046
2047        Ok(self.state.potential_arrow_start == Some(expr.span_lo())
2048            && expr.is_ident_ref_to("async"))
2049    }
2050
2051    /// 12.2.5 Array Initializer
2052    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                // TODO: The proposal doesn't mention import.defer yet because it was
2121                // pending on a decision for import.source. Wait to enable it until it's
2122                // included in the proposal.
2123                _ => 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        // We follow behavior of tsc
2150        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            // It is an early Reference Error if LeftHandSideExpression is neither
2172            // an ObjectLiteral nor an ArrayLiteral and
2173            // IsValidSimpleAssignmentTarget of LeftHandSideExpression is false.
2174            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}