swc_ecma_parser/parser/
class_and_fn.rs

1use swc_atoms::atom;
2use swc_common::{BytePos, Span, Spanned};
3use swc_ecma_ast::*;
4
5use crate::{
6    error::SyntaxError,
7    input::Tokens,
8    lexer::Token,
9    parser::{
10        state::State,
11        util::{IsInvalidClassName, IsSimpleParameterList},
12    },
13    Context, PResult, Parser,
14};
15
16struct MakeMethodArgs {
17    start: BytePos,
18    accessibility: Option<Accessibility>,
19    is_abstract: bool,
20    static_token: Option<Span>,
21    decorators: Vec<Decorator>,
22    is_optional: bool,
23    is_override: bool,
24    key: Key,
25    kind: MethodKind,
26    is_async: bool,
27    is_generator: bool,
28}
29
30impl<I: Tokens> Parser<I> {
31    /// If `required` is `true`, this never returns `None`.
32    fn parse_maybe_opt_binding_ident(
33        &mut self,
34        required: bool,
35        disallow_let: bool,
36    ) -> PResult<Option<Ident>> {
37        if required {
38            self.parse_binding_ident(disallow_let)
39                .map(|v| v.id)
40                .map(Some)
41        } else {
42            self.parse_opt_binding_ident(disallow_let)
43                .map(|v| v.map(|v| v.id))
44        }
45    }
46
47    fn parse_maybe_decorator_args(&mut self, expr: Box<Expr>) -> PResult<Box<Expr>> {
48        let type_args = if self.input().syntax().typescript() && self.input().is(Token::Lt) {
49            let ret = self.parse_ts_type_args()?;
50            self.assert_and_bump(Token::Gt);
51            Some(ret)
52        } else {
53            None
54        };
55
56        if type_args.is_none() && !self.input().is(Token::LParen) {
57            return Ok(expr);
58        }
59
60        let args = self.parse_args(false)?;
61        Ok(CallExpr {
62            span: self.span(expr.span_lo()),
63            callee: Callee::Expr(expr),
64            args,
65            ..Default::default()
66        }
67        .into())
68    }
69
70    pub(crate) fn parse_decorators(&mut self, allow_export: bool) -> PResult<Vec<Decorator>> {
71        if !self.syntax().decorators() {
72            return Ok(Vec::new());
73        }
74        trace_cur!(self, parse_decorators);
75
76        let mut decorators = Vec::new();
77        let start = self.cur_pos();
78
79        while self.input().is(Token::At) {
80            decorators.push(self.parse_decorator()?);
81        }
82        if decorators.is_empty() {
83            return Ok(decorators);
84        }
85
86        if self.input().is(Token::Export) {
87            if !self.ctx().contains(Context::InClass)
88                && !self.ctx().contains(Context::InFunction)
89                && !allow_export
90            {
91                syntax_error!(self, self.input().cur_span(), SyntaxError::ExportNotAllowed);
92            }
93
94            if !self.ctx().contains(Context::InClass)
95                && !self.ctx().contains(Context::InFunction)
96                && !self.syntax().decorators_before_export()
97            {
98                syntax_error!(self, self.span(start), SyntaxError::DecoratorOnExport);
99            }
100        } else if !self.input().is(Token::Class) {
101            // syntax_error!(p, self.span(start),
102            // SyntaxError::InvalidLeadingDecorator)
103        }
104
105        Ok(decorators)
106    }
107
108    fn parse_decorator(&mut self) -> PResult<Decorator> {
109        let start = self.cur_pos();
110        trace_cur!(self, parse_decorator);
111
112        self.assert_and_bump(Token::At);
113
114        let expr = if self.input_mut().eat(Token::LParen) {
115            let expr = self.parse_expr()?;
116            expect!(self, Token::RParen);
117            expr
118        } else {
119            let expr = self
120                .parse_ident(false, false)
121                .map(Expr::from)
122                .map(Box::new)?;
123
124            self.parse_subscripts(Callee::Expr(expr), false, true)?
125        };
126
127        let expr = self.parse_maybe_decorator_args(expr)?;
128
129        Ok(Decorator {
130            span: self.span(start),
131            expr,
132        })
133    }
134
135    pub(crate) fn parse_access_modifier(&mut self) -> PResult<Option<Accessibility>> {
136        Ok(self
137            .parse_ts_modifier(&["public", "protected", "private", "in", "out"], false)?
138            .and_then(|s| match s {
139                "public" => Some(Accessibility::Public),
140                "protected" => Some(Accessibility::Protected),
141                "private" => Some(Accessibility::Private),
142                other => {
143                    self.emit_err(self.input().prev_span(), SyntaxError::TS1274(other.into()));
144                    None
145                }
146            }))
147    }
148
149    fn parse_super_class(&mut self) -> PResult<(Box<Expr>, Option<Box<TsTypeParamInstantiation>>)> {
150        let super_class = self.parse_lhs_expr()?;
151        match *super_class {
152            Expr::TsInstantiation(TsInstantiation {
153                expr, type_args, ..
154            }) => Ok((expr, Some(type_args))),
155            _ => {
156                // We still need to parse TS type arguments,
157                // because in some cases "super class" returned by `parse_lhs_expr`
158                // may not include `TsExprWithTypeArgs`
159                // but it's a super class with type params, for example, in JSX.
160                if self.syntax().typescript() && self.input().is(Token::Lt) {
161                    let ret = self.parse_ts_type_args()?;
162                    self.assert_and_bump(Token::Gt);
163                    Ok((super_class, Some(ret)))
164                } else {
165                    Ok((super_class, None))
166                }
167            }
168        }
169    }
170
171    fn is_class_method(&mut self) -> bool {
172        let cur = self.input().cur();
173        cur == Token::LParen
174            || (self.input().syntax().typescript()
175                && (cur == Token::Lt || cur == Token::JSXTagStart))
176    }
177
178    fn is_class_property(&mut self, asi: bool) -> bool {
179        let cur = self.input().cur();
180        (self.input().syntax().typescript() && (cur == Token::Bang || cur == Token::Colon))
181            || (cur == Token::Eq || cur == Token::RBrace)
182            || if asi {
183                self.is_general_semi()
184            } else {
185                self.input().is(Token::Semi)
186            }
187    }
188
189    fn parse_class_prop_name(&mut self) -> PResult<Key> {
190        if self.input().is(Token::Hash) {
191            let name = self.parse_private_name()?;
192            if name.name == "constructor" {
193                self.emit_err(name.span, SyntaxError::PrivateConstructor);
194            }
195            Ok(Key::Private(name))
196        } else {
197            self.parse_prop_name().map(Key::Public)
198        }
199    }
200
201    /// `parse_args` closure should not eat '(' or ')'.
202    pub(crate) fn parse_fn_args_body<F>(
203        &mut self,
204        decorators: Vec<Decorator>,
205        start: BytePos,
206        parse_args: F,
207        is_async: bool,
208        is_generator: bool,
209    ) -> PResult<Box<Function>>
210    where
211        F: FnOnce(&mut Self) -> PResult<Vec<Param>>,
212    {
213        trace_cur!(self, parse_fn_args_body);
214        let f = |p: &mut Self| {
215            let type_params = if p.syntax().typescript() {
216                p.in_type(|p| {
217                    trace_cur!(p, parse_fn_args_body__type_params);
218
219                    Ok(
220                        if p.input().is(Token::Lt) || p.input().is(Token::JSXTagStart) {
221                            Some(p.parse_ts_type_params(false, true)?)
222                        } else {
223                            None
224                        },
225                    )
226                })?
227            } else {
228                None
229            };
230
231            expect!(p, Token::LParen);
232
233            let parse_args_with_generator_ctx = |p: &mut Self| {
234                if is_generator {
235                    p.do_inside_of_context(Context::InGenerator, parse_args)
236                } else {
237                    p.do_outside_of_context(Context::InGenerator, parse_args)
238                }
239            };
240
241            let params = p.do_inside_of_context(Context::InParameters, |p| {
242                p.do_outside_of_context(Context::InFunction, |p| {
243                    if is_async {
244                        p.do_inside_of_context(Context::InAsync, parse_args_with_generator_ctx)
245                    } else {
246                        p.do_outside_of_context(Context::InAsync, parse_args_with_generator_ctx)
247                    }
248                })
249            })?;
250
251            expect!(p, Token::RParen);
252
253            // typescript extension
254            let return_type = if p.syntax().typescript() && p.input().is(Token::Colon) {
255                p.parse_ts_type_or_type_predicate_ann(Token::Colon)
256                    .map(Some)?
257            } else {
258                None
259            };
260
261            let body: Option<_> = p.parse_fn_block_body(
262                is_async,
263                is_generator,
264                false,
265                params.is_simple_parameter_list(),
266            )?;
267
268            if p.syntax().typescript() && body.is_none() {
269                // Declare functions cannot have assignment pattern in parameters
270                for param in &params {
271                    // TODO: Search deeply for assignment pattern using a Visitor
272
273                    let span = match &param.pat {
274                        Pat::Assign(ref p) => Some(p.span()),
275                        _ => None,
276                    };
277
278                    if let Some(span) = span {
279                        p.emit_err(span, SyntaxError::TS2371)
280                    }
281                }
282            }
283
284            Ok(Box::new(Function {
285                span: p.span(start),
286                decorators,
287                type_params,
288                params,
289                body,
290                is_async,
291                is_generator,
292                return_type,
293                ctxt: Default::default(),
294            }))
295        };
296
297        let f_with_generator_ctx = |p: &mut Self| {
298            if is_generator {
299                p.do_inside_of_context(Context::InGenerator, f)
300            } else {
301                p.do_outside_of_context(Context::InGenerator, f)
302            }
303        };
304
305        if is_async {
306            self.do_inside_of_context(Context::InAsync, f_with_generator_ctx)
307        } else {
308            self.do_outside_of_context(Context::InAsync, f_with_generator_ctx)
309        }
310    }
311
312    pub(crate) fn parse_async_fn_expr(&mut self) -> PResult<Box<Expr>> {
313        let start = self.cur_pos();
314        expect!(self, Token::Async);
315        self.parse_fn(None, Some(start), Vec::new())
316    }
317
318    /// Parse function expression
319    pub(crate) fn parse_fn_expr(&mut self) -> PResult<Box<Expr>> {
320        self.parse_fn(None, None, Vec::new())
321    }
322
323    pub(crate) fn parse_async_fn_decl(&mut self, decorators: Vec<Decorator>) -> PResult<Decl> {
324        let start = self.cur_pos();
325        expect!(self, Token::Async);
326        self.parse_fn(None, Some(start), decorators)
327    }
328
329    pub(crate) fn parse_fn_decl(&mut self, decorators: Vec<Decorator>) -> PResult<Decl> {
330        self.parse_fn(None, None, decorators)
331    }
332
333    pub(crate) fn parse_default_async_fn(
334        &mut self,
335        start: BytePos,
336        decorators: Vec<Decorator>,
337    ) -> PResult<ExportDefaultDecl> {
338        let start_of_async = self.cur_pos();
339        expect!(self, Token::Async);
340        self.parse_fn(Some(start), Some(start_of_async), decorators)
341    }
342
343    pub(crate) fn parse_default_fn(
344        &mut self,
345        start: BytePos,
346        decorators: Vec<Decorator>,
347    ) -> PResult<ExportDefaultDecl> {
348        self.parse_fn(Some(start), None, decorators)
349    }
350
351    fn parse_fn_inner(
352        &mut self,
353        _start_of_output_type: Option<BytePos>,
354        start_of_async: Option<BytePos>,
355        decorators: Vec<Decorator>,
356        is_fn_expr: bool,
357        is_ident_required: bool,
358    ) -> PResult<(Option<Ident>, Box<Function>)> {
359        let start = start_of_async.unwrap_or_else(|| self.cur_pos());
360        self.assert_and_bump(Token::Function);
361        let is_async = start_of_async.is_some();
362
363        let is_generator = self.input_mut().eat(Token::Asterisk);
364
365        let ident = if is_fn_expr {
366            let f_with_generator_context = |p: &mut Self| {
367                if is_generator {
368                    p.do_inside_of_context(Context::InGenerator, |p| {
369                        p.parse_maybe_opt_binding_ident(is_ident_required, false)
370                    })
371                } else {
372                    p.do_outside_of_context(Context::InGenerator, |p| {
373                        p.parse_maybe_opt_binding_ident(is_ident_required, false)
374                    })
375                }
376            };
377
378            self.do_outside_of_context(
379                Context::AllowDirectSuper.union(Context::InClassField),
380                |p| {
381                    if is_async {
382                        p.do_inside_of_context(Context::InAsync, f_with_generator_context)
383                    } else {
384                        p.do_outside_of_context(Context::InAsync, f_with_generator_context)
385                    }
386                },
387            )?
388        } else {
389            // function declaration does not change context for `BindingIdentifier`.
390            self.do_outside_of_context(
391                Context::AllowDirectSuper.union(Context::InClassField),
392                |p| p.parse_maybe_opt_binding_ident(is_ident_required, false),
393            )?
394        };
395
396        self.do_outside_of_context(
397            Context::AllowDirectSuper
398                .union(Context::InClassField)
399                .union(Context::WillExpectColonForCond),
400            |p| {
401                let f = p.parse_fn_args_body(
402                    decorators,
403                    start,
404                    Self::parse_formal_params,
405                    is_async,
406                    is_generator,
407                )?;
408                if is_fn_expr && f.body.is_none() {
409                    unexpected!(p, "{");
410                }
411                Ok((ident, f))
412            },
413        )
414    }
415
416    fn parse_fn<T>(
417        &mut self,
418        start_of_output_type: Option<BytePos>,
419        start_of_async: Option<BytePos>,
420        decorators: Vec<Decorator>,
421    ) -> PResult<T>
422    where
423        T: OutputType,
424    {
425        let start = start_of_async.unwrap_or_else(|| self.cur_pos());
426        let (ident, f) = self.parse_fn_inner(
427            start_of_output_type,
428            start_of_async,
429            decorators,
430            T::is_fn_expr(),
431            T::IS_IDENT_REQUIRED,
432        )?;
433
434        match T::finish_fn(self.span(start_of_output_type.unwrap_or(start)), ident, f) {
435            Ok(v) => Ok(v),
436            Err(kind) => syntax_error!(self, kind),
437        }
438    }
439
440    pub(crate) fn parse_class_decl(
441        &mut self,
442        start: BytePos,
443        class_start: BytePos,
444        decorators: Vec<Decorator>,
445        is_abstract: bool,
446    ) -> PResult<Decl> {
447        self.parse_class(start, class_start, decorators, is_abstract)
448    }
449
450    pub(crate) fn parse_class_expr(
451        &mut self,
452        start: BytePos,
453        decorators: Vec<Decorator>,
454    ) -> PResult<Box<Expr>> {
455        self.parse_class(start, start, decorators, false)
456    }
457
458    pub(crate) fn parse_default_class(
459        &mut self,
460        start: BytePos,
461        class_start: BytePos,
462        decorators: Vec<Decorator>,
463        is_abstract: bool,
464    ) -> PResult<ExportDefaultDecl> {
465        self.parse_class(start, class_start, decorators, is_abstract)
466    }
467
468    fn make_method<F>(
469        &mut self,
470        parse_args: F,
471        MakeMethodArgs {
472            start,
473            accessibility,
474            is_abstract,
475            static_token,
476            decorators,
477            is_optional,
478            is_override,
479            key,
480            kind,
481            is_async,
482            is_generator,
483        }: MakeMethodArgs,
484    ) -> PResult<ClassMember>
485    where
486        F: FnOnce(&mut Self) -> PResult<Vec<Param>>,
487    {
488        trace_cur!(self, make_method);
489
490        let is_static = static_token.is_some();
491        let function = self.do_inside_of_context(Context::AllowDirectSuper, |p| {
492            p.do_outside_of_context(Context::InClassField, |p| {
493                p.parse_fn_args_body(decorators, start, parse_args, is_async, is_generator)
494            })
495        })?;
496
497        match kind {
498            MethodKind::Getter | MethodKind::Setter
499                if self.input().syntax().typescript()
500                    && self.input().target() == EsVersion::Es3 =>
501            {
502                self.emit_err(key.span(), SyntaxError::TS1056);
503            }
504            _ => {}
505        }
506
507        match key {
508            Key::Private(key) => {
509                let span = self.span(start);
510                if accessibility.is_some() {
511                    self.emit_err(span.with_hi(key.span_hi()), SyntaxError::TS18010);
512                }
513
514                Ok(PrivateMethod {
515                    span,
516
517                    accessibility,
518                    is_abstract,
519                    is_optional,
520                    is_override,
521
522                    is_static,
523                    key,
524                    function,
525                    kind,
526                }
527                .into())
528            }
529            Key::Public(key) => {
530                let span = self.span(start);
531                if is_abstract && function.body.is_some() {
532                    self.emit_err(span, SyntaxError::TS1245)
533                }
534                Ok(ClassMethod {
535                    span,
536
537                    accessibility,
538                    is_abstract,
539                    is_optional,
540                    is_override,
541
542                    is_static,
543                    key,
544                    function,
545                    kind,
546                }
547                .into())
548            }
549            #[cfg(swc_ast_unknown)]
550            _ => unreachable!(),
551        }
552    }
553
554    pub(crate) fn parse_fn_block_or_expr_body(
555        &mut self,
556        is_async: bool,
557        is_generator: bool,
558        is_arrow_function: bool,
559        is_simple_parameter_list: bool,
560    ) -> PResult<Box<BlockStmtOrExpr>> {
561        self.parse_fn_body(
562            is_async,
563            is_generator,
564            is_arrow_function,
565            is_simple_parameter_list,
566            |p, is_simple_parameter_list| {
567                if p.input().is(Token::LBrace) {
568                    p.parse_block(false)
569                        .map(|block_stmt| {
570                            if !is_simple_parameter_list {
571                                if let Some(span) = has_use_strict(&block_stmt) {
572                                    p.emit_err(span, SyntaxError::IllegalLanguageModeDirective);
573                                }
574                            }
575                            BlockStmtOrExpr::BlockStmt(block_stmt)
576                        })
577                        .map(Box::new)
578                } else {
579                    p.parse_assignment_expr()
580                        .map(BlockStmtOrExpr::Expr)
581                        .map(Box::new)
582                }
583            },
584        )
585    }
586
587    fn parse_fn_body<T>(
588        &mut self,
589        is_async: bool,
590        is_generator: bool,
591        is_arrow_function: bool,
592        is_simple_parameter_list: bool,
593        f: impl FnOnce(&mut Self, bool) -> PResult<T>,
594    ) -> PResult<T> {
595        if self.ctx().contains(Context::InDeclare)
596            && self.syntax().typescript()
597            && self.input().is(Token::LBrace)
598        {
599            //            self.emit_err(
600            //                self.ctx().span_of_fn_name.expect("we are not in function"),
601            //                SyntaxError::TS1183,
602            //            );
603            self.emit_err(self.input().cur_span(), SyntaxError::TS1183);
604        }
605
606        let f_with_generator_context = |p: &mut Self| {
607            let f_with_inside_non_arrow_fn_scope = |p: &mut Self| {
608                let f_with_new_state = |p: &mut Self| {
609                    let mut p = p.with_state(State::default());
610                    f(&mut p, is_simple_parameter_list)
611                };
612
613                if is_arrow_function && !p.ctx().contains(Context::InsideNonArrowFunctionScope) {
614                    p.do_outside_of_context(Context::InsideNonArrowFunctionScope, f_with_new_state)
615                } else {
616                    p.do_inside_of_context(Context::InsideNonArrowFunctionScope, f_with_new_state)
617                }
618            };
619
620            if is_generator {
621                p.do_inside_of_context(Context::InGenerator, f_with_inside_non_arrow_fn_scope)
622            } else {
623                p.do_outside_of_context(Context::InGenerator, f_with_inside_non_arrow_fn_scope)
624            }
625        };
626
627        self.do_inside_of_context(Context::InFunction, |p| {
628            p.do_outside_of_context(
629                Context::InStaticBlock
630                    .union(Context::IsBreakAllowed)
631                    .union(Context::IsContinueAllowed)
632                    .union(Context::TopLevel),
633                |p| {
634                    if is_async {
635                        p.do_inside_of_context(Context::InAsync, f_with_generator_context)
636                    } else {
637                        p.do_outside_of_context(Context::InAsync, f_with_generator_context)
638                    }
639                },
640            )
641        })
642    }
643
644    pub(super) fn parse_fn_block_body(
645        &mut self,
646        is_async: bool,
647        is_generator: bool,
648        is_arrow_function: bool,
649        is_simple_parameter_list: bool,
650    ) -> PResult<Option<BlockStmt>> {
651        self.parse_fn_body(
652            is_async,
653            is_generator,
654            is_arrow_function,
655            is_simple_parameter_list,
656            |p, is_simple_parameter_list| {
657                // allow omitting body and allow placing `{` on next line
658                if p.input().syntax().typescript()
659                    && !p.input().is(Token::LBrace)
660                    && p.eat_general_semi()
661                {
662                    return Ok(None);
663                }
664                p.allow_in_expr(|p| p.parse_block(true)).map(|block_stmt| {
665                    if !is_simple_parameter_list {
666                        if let Some(span) = has_use_strict(&block_stmt) {
667                            p.emit_err(span, SyntaxError::IllegalLanguageModeDirective);
668                        }
669                    }
670                    Some(block_stmt)
671                })
672            },
673        )
674    }
675
676    fn make_property(
677        &mut self,
678        start: BytePos,
679        decorators: Vec<Decorator>,
680        accessibility: Option<Accessibility>,
681        key: Key,
682        is_static: bool,
683        accessor_token: Option<Span>,
684        is_optional: bool,
685        readonly: bool,
686        declare: bool,
687        is_abstract: bool,
688        is_override: bool,
689    ) -> PResult<ClassMember> {
690        if is_constructor(&key) {
691            syntax_error!(self, key.span(), SyntaxError::PropertyNamedConstructor);
692        }
693        if key.is_private() {
694            if declare {
695                self.emit_err(
696                    key.span(),
697                    SyntaxError::PrivateNameModifier(atom!("declare")),
698                )
699            }
700            if is_abstract {
701                self.emit_err(
702                    key.span(),
703                    SyntaxError::PrivateNameModifier(atom!("abstract")),
704                )
705            }
706        }
707        let definite =
708            self.input().syntax().typescript() && !is_optional && self.input_mut().eat(Token::Bang);
709
710        let type_ann = self.try_parse_ts_type_ann()?;
711
712        self.do_inside_of_context(Context::IncludeInExpr.union(Context::InClassField), |p| {
713            let value = if p.input().is(Token::Eq) {
714                p.assert_and_bump(Token::Eq);
715                Some(p.parse_assignment_expr()?)
716            } else {
717                None
718            };
719
720            if !p.eat_general_semi() {
721                p.emit_err(p.input().cur_span(), SyntaxError::TS1005);
722            }
723
724            if accessor_token.is_some() {
725                return Ok(ClassMember::AutoAccessor(AutoAccessor {
726                    span: p.span(start),
727                    key,
728                    value,
729                    type_ann,
730                    is_static,
731                    decorators,
732                    accessibility,
733                    is_abstract,
734                    is_override,
735                    definite,
736                }));
737            }
738
739            Ok(match key {
740                Key::Private(key) => {
741                    let span = p.span(start);
742                    if accessibility.is_some() {
743                        p.emit_err(span.with_hi(key.span_hi()), SyntaxError::TS18010);
744                    }
745
746                    PrivateProp {
747                        span: p.span(start),
748                        key,
749                        value,
750                        is_static,
751                        decorators,
752                        accessibility,
753                        is_optional,
754                        is_override,
755                        readonly,
756                        type_ann,
757                        definite,
758                        ctxt: Default::default(),
759                    }
760                    .into()
761                }
762                Key::Public(key) => {
763                    let span = p.span(start);
764                    if is_abstract && value.is_some() {
765                        p.emit_err(span, SyntaxError::TS1267)
766                    }
767                    ClassProp {
768                        span,
769                        key,
770                        value,
771                        is_static,
772                        decorators,
773                        accessibility,
774                        is_abstract,
775                        is_optional,
776                        is_override,
777                        readonly,
778                        declare,
779                        definite,
780                        type_ann,
781                    }
782                    .into()
783                }
784                #[cfg(swc_ast_unknown)]
785                _ => unreachable!(),
786            })
787        })
788    }
789
790    fn parse_static_block(&mut self, start: BytePos) -> PResult<ClassMember> {
791        let body = self.do_inside_of_context(
792            Context::InStaticBlock
793                .union(Context::InClassField)
794                .union(Context::AllowUsingDecl),
795            |p| p.parse_block(false),
796        )?;
797
798        let span = self.span(start);
799        Ok(StaticBlock { span, body }.into())
800    }
801
802    fn parse_class_member_with_is_static(
803        &mut self,
804        start: BytePos,
805        declare_token: Option<Span>,
806        accessibility: Option<Accessibility>,
807        static_token: Option<Span>,
808        accessor_token: Option<Span>,
809        decorators: Vec<Decorator>,
810    ) -> PResult<ClassMember> {
811        let mut is_static = static_token.is_some();
812
813        let mut is_abstract = false;
814        let mut is_override = false;
815        let mut readonly = None;
816        let mut modifier_span = None;
817        let declare = declare_token.is_some();
818        while let Some(modifier) = if self.input().syntax().typescript() {
819            self.parse_ts_modifier(&["abstract", "readonly", "override", "static"], true)?
820        } else {
821            None
822        } {
823            modifier_span = Some(self.input().prev_span());
824            match modifier {
825                "abstract" => {
826                    if is_abstract {
827                        self.emit_err(
828                            self.input().prev_span(),
829                            SyntaxError::TS1030(atom!("abstract")),
830                        );
831                    } else if is_override {
832                        self.emit_err(
833                            self.input().prev_span(),
834                            SyntaxError::TS1029(atom!("abstract"), atom!("override")),
835                        );
836                    }
837                    is_abstract = true;
838                }
839                "override" => {
840                    if is_override {
841                        self.emit_err(
842                            self.input().prev_span(),
843                            SyntaxError::TS1030(atom!("override")),
844                        );
845                    } else if readonly.is_some() {
846                        self.emit_err(
847                            self.input().prev_span(),
848                            SyntaxError::TS1029(atom!("override"), atom!("readonly")),
849                        );
850                    } else if declare {
851                        self.emit_err(
852                            self.input().prev_span(),
853                            SyntaxError::TS1243(atom!("override"), atom!("declare")),
854                        );
855                    } else if !self.ctx().contains(Context::HasSuperClass) {
856                        self.emit_err(self.input().prev_span(), SyntaxError::TS4112);
857                    }
858                    is_override = true;
859                }
860                "readonly" => {
861                    let readonly_span = self.input().prev_span();
862                    if readonly.is_some() {
863                        self.emit_err(readonly_span, SyntaxError::TS1030(atom!("readonly")));
864                    } else {
865                        readonly = Some(readonly_span);
866                    }
867                }
868                "static" => {
869                    if is_override {
870                        self.emit_err(
871                            self.input().prev_span(),
872                            SyntaxError::TS1029(atom!("static"), atom!("override")),
873                        );
874                    }
875
876                    is_static = true;
877                }
878                _ => {}
879            }
880        }
881
882        let accessor_token = accessor_token.or_else(|| {
883            if self.syntax().auto_accessors() && readonly.is_none() {
884                let start = self.cur_pos();
885                if !peek!(self).is_some_and(|cur| cur == Token::LParen)
886                    && self.input_mut().eat(Token::Accessor)
887                {
888                    Some(self.span(start))
889                } else {
890                    None
891                }
892            } else {
893                None
894            }
895        });
896
897        if is_static && self.input().is(Token::LBrace) {
898            if let Some(span) = declare_token {
899                self.emit_err(span, SyntaxError::TS1184);
900            }
901            if accessibility.is_some() {
902                self.emit_err(self.input().cur_span(), SyntaxError::TS1184);
903            }
904            return self.parse_static_block(start);
905        }
906        if self.input().is(Token::Static) && peek!(self).is_some_and(|cur| cur == Token::LBrace) {
907            // For "readonly", "abstract" and "override"
908            if let Some(span) = modifier_span {
909                self.emit_err(span, SyntaxError::TS1184);
910            }
911            if let Some(span) = static_token {
912                self.emit_err(span, SyntaxError::TS1184);
913            }
914            self.bump(); // consume "static"
915            return self.parse_static_block(start);
916        }
917
918        if self.input().syntax().typescript()
919            && !is_abstract
920            && !is_override
921            && accessibility.is_none()
922        {
923            let idx = self.try_parse_ts_index_signature(start, readonly.is_some(), is_static)?;
924            if let Some(idx) = idx {
925                return Ok(idx.into());
926            }
927        }
928
929        if self.input_mut().eat(Token::Asterisk) {
930            // generator method
931            let key = self.parse_class_prop_name()?;
932            if readonly.is_some() {
933                self.emit_err(self.span(start), SyntaxError::ReadOnlyMethod);
934            }
935            if is_constructor(&key) {
936                self.emit_err(self.span(start), SyntaxError::GeneratorConstructor);
937            }
938
939            return self.make_method(
940                Self::parse_unique_formal_params,
941                MakeMethodArgs {
942                    start,
943                    decorators,
944                    is_async: false,
945                    is_generator: true,
946                    accessibility,
947                    is_abstract,
948                    is_override,
949                    is_optional: false,
950                    static_token,
951                    key,
952                    kind: MethodKind::Method,
953                },
954            );
955        }
956
957        trace_cur!(self, parse_class_member_with_is_static__normal_class_member);
958        let key = if readonly.is_some() && matches!(self.input().cur(), Token::Bang | Token::Colon)
959        {
960            Key::Public(PropName::Ident(IdentName::new(
961                atom!("readonly"),
962                readonly.unwrap(),
963            )))
964        } else {
965            self.parse_class_prop_name()?
966        };
967        let is_optional =
968            self.input().syntax().typescript() && self.input_mut().eat(Token::QuestionMark);
969
970        if self.is_class_method() {
971            // handle a(){} / get(){} / set(){} / async(){}
972
973            trace_cur!(self, parse_class_member_with_is_static__normal_class_method);
974
975            if let Some(token) = declare_token {
976                self.emit_err(token, SyntaxError::TS1031)
977            }
978
979            if readonly.is_some() {
980                syntax_error!(self, self.span(start), SyntaxError::ReadOnlyMethod);
981            }
982            let is_constructor = is_constructor(&key);
983
984            if is_constructor {
985                if self.syntax().typescript() && is_override {
986                    self.emit_err(self.span(start), SyntaxError::TS1089(atom!("override")));
987                }
988
989                if self.syntax().typescript() && self.input().is(Token::Lt) {
990                    let start = self.cur_pos();
991                    if peek!(self).is_some_and(|cur| cur == Token::Lt) {
992                        self.assert_and_bump(Token::Lt);
993                        let start2 = self.cur_pos();
994                        self.assert_and_bump(Token::Gt);
995
996                        self.emit_err(self.span(start), SyntaxError::TS1098);
997                        self.emit_err(self.span(start2), SyntaxError::TS1092);
998                    } else {
999                        let type_params = self.try_parse_ts_type_params(false, true)?;
1000
1001                        if let Some(type_params) = type_params {
1002                            for param in type_params.params {
1003                                self.emit_err(param.span(), SyntaxError::TS1092);
1004                            }
1005                        }
1006                    }
1007                }
1008
1009                expect!(self, Token::LParen);
1010                let params = self.parse_constructor_params()?;
1011                expect!(self, Token::RParen);
1012
1013                if self.syntax().typescript() && self.input().is(Token::Colon) {
1014                    let start = self.cur_pos();
1015                    let type_ann = self.parse_ts_type_ann(true, start)?;
1016
1017                    self.emit_err(type_ann.type_ann.span(), SyntaxError::TS1093);
1018                }
1019
1020                let body: Option<_> = self.parse_fn_block_body(
1021                    false,
1022                    false,
1023                    false,
1024                    params.is_simple_parameter_list(),
1025                )?;
1026
1027                if body.is_none() {
1028                    for param in params.iter() {
1029                        if param.is_ts_param_prop() {
1030                            self.emit_err(param.span(), SyntaxError::TS2369)
1031                        }
1032                    }
1033                }
1034
1035                if self.syntax().typescript() && body.is_none() {
1036                    // Declare constructors cannot have assignment pattern in parameters
1037                    for param in &params {
1038                        // TODO: Search deeply for assignment pattern using a Visitor
1039
1040                        let span = match *param {
1041                            ParamOrTsParamProp::Param(ref param) => match param.pat {
1042                                Pat::Assign(ref p) => Some(p.span()),
1043                                _ => None,
1044                            },
1045                            ParamOrTsParamProp::TsParamProp(TsParamProp {
1046                                param: TsParamPropParam::Assign(ref p),
1047                                ..
1048                            }) => Some(p.span()),
1049                            _ => None,
1050                        };
1051
1052                        if let Some(span) = span {
1053                            self.emit_err(span, SyntaxError::TS2371)
1054                        }
1055                    }
1056                }
1057
1058                if let Some(static_token) = static_token {
1059                    self.emit_err(static_token, SyntaxError::TS1089(atom!("static")))
1060                }
1061
1062                if let Some(span) = modifier_span {
1063                    if is_abstract {
1064                        self.emit_err(span, SyntaxError::TS1242);
1065                    }
1066                }
1067
1068                return Ok(ClassMember::Constructor(Constructor {
1069                    span: self.span(start),
1070                    accessibility,
1071                    key: match key {
1072                        Key::Public(key) => key,
1073                        _ => unreachable!("is_constructor() returns false for PrivateName"),
1074                    },
1075                    is_optional,
1076                    params,
1077                    body,
1078                    ..Default::default()
1079                }));
1080            } else {
1081                return self.make_method(
1082                    Self::parse_formal_params,
1083                    MakeMethodArgs {
1084                        start,
1085                        is_optional,
1086                        accessibility,
1087                        decorators,
1088                        is_abstract,
1089                        is_override,
1090                        static_token,
1091                        kind: MethodKind::Method,
1092                        key,
1093                        is_async: false,
1094                        is_generator: false,
1095                    },
1096                );
1097            }
1098        }
1099
1100        let is_next_line_generator =
1101            self.input_mut().had_line_break_before_cur() && self.input().is(Token::Asterisk);
1102        let getter_or_setter_ident = match key {
1103            // `get\n*` is an uninitialized property named 'get' followed by a generator.
1104            Key::Public(PropName::Ident(ref i))
1105                if (i.sym == "get" || i.sym == "set")
1106                    && !self.is_class_property(/* asi */ false)
1107                    && !is_next_line_generator =>
1108            {
1109                Some(i)
1110            }
1111            _ => None,
1112        };
1113
1114        if getter_or_setter_ident.is_none() && self.is_class_property(/* asi */ true) {
1115            return self.make_property(
1116                start,
1117                decorators,
1118                accessibility,
1119                key,
1120                is_static,
1121                accessor_token,
1122                is_optional,
1123                readonly.is_some(),
1124                declare,
1125                is_abstract,
1126                is_override,
1127            );
1128        }
1129
1130        if match key {
1131            Key::Public(PropName::Ident(ref i)) => i.sym == "async",
1132            _ => false,
1133        } && !self.input_mut().had_line_break_before_cur()
1134        {
1135            // handle async foo(){}
1136
1137            if self.input().syntax().typescript()
1138                && self.parse_ts_modifier(&["override"], false)?.is_some()
1139            {
1140                is_override = true;
1141                self.emit_err(
1142                    self.input().prev_span(),
1143                    SyntaxError::TS1029(atom!("override"), atom!("async")),
1144                );
1145            }
1146
1147            let is_generator = self.input_mut().eat(Token::Asterisk);
1148            let key = self.parse_class_prop_name()?;
1149            if is_constructor(&key) {
1150                syntax_error!(self, key.span(), SyntaxError::AsyncConstructor)
1151            }
1152            if readonly.is_some() {
1153                syntax_error!(self, self.span(start), SyntaxError::ReadOnlyMethod);
1154            }
1155
1156            // handle async foo(){}
1157            let is_optional = is_optional
1158                || self.input().syntax().typescript() && self.input_mut().eat(Token::QuestionMark);
1159            return self.make_method(
1160                Self::parse_unique_formal_params,
1161                MakeMethodArgs {
1162                    start,
1163                    static_token,
1164                    key,
1165                    is_abstract,
1166                    accessibility,
1167                    is_optional,
1168                    is_override,
1169                    decorators,
1170                    kind: MethodKind::Method,
1171                    is_async: true,
1172                    is_generator,
1173                },
1174            );
1175        }
1176
1177        if let Some(i) = getter_or_setter_ident {
1178            let key_span = key.span();
1179
1180            // handle get foo(){} / set foo(v){}
1181            let key = self.parse_class_prop_name()?;
1182
1183            if readonly.is_some() {
1184                self.emit_err(key_span, SyntaxError::GetterSetterCannotBeReadonly);
1185            }
1186
1187            if is_constructor(&key) {
1188                self.emit_err(key_span, SyntaxError::ConstructorAccessor);
1189            }
1190
1191            return match &*i.sym {
1192                "get" => self.make_method(
1193                    |p| {
1194                        let params = p.parse_formal_params()?;
1195
1196                        if params.iter().any(is_not_this) {
1197                            p.emit_err(key_span, SyntaxError::GetterParam);
1198                        }
1199
1200                        Ok(params)
1201                    },
1202                    MakeMethodArgs {
1203                        decorators,
1204                        start,
1205                        is_abstract,
1206                        is_async: false,
1207                        is_generator: false,
1208                        is_optional,
1209                        is_override,
1210                        accessibility,
1211                        static_token,
1212                        key,
1213                        kind: MethodKind::Getter,
1214                    },
1215                ),
1216                "set" => self.make_method(
1217                    |p| {
1218                        let params = p.parse_formal_params()?;
1219
1220                        if params.iter().filter(|p| is_not_this(p)).count() != 1 {
1221                            p.emit_err(key_span, SyntaxError::SetterParam);
1222                        }
1223
1224                        if !params.is_empty() {
1225                            if let Pat::Rest(..) = params[0].pat {
1226                                p.emit_err(params[0].pat.span(), SyntaxError::RestPatInSetter);
1227                            }
1228                        }
1229
1230                        Ok(params)
1231                    },
1232                    MakeMethodArgs {
1233                        decorators,
1234                        start,
1235                        is_optional,
1236                        is_abstract,
1237                        is_override,
1238                        is_async: false,
1239                        is_generator: false,
1240                        accessibility,
1241                        static_token,
1242                        key,
1243                        kind: MethodKind::Setter,
1244                    },
1245                ),
1246                _ => unreachable!(),
1247            };
1248        }
1249
1250        unexpected!(self, "* for generator, private key, identifier or async")
1251    }
1252
1253    fn parse_class_member(&mut self) -> PResult<ClassMember> {
1254        trace_cur!(self, parse_class_member);
1255
1256        let start = self.cur_pos();
1257        let decorators = self.parse_decorators(false)?;
1258        let declare = self.syntax().typescript() && self.input_mut().eat(Token::Declare);
1259        let accessibility = if self.input().syntax().typescript() {
1260            self.parse_access_modifier()?
1261        } else {
1262            None
1263        };
1264        // Allow `private declare`.
1265        let declare = declare || self.syntax().typescript() && self.input_mut().eat(Token::Declare);
1266
1267        let declare_token = if declare {
1268            // Handle declare(){}
1269            if self.is_class_method() {
1270                let key = Key::Public(PropName::Ident(IdentName::new(
1271                    atom!("declare"),
1272                    self.span(start),
1273                )));
1274                let is_optional =
1275                    self.input().syntax().typescript() && self.input_mut().eat(Token::QuestionMark);
1276                return self.make_method(
1277                    Self::parse_unique_formal_params,
1278                    MakeMethodArgs {
1279                        start,
1280                        accessibility,
1281                        decorators,
1282                        is_abstract: false,
1283                        is_optional,
1284                        is_override: false,
1285                        is_async: false,
1286                        is_generator: false,
1287                        static_token: None,
1288                        key,
1289                        kind: MethodKind::Method,
1290                    },
1291                );
1292            } else if self.is_class_property(/* asi */ true)
1293                || (self.syntax().typescript() && self.input().is(Token::QuestionMark))
1294            {
1295                // Property named `declare`
1296
1297                let key = Key::Public(PropName::Ident(IdentName::new(
1298                    atom!("declare"),
1299                    self.span(start),
1300                )));
1301                let is_optional =
1302                    self.input().syntax().typescript() && self.input_mut().eat(Token::QuestionMark);
1303                return self.make_property(
1304                    start,
1305                    decorators,
1306                    accessibility,
1307                    key,
1308                    false,
1309                    None,
1310                    is_optional,
1311                    false,
1312                    false,
1313                    false,
1314                    false,
1315                );
1316            } else {
1317                Some(self.span(start))
1318            }
1319        } else {
1320            None
1321        };
1322
1323        let static_token = {
1324            let start = self.cur_pos();
1325            if self.input_mut().eat(Token::Static) {
1326                Some(self.span(start))
1327            } else {
1328                None
1329            }
1330        };
1331
1332        let accessor_token = if self.syntax().auto_accessors() {
1333            let start = self.cur_pos();
1334            if self.input_mut().eat(Token::Accessor) {
1335                Some(self.span(start))
1336            } else {
1337                None
1338            }
1339        } else {
1340            None
1341        };
1342
1343        if let Some(accessor_token) = accessor_token {
1344            // Handle accessor(){}
1345            if self.is_class_method() {
1346                let key = Key::Public(PropName::Ident(IdentName::new(
1347                    atom!("accessor"),
1348                    accessor_token,
1349                )));
1350                let is_optional =
1351                    self.input().syntax().typescript() && self.input_mut().eat(Token::QuestionMark);
1352                return self.make_method(
1353                    Self::parse_unique_formal_params,
1354                    MakeMethodArgs {
1355                        start,
1356                        accessibility,
1357                        decorators,
1358                        is_abstract: false,
1359                        is_optional,
1360                        is_override: false,
1361                        is_async: false,
1362                        is_generator: false,
1363                        static_token,
1364                        key,
1365                        kind: MethodKind::Method,
1366                    },
1367                );
1368            } else if self.is_class_property(/* asi */ true)
1369                || (self.syntax().typescript() && self.input().is(Token::QuestionMark))
1370            {
1371                // Property named `accessor`
1372
1373                let key = Key::Public(PropName::Ident(IdentName::new(
1374                    atom!("accessor"),
1375                    accessor_token,
1376                )));
1377                let is_optional =
1378                    self.input().syntax().typescript() && self.input_mut().eat(Token::QuestionMark);
1379                let is_static = static_token.is_some();
1380                return self.make_property(
1381                    start,
1382                    decorators,
1383                    accessibility,
1384                    key,
1385                    is_static,
1386                    None,
1387                    is_optional,
1388                    false,
1389                    declare,
1390                    false,
1391                    false,
1392                );
1393            }
1394        }
1395
1396        if let Some(static_token) = static_token {
1397            // Handle static(){}
1398            if self.is_class_method() {
1399                let key = Key::Public(PropName::Ident(IdentName::new(
1400                    atom!("static"),
1401                    static_token,
1402                )));
1403                let is_optional =
1404                    self.input().syntax().typescript() && self.input_mut().eat(Token::QuestionMark);
1405                return self.make_method(
1406                    Self::parse_unique_formal_params,
1407                    MakeMethodArgs {
1408                        start,
1409                        accessibility,
1410                        decorators,
1411                        is_abstract: false,
1412                        is_optional,
1413                        is_override: false,
1414                        is_async: false,
1415                        is_generator: false,
1416                        static_token: None,
1417                        key,
1418                        kind: MethodKind::Method,
1419                    },
1420                );
1421            } else if self.is_class_property(/* asi */ false)
1422                || (self.syntax().typescript() && self.input().is(Token::QuestionMark))
1423            {
1424                // Property named `static`
1425
1426                // Avoid to parse
1427                //   static
1428                //   {}
1429                let is_parsing_static_blocks = self.input().is(Token::LBrace);
1430                if !is_parsing_static_blocks {
1431                    let key = Key::Public(PropName::Ident(IdentName::new(
1432                        atom!("static"),
1433                        static_token,
1434                    )));
1435                    let is_optional = self.input().syntax().typescript()
1436                        && self.input_mut().eat(Token::QuestionMark);
1437                    return self.make_property(
1438                        start,
1439                        decorators,
1440                        accessibility,
1441                        key,
1442                        false,
1443                        accessor_token,
1444                        is_optional,
1445                        false,
1446                        declare,
1447                        false,
1448                        false,
1449                    );
1450                }
1451            } else {
1452                // TODO: error if static contains escape
1453            }
1454        }
1455
1456        self.parse_class_member_with_is_static(
1457            start,
1458            declare_token,
1459            accessibility,
1460            static_token,
1461            accessor_token,
1462            decorators,
1463        )
1464    }
1465
1466    fn parse_class_body(&mut self) -> PResult<Vec<ClassMember>> {
1467        let mut elems = Vec::with_capacity(32);
1468        let mut has_constructor_with_body = false;
1469        while !self.input().is(Token::RBrace) {
1470            if self.input_mut().eat(Token::Semi) {
1471                let span = self.input().prev_span();
1472                debug_assert!(span.lo <= span.hi);
1473                elems.push(ClassMember::Empty(EmptyStmt { span }));
1474                continue;
1475            }
1476            let elem =
1477                self.do_inside_of_context(Context::AllowDirectSuper, Self::parse_class_member)?;
1478
1479            if !self.ctx().contains(Context::InDeclare) {
1480                if let ClassMember::Constructor(Constructor {
1481                    body: Some(..),
1482                    span,
1483                    ..
1484                }) = elem
1485                {
1486                    if has_constructor_with_body {
1487                        self.emit_err(span, SyntaxError::DuplicateConstructor);
1488                    }
1489                    has_constructor_with_body = true;
1490                }
1491            }
1492            elems.push(elem);
1493        }
1494        Ok(elems)
1495    }
1496
1497    fn parse_class<T>(
1498        &mut self,
1499        start: BytePos,
1500        class_start: BytePos,
1501        decorators: Vec<Decorator>,
1502        is_abstract: bool,
1503    ) -> PResult<T>
1504    where
1505        T: OutputType,
1506    {
1507        let (ident, mut class) = self.do_inside_of_context(Context::InClass, |p| {
1508            p.parse_class_inner(start, class_start, decorators, T::IS_IDENT_REQUIRED)
1509        })?;
1510
1511        if is_abstract {
1512            class.is_abstract = true
1513        } else {
1514            for member in class.body.iter() {
1515                match member {
1516                    ClassMember::ClassProp(ClassProp {
1517                        is_abstract: true,
1518                        span,
1519                        ..
1520                    })
1521                    | ClassMember::Method(ClassMethod {
1522                        span,
1523                        is_abstract: true,
1524                        ..
1525                    }) => self.emit_err(*span, SyntaxError::TS1244),
1526                    _ => (),
1527                }
1528            }
1529        }
1530
1531        match T::finish_class(self.span(start), ident, class) {
1532            Ok(v) => Ok(v),
1533            Err(kind) => syntax_error!(self, kind),
1534        }
1535    }
1536
1537    /// Not generic
1538    fn parse_class_inner(
1539        &mut self,
1540        _start: BytePos,
1541        class_start: BytePos,
1542        decorators: Vec<Decorator>,
1543        is_ident_required: bool,
1544    ) -> PResult<(Option<Ident>, Box<Class>)> {
1545        self.strict_mode(|p| {
1546            expect!(p, Token::Class);
1547
1548            let ident = p.parse_maybe_opt_binding_ident(is_ident_required, true)?;
1549            if p.input().syntax().typescript() {
1550                if let Some(span) = ident.invalid_class_name() {
1551                    p.emit_err(span, SyntaxError::TS2414);
1552                }
1553            }
1554
1555            let type_params = if p.input().syntax().typescript() {
1556                p.try_parse_ts_type_params(true, true)?
1557            } else {
1558                None
1559            };
1560
1561            let (mut super_class, mut super_type_params) = if p.input_mut().eat(Token::Extends) {
1562                let (super_class, super_type_params) = p.parse_super_class()?;
1563
1564                if p.syntax().typescript() && p.input_mut().eat(Token::Comma) {
1565                    let exprs = p.parse_ts_heritage_clause()?;
1566
1567                    for e in &exprs {
1568                        p.emit_err(e.span(), SyntaxError::TS1174);
1569                    }
1570                }
1571
1572                (Some(super_class), super_type_params)
1573            } else {
1574                (None, None)
1575            };
1576
1577            // Handle TS1172
1578            if p.input_mut().eat(Token::Extends) {
1579                p.emit_err(p.input().prev_span(), SyntaxError::TS1172);
1580
1581                p.parse_super_class()?;
1582            };
1583
1584            let implements =
1585                if p.input().syntax().typescript() && p.input_mut().eat(Token::Implements) {
1586                    p.parse_ts_heritage_clause()?
1587                } else {
1588                    Vec::with_capacity(4)
1589                };
1590
1591            {
1592                // Handle TS1175
1593                if p.input().syntax().typescript() && p.input_mut().eat(Token::Implements) {
1594                    p.emit_err(p.input().prev_span(), SyntaxError::TS1175);
1595
1596                    p.parse_ts_heritage_clause()?;
1597                }
1598            }
1599
1600            // Handle TS1173
1601            if p.input().syntax().typescript() && p.input_mut().eat(Token::Extends) {
1602                p.emit_err(p.input().prev_span(), SyntaxError::TS1173);
1603
1604                let (sc, type_params) = p.parse_super_class()?;
1605
1606                if super_class.is_none() {
1607                    super_class = Some(sc);
1608                    if type_params.is_some() {
1609                        super_type_params = type_params;
1610                    }
1611                }
1612            }
1613
1614            expect!(p, Token::LBrace);
1615
1616            let body = if super_class.is_some() {
1617                p.do_inside_of_context(Context::HasSuperClass, Self::parse_class_body)?
1618            } else {
1619                p.do_outside_of_context(Context::HasSuperClass, Self::parse_class_body)?
1620            };
1621
1622            if p.input().cur() == Token::Eof {
1623                let eof_text = p.input_mut().dump_cur();
1624                p.emit_err(
1625                    p.input().cur_span(),
1626                    SyntaxError::Expected(format!("{:?}", Token::RBrace), eof_text),
1627                );
1628            } else {
1629                expect!(p, Token::RBrace);
1630            }
1631
1632            let span = p.span(class_start);
1633            Ok((
1634                ident,
1635                Box::new(Class {
1636                    span,
1637                    decorators,
1638                    is_abstract: false,
1639                    type_params,
1640                    super_class,
1641                    super_type_params,
1642                    body,
1643                    implements,
1644                    ..Default::default()
1645                }),
1646            ))
1647        })
1648    }
1649}
1650
1651trait OutputType: Sized {
1652    const IS_IDENT_REQUIRED: bool;
1653
1654    /// From babel..
1655    ///
1656    /// When parsing function expression, the binding identifier is parsed
1657    /// according to the rules inside the function.
1658    /// e.g. (function* yield() {}) is invalid because "yield" is disallowed in
1659    /// generators.
1660    /// This isn't the case with function declarations: function* yield() {} is
1661    /// valid because yield is parsed as if it was outside the generator.
1662    /// Therefore, this.state.inGenerator is set before or after parsing the
1663    /// function id according to the "isStatement" parameter.
1664    fn is_fn_expr() -> bool {
1665        false
1666    }
1667
1668    fn finish_fn(span: Span, ident: Option<Ident>, f: Box<Function>) -> Result<Self, SyntaxError>;
1669
1670    fn finish_class(
1671        span: Span,
1672        ident: Option<Ident>,
1673        class: Box<Class>,
1674    ) -> Result<Self, SyntaxError>;
1675}
1676
1677impl OutputType for Box<Expr> {
1678    const IS_IDENT_REQUIRED: bool = false;
1679
1680    fn is_fn_expr() -> bool {
1681        true
1682    }
1683
1684    fn finish_fn(
1685        _span: Span,
1686        ident: Option<Ident>,
1687        function: Box<Function>,
1688    ) -> Result<Self, SyntaxError> {
1689        Ok(FnExpr { ident, function }.into())
1690    }
1691
1692    fn finish_class(
1693        _span: Span,
1694        ident: Option<Ident>,
1695        class: Box<Class>,
1696    ) -> Result<Self, SyntaxError> {
1697        Ok(ClassExpr { ident, class }.into())
1698    }
1699}
1700
1701impl OutputType for ExportDefaultDecl {
1702    const IS_IDENT_REQUIRED: bool = false;
1703
1704    fn finish_fn(
1705        span: Span,
1706        ident: Option<Ident>,
1707        function: Box<Function>,
1708    ) -> Result<Self, SyntaxError> {
1709        Ok(ExportDefaultDecl {
1710            span,
1711            decl: DefaultDecl::Fn(FnExpr { ident, function }),
1712        })
1713    }
1714
1715    fn finish_class(
1716        span: Span,
1717        ident: Option<Ident>,
1718        class: Box<Class>,
1719    ) -> Result<Self, SyntaxError> {
1720        Ok(ExportDefaultDecl {
1721            span,
1722            decl: DefaultDecl::Class(ClassExpr { ident, class }),
1723        })
1724    }
1725}
1726
1727impl OutputType for Decl {
1728    const IS_IDENT_REQUIRED: bool = true;
1729
1730    fn finish_fn(
1731        _span: Span,
1732        ident: Option<Ident>,
1733        function: Box<Function>,
1734    ) -> Result<Self, SyntaxError> {
1735        let ident = ident.ok_or(SyntaxError::ExpectedIdent)?;
1736
1737        Ok(FnDecl {
1738            declare: false,
1739            ident,
1740            function,
1741        }
1742        .into())
1743    }
1744
1745    fn finish_class(_: Span, ident: Option<Ident>, class: Box<Class>) -> Result<Self, SyntaxError> {
1746        let ident = ident.ok_or(SyntaxError::ExpectedIdent)?;
1747
1748        Ok(ClassDecl {
1749            declare: false,
1750            ident,
1751            class,
1752        }
1753        .into())
1754    }
1755}
1756
1757fn has_use_strict(block: &BlockStmt) -> Option<Span> {
1758    block
1759        .stmts
1760        .iter()
1761        .take_while(|s| s.can_precede_directive())
1762        .find_map(|s| {
1763            if s.is_use_strict() {
1764                Some(s.span())
1765            } else {
1766                None
1767            }
1768        })
1769}
1770
1771fn is_constructor(key: &Key) -> bool {
1772    if let Key::Public(PropName::Ident(IdentName { sym, .. })) = key {
1773        sym.eq("constructor")
1774    } else if let Key::Public(PropName::Str(Str { value, .. })) = key {
1775        value.eq("constructor")
1776    } else {
1777        false
1778    }
1779}
1780
1781pub(crate) fn is_not_this(p: &Param) -> bool {
1782    !matches!(
1783        &p.pat,
1784        Pat::Ident(BindingIdent {
1785            id: Ident{ sym: this, .. },
1786            ..
1787        })if &**this == "this"
1788    )
1789}
1790
1791#[cfg(test)]
1792mod tests {
1793
1794    use swc_common::DUMMY_SP as span;
1795    use swc_ecma_ast::*;
1796    use swc_ecma_visit::assert_eq_ignore_span;
1797
1798    use crate::{test_parser, Syntax};
1799
1800    fn expr(s: &'static str) -> Box<Expr> {
1801        test_parser(s, Syntax::default(), |p| p.parse_expr())
1802    }
1803
1804    #[test]
1805    fn class_expr() {
1806        assert_eq_ignore_span!(
1807            expr("(class extends a {})"),
1808            Box::new(Expr::Paren(ParenExpr {
1809                span,
1810                expr: Box::new(Expr::Class(ClassExpr {
1811                    ident: None,
1812                    class: Box::new(Class {
1813                        decorators: Vec::new(),
1814                        span,
1815                        body: Vec::new(),
1816                        super_class: Some(expr("a")),
1817                        implements: Vec::new(),
1818                        is_abstract: false,
1819                        ..Default::default()
1820                    }),
1821                })),
1822            }))
1823        );
1824    }
1825}