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