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 #[cfg(swc_ast_unknown)]
586 _ => unreachable!(),
587 }
588}
589
590pub fn parse_fn_block_or_expr_body<'a, P: Parser<'a>>(
591 p: &mut P,
592 is_async: bool,
593 is_generator: bool,
594 is_arrow_function: bool,
595 is_simple_parameter_list: bool,
596) -> PResult<Box<BlockStmtOrExpr>> {
597 parse_fn_body(
598 p,
599 is_async,
600 is_generator,
601 is_arrow_function,
602 is_simple_parameter_list,
603 |p, is_simple_parameter_list| {
604 if p.input().is(&P::Token::LBRACE) {
605 parse_block(p, false)
606 .map(|block_stmt| {
607 if !is_simple_parameter_list {
608 if let Some(span) = has_use_strict(&block_stmt) {
609 p.emit_err(span, SyntaxError::IllegalLanguageModeDirective);
610 }
611 }
612 BlockStmtOrExpr::BlockStmt(block_stmt)
613 })
614 .map(Box::new)
615 } else {
616 parse_assignment_expr(p)
617 .map(BlockStmtOrExpr::Expr)
618 .map(Box::new)
619 }
620 },
621 )
622}
623
624fn parse_fn_body<'a, P: Parser<'a>, T>(
625 p: &mut P,
626 is_async: bool,
627 is_generator: bool,
628 is_arrow_function: bool,
629 is_simple_parameter_list: bool,
630 f: impl FnOnce(&mut P, bool) -> PResult<T>,
631) -> PResult<T> {
632 if p.ctx().contains(Context::InDeclare)
633 && p.syntax().typescript()
634 && p.input().is(&P::Token::LBRACE)
635 {
636 p.emit_err(p.input().cur_span(), SyntaxError::TS1183);
641 }
642
643 let f_with_generator_context = |p: &mut P| {
644 let f_with_inside_non_arrow_fn_scope = |p: &mut P| {
645 let f_with_new_state = |p: &mut P| {
646 let mut p = p.with_state(crate::common::parser::state::State::default());
647 f(&mut p, is_simple_parameter_list)
648 };
649
650 if is_arrow_function && !p.ctx().contains(Context::InsideNonArrowFunctionScope) {
651 p.do_outside_of_context(Context::InsideNonArrowFunctionScope, f_with_new_state)
652 } else {
653 p.do_inside_of_context(Context::InsideNonArrowFunctionScope, f_with_new_state)
654 }
655 };
656
657 if is_generator {
658 p.do_inside_of_context(Context::InGenerator, f_with_inside_non_arrow_fn_scope)
659 } else {
660 p.do_outside_of_context(Context::InGenerator, f_with_inside_non_arrow_fn_scope)
661 }
662 };
663
664 p.do_inside_of_context(Context::InFunction, |p| {
665 p.do_outside_of_context(
666 Context::InStaticBlock
667 .union(Context::IsBreakAllowed)
668 .union(Context::IsContinueAllowed)
669 .union(Context::TopLevel),
670 |p| {
671 if is_async {
672 p.do_inside_of_context(Context::InAsync, f_with_generator_context)
673 } else {
674 p.do_outside_of_context(Context::InAsync, f_with_generator_context)
675 }
676 },
677 )
678 })
679}
680
681pub(super) fn parse_fn_block_body<'a, P: Parser<'a>>(
682 p: &mut P,
683 is_async: bool,
684 is_generator: bool,
685 is_arrow_function: bool,
686 is_simple_parameter_list: bool,
687) -> PResult<Option<BlockStmt>> {
688 parse_fn_body(
689 p,
690 is_async,
691 is_generator,
692 is_arrow_function,
693 is_simple_parameter_list,
694 |p, is_simple_parameter_list| {
695 if p.input().syntax().typescript()
697 && !p.input().is(&P::Token::LBRACE)
698 && p.eat_general_semi()
699 {
700 return Ok(None);
701 }
702 p.allow_in_expr(|p| parse_block(p, true)).map(|block_stmt| {
703 if !is_simple_parameter_list {
704 if let Some(span) = has_use_strict(&block_stmt) {
705 p.emit_err(span, SyntaxError::IllegalLanguageModeDirective);
706 }
707 }
708 Some(block_stmt)
709 })
710 },
711 )
712}
713
714fn make_property<'a, P: Parser<'a>>(
715 p: &mut P,
716 start: BytePos,
717 decorators: Vec<Decorator>,
718 accessibility: Option<Accessibility>,
719 key: Key,
720 is_static: bool,
721 accessor_token: Option<Span>,
722 is_optional: bool,
723 readonly: bool,
724 declare: bool,
725 is_abstract: bool,
726 is_override: bool,
727) -> PResult<ClassMember> {
728 if is_constructor(&key) {
729 syntax_error!(p, key.span(), SyntaxError::PropertyNamedConstructor);
730 }
731 if key.is_private() {
732 if declare {
733 p.emit_err(
734 key.span(),
735 SyntaxError::PrivateNameModifier(atom!("declare")),
736 )
737 }
738 if is_abstract {
739 p.emit_err(
740 key.span(),
741 SyntaxError::PrivateNameModifier(atom!("abstract")),
742 )
743 }
744 }
745 let definite =
746 p.input().syntax().typescript() && !is_optional && p.input_mut().eat(&P::Token::BANG);
747
748 let type_ann = try_parse_ts_type_ann(p)?;
749
750 p.do_inside_of_context(Context::IncludeInExpr.union(Context::InClassField), |p| {
751 let value = if p.input().is(&P::Token::EQUAL) {
752 p.assert_and_bump(&P::Token::EQUAL);
753 Some(parse_assignment_expr(p)?)
754 } else {
755 None
756 };
757
758 if !p.eat_general_semi() {
759 p.emit_err(p.input().cur_span(), SyntaxError::TS1005);
760 }
761
762 if accessor_token.is_some() {
763 return Ok(ClassMember::AutoAccessor(AutoAccessor {
764 span: p.span(start),
765 key,
766 value,
767 type_ann,
768 is_static,
769 decorators,
770 accessibility,
771 is_abstract,
772 is_override,
773 definite,
774 }));
775 }
776
777 Ok(match key {
778 Key::Private(key) => {
779 let span = p.span(start);
780 if accessibility.is_some() {
781 p.emit_err(span.with_hi(key.span_hi()), SyntaxError::TS18010);
782 }
783
784 PrivateProp {
785 span: p.span(start),
786 key,
787 value,
788 is_static,
789 decorators,
790 accessibility,
791 is_optional,
792 is_override,
793 readonly,
794 type_ann,
795 definite,
796 ctxt: Default::default(),
797 }
798 .into()
799 }
800 Key::Public(key) => {
801 let span = p.span(start);
802 if is_abstract && value.is_some() {
803 p.emit_err(span, SyntaxError::TS1267)
804 }
805 ClassProp {
806 span,
807 key,
808 value,
809 is_static,
810 decorators,
811 accessibility,
812 is_abstract,
813 is_optional,
814 is_override,
815 readonly,
816 declare,
817 definite,
818 type_ann,
819 }
820 .into()
821 }
822 #[cfg(swc_ast_unknown)]
823 _ => unreachable!(),
824 })
825 })
826}
827
828fn parse_static_block<'a, P: Parser<'a>>(p: &mut P, start: BytePos) -> PResult<ClassMember> {
829 let body = p.do_inside_of_context(
830 Context::InStaticBlock
831 .union(Context::InClassField)
832 .union(Context::AllowUsingDecl),
833 |p| parse_block(p, false),
834 )?;
835
836 let span = p.span(start);
837 Ok(StaticBlock { span, body }.into())
838}
839
840fn parse_class_member_with_is_static<'a, P: Parser<'a>>(
841 p: &mut P,
842 start: BytePos,
843 declare_token: Option<Span>,
844 accessibility: Option<Accessibility>,
845 static_token: Option<Span>,
846 accessor_token: Option<Span>,
847 decorators: Vec<Decorator>,
848) -> PResult<ClassMember> {
849 let mut is_static = static_token.is_some();
850
851 let mut is_abstract = false;
852 let mut is_override = false;
853 let mut readonly = None;
854 let mut modifier_span = None;
855 let declare = declare_token.is_some();
856 while let Some(modifier) = if p.input().syntax().typescript() {
857 parse_ts_modifier(p, &["abstract", "readonly", "override", "static"], true)?
858 } else {
859 None
860 } {
861 modifier_span = Some(p.input().prev_span());
862 match modifier {
863 "abstract" => {
864 if is_abstract {
865 p.emit_err(
866 p.input().prev_span(),
867 SyntaxError::TS1030(atom!("abstract")),
868 );
869 } else if is_override {
870 p.emit_err(
871 p.input().prev_span(),
872 SyntaxError::TS1029(atom!("abstract"), atom!("override")),
873 );
874 }
875 is_abstract = true;
876 }
877 "override" => {
878 if is_override {
879 p.emit_err(
880 p.input().prev_span(),
881 SyntaxError::TS1030(atom!("override")),
882 );
883 } else if readonly.is_some() {
884 p.emit_err(
885 p.input().prev_span(),
886 SyntaxError::TS1029(atom!("override"), atom!("readonly")),
887 );
888 } else if declare {
889 p.emit_err(
890 p.input().prev_span(),
891 SyntaxError::TS1243(atom!("override"), atom!("declare")),
892 );
893 } else if !p.ctx().contains(Context::HasSuperClass) {
894 p.emit_err(p.input().prev_span(), SyntaxError::TS4112);
895 }
896 is_override = true;
897 }
898 "readonly" => {
899 let readonly_span = p.input().prev_span();
900 if readonly.is_some() {
901 p.emit_err(readonly_span, SyntaxError::TS1030(atom!("readonly")));
902 } else {
903 readonly = Some(readonly_span);
904 }
905 }
906 "static" => {
907 if is_override {
908 p.emit_err(
909 p.input().prev_span(),
910 SyntaxError::TS1029(atom!("static"), atom!("override")),
911 );
912 }
913
914 is_static = true;
915 }
916 _ => {}
917 }
918 }
919
920 let accessor_token = accessor_token.or_else(|| {
921 if p.syntax().auto_accessors() && readonly.is_none() {
922 let start = p.cur_pos();
923 if !peek!(p).is_some_and(|cur| cur.is_lparen())
924 && p.input_mut().eat(&P::Token::ACCESSOR)
925 {
926 Some(p.span(start))
927 } else {
928 None
929 }
930 } else {
931 None
932 }
933 });
934
935 if is_static && p.input().is(&P::Token::LBRACE) {
936 if let Some(span) = declare_token {
937 p.emit_err(span, SyntaxError::TS1184);
938 }
939 if accessibility.is_some() {
940 p.emit_err(p.input().cur_span(), SyntaxError::TS1184);
941 }
942 return parse_static_block(p, start);
943 }
944 if p.input().is(&P::Token::STATIC) && peek!(p).is_some_and(|cur| cur.is_lbrace()) {
945 if let Some(span) = modifier_span {
947 p.emit_err(span, SyntaxError::TS1184);
948 }
949 if let Some(span) = static_token {
950 p.emit_err(span, SyntaxError::TS1184);
951 }
952 p.bump(); return parse_static_block(p, start);
954 }
955
956 if p.input().syntax().typescript() && !is_abstract && !is_override && accessibility.is_none() {
957 let idx = try_parse_ts_index_signature(p, start, readonly.is_some(), is_static)?;
958 if let Some(idx) = idx {
959 return Ok(idx.into());
960 }
961 }
962
963 if p.input_mut().eat(&P::Token::MUL) {
964 let key = parse_class_prop_name(p)?;
966 if readonly.is_some() {
967 p.emit_err(p.span(start), SyntaxError::ReadOnlyMethod);
968 }
969 if is_constructor(&key) {
970 p.emit_err(p.span(start), SyntaxError::GeneratorConstructor);
971 }
972
973 return make_method(
974 p,
975 parse_unique_formal_params,
976 MakeMethodArgs {
977 start,
978 decorators,
979 is_async: false,
980 is_generator: true,
981 accessibility,
982 is_abstract,
983 is_override,
984 is_optional: false,
985 static_token,
986 key,
987 kind: MethodKind::Method,
988 },
989 );
990 }
991
992 trace_cur!(p, parse_class_member_with_is_static__normal_class_member);
993 let key = if readonly.is_some() && (p.input().cur().is_bang() || p.input().cur().is_colon()) {
994 Key::Public(PropName::Ident(IdentName::new(
995 atom!("readonly"),
996 readonly.unwrap(),
997 )))
998 } else {
999 parse_class_prop_name(p)?
1000 };
1001 let is_optional = p.input().syntax().typescript() && p.input_mut().eat(&P::Token::QUESTION);
1002
1003 if is_class_method(p) {
1004 trace_cur!(p, parse_class_member_with_is_static__normal_class_method);
1007
1008 if let Some(token) = declare_token {
1009 p.emit_err(token, SyntaxError::TS1031)
1010 }
1011
1012 if readonly.is_some() {
1013 syntax_error!(p, p.span(start), SyntaxError::ReadOnlyMethod);
1014 }
1015 let is_constructor = is_constructor(&key);
1016
1017 if is_constructor {
1018 if p.syntax().typescript() && is_override {
1019 p.emit_err(p.span(start), SyntaxError::TS1089(atom!("override")));
1020 }
1021
1022 if p.syntax().typescript() && p.input().is(&P::Token::LESS) {
1023 let start = p.cur_pos();
1024 if peek!(p).is_some_and(|cur| cur.is_less()) {
1025 p.assert_and_bump(&P::Token::LESS);
1026 let start2 = p.cur_pos();
1027 p.assert_and_bump(&P::Token::GREATER);
1028
1029 p.emit_err(p.span(start), SyntaxError::TS1098);
1030 p.emit_err(p.span(start2), SyntaxError::TS1092);
1031 } else {
1032 let type_params = try_parse_ts_type_params(p, false, true)?;
1033
1034 if let Some(type_params) = type_params {
1035 for param in type_params.params {
1036 p.emit_err(param.span(), SyntaxError::TS1092);
1037 }
1038 }
1039 }
1040 }
1041
1042 expect!(p, &P::Token::LPAREN);
1043 let params = parse_constructor_params(p)?;
1044 expect!(p, &P::Token::RPAREN);
1045
1046 if p.syntax().typescript() && p.input().is(&P::Token::COLON) {
1047 let start = p.cur_pos();
1048 let type_ann = parse_ts_type_ann(p, true, start)?;
1049
1050 p.emit_err(type_ann.type_ann.span(), SyntaxError::TS1093);
1051 }
1052
1053 let body: Option<_> =
1054 parse_fn_block_body(p, false, false, false, params.is_simple_parameter_list())?;
1055
1056 if body.is_none() {
1057 for param in params.iter() {
1058 if param.is_ts_param_prop() {
1059 p.emit_err(param.span(), SyntaxError::TS2369)
1060 }
1061 }
1062 }
1063
1064 if p.syntax().typescript() && body.is_none() {
1065 for param in ¶ms {
1067 let span = match *param {
1070 ParamOrTsParamProp::Param(ref param) => match param.pat {
1071 Pat::Assign(ref p) => Some(p.span()),
1072 _ => None,
1073 },
1074 ParamOrTsParamProp::TsParamProp(TsParamProp {
1075 param: TsParamPropParam::Assign(ref p),
1076 ..
1077 }) => Some(p.span()),
1078 _ => None,
1079 };
1080
1081 if let Some(span) = span {
1082 p.emit_err(span, SyntaxError::TS2371)
1083 }
1084 }
1085 }
1086
1087 if let Some(static_token) = static_token {
1088 p.emit_err(static_token, SyntaxError::TS1089(atom!("static")))
1089 }
1090
1091 if let Some(span) = modifier_span {
1092 if is_abstract {
1093 p.emit_err(span, SyntaxError::TS1242);
1094 }
1095 }
1096
1097 return Ok(ClassMember::Constructor(Constructor {
1098 span: p.span(start),
1099 accessibility,
1100 key: match key {
1101 Key::Public(key) => key,
1102 _ => unreachable!("is_constructor() returns false for PrivateName"),
1103 },
1104 is_optional,
1105 params,
1106 body,
1107 ..Default::default()
1108 }));
1109 } else {
1110 return make_method(
1111 p,
1112 parse_formal_params,
1113 MakeMethodArgs {
1114 start,
1115 is_optional,
1116 accessibility,
1117 decorators,
1118 is_abstract,
1119 is_override,
1120 static_token,
1121 kind: MethodKind::Method,
1122 key,
1123 is_async: false,
1124 is_generator: false,
1125 },
1126 );
1127 }
1128 }
1129
1130 let is_next_line_generator =
1131 p.input_mut().had_line_break_before_cur() && p.input().is(&P::Token::MUL);
1132 let getter_or_setter_ident = match key {
1133 Key::Public(PropName::Ident(ref i))
1135 if (i.sym == "get" || i.sym == "set")
1136 && !is_class_property(p, false)
1137 && !is_next_line_generator =>
1138 {
1139 Some(i)
1140 }
1141 _ => None,
1142 };
1143
1144 if getter_or_setter_ident.is_none() && is_class_property(p, true) {
1145 return make_property(
1146 p,
1147 start,
1148 decorators,
1149 accessibility,
1150 key,
1151 is_static,
1152 accessor_token,
1153 is_optional,
1154 readonly.is_some(),
1155 declare,
1156 is_abstract,
1157 is_override,
1158 );
1159 }
1160
1161 if match key {
1162 Key::Public(PropName::Ident(ref i)) => i.sym == "async",
1163 _ => false,
1164 } && !p.input_mut().had_line_break_before_cur()
1165 {
1166 if p.input().syntax().typescript() && parse_ts_modifier(p, &["override"], false)?.is_some()
1169 {
1170 is_override = true;
1171 p.emit_err(
1172 p.input().prev_span(),
1173 SyntaxError::TS1029(atom!("override"), atom!("async")),
1174 );
1175 }
1176
1177 let is_generator = p.input_mut().eat(&P::Token::MUL);
1178 let key = parse_class_prop_name(p)?;
1179 if is_constructor(&key) {
1180 syntax_error!(p, key.span(), SyntaxError::AsyncConstructor)
1181 }
1182 if readonly.is_some() {
1183 syntax_error!(p, p.span(start), SyntaxError::ReadOnlyMethod);
1184 }
1185
1186 let is_optional = is_optional
1188 || p.input().syntax().typescript() && p.input_mut().eat(&P::Token::QUESTION);
1189 return make_method(
1190 p,
1191 parse_unique_formal_params,
1192 MakeMethodArgs {
1193 start,
1194 static_token,
1195 key,
1196 is_abstract,
1197 accessibility,
1198 is_optional,
1199 is_override,
1200 decorators,
1201 kind: MethodKind::Method,
1202 is_async: true,
1203 is_generator,
1204 },
1205 );
1206 }
1207
1208 if let Some(i) = getter_or_setter_ident {
1209 let key_span = key.span();
1210
1211 let key = parse_class_prop_name(p)?;
1213
1214 if readonly.is_some() {
1215 p.emit_err(key_span, SyntaxError::GetterSetterCannotBeReadonly);
1216 }
1217
1218 if is_constructor(&key) {
1219 p.emit_err(key_span, SyntaxError::ConstructorAccessor);
1220 }
1221
1222 return match &*i.sym {
1223 "get" => make_method(
1224 p,
1225 |p| {
1226 let params = parse_formal_params(p)?;
1227
1228 if params.iter().any(is_not_this) {
1229 p.emit_err(key_span, SyntaxError::GetterParam);
1230 }
1231
1232 Ok(params)
1233 },
1234 MakeMethodArgs {
1235 decorators,
1236 start,
1237 is_abstract,
1238 is_async: false,
1239 is_generator: false,
1240 is_optional,
1241 is_override,
1242 accessibility,
1243 static_token,
1244 key,
1245 kind: MethodKind::Getter,
1246 },
1247 ),
1248 "set" => make_method(
1249 p,
1250 |p| {
1251 let params = parse_formal_params(p)?;
1252
1253 if params.iter().filter(|p| is_not_this(p)).count() != 1 {
1254 p.emit_err(key_span, SyntaxError::SetterParam);
1255 }
1256
1257 if !params.is_empty() {
1258 if let Pat::Rest(..) = params[0].pat {
1259 p.emit_err(params[0].pat.span(), SyntaxError::RestPatInSetter);
1260 }
1261 }
1262
1263 Ok(params)
1264 },
1265 MakeMethodArgs {
1266 decorators,
1267 start,
1268 is_optional,
1269 is_abstract,
1270 is_override,
1271 is_async: false,
1272 is_generator: false,
1273 accessibility,
1274 static_token,
1275 key,
1276 kind: MethodKind::Setter,
1277 },
1278 ),
1279 _ => unreachable!(),
1280 };
1281 }
1282
1283 unexpected!(p, "* for generator, private key, identifier or async")
1284}
1285
1286fn parse_class_member<'a, P: Parser<'a>>(p: &mut P) -> PResult<ClassMember> {
1287 trace_cur!(p, parse_class_member);
1288
1289 let start = p.cur_pos();
1290 let decorators = parse_decorators(p, false)?;
1291 let declare = p.syntax().typescript() && p.input_mut().eat(&P::Token::DECLARE);
1292 let accessibility = if p.input().syntax().typescript() {
1293 parse_access_modifier(p)?
1294 } else {
1295 None
1296 };
1297 let declare = declare || p.syntax().typescript() && p.input_mut().eat(&P::Token::DECLARE);
1299
1300 let declare_token = if declare {
1301 if is_class_method(p) {
1303 let key = Key::Public(PropName::Ident(IdentName::new(
1304 atom!("declare"),
1305 p.span(start),
1306 )));
1307 let is_optional =
1308 p.input().syntax().typescript() && p.input_mut().eat(&P::Token::QUESTION);
1309 return make_method(
1310 p,
1311 parse_unique_formal_params,
1312 MakeMethodArgs {
1313 start,
1314 accessibility,
1315 decorators,
1316 is_abstract: false,
1317 is_optional,
1318 is_override: false,
1319 is_async: false,
1320 is_generator: false,
1321 static_token: None,
1322 key,
1323 kind: MethodKind::Method,
1324 },
1325 );
1326 } else if is_class_property(p, true)
1327 || (p.syntax().typescript() && p.input().is(&P::Token::QUESTION))
1328 {
1329 let key = Key::Public(PropName::Ident(IdentName::new(
1332 atom!("declare"),
1333 p.span(start),
1334 )));
1335 let is_optional =
1336 p.input().syntax().typescript() && p.input_mut().eat(&P::Token::QUESTION);
1337 return make_property(
1338 p,
1339 start,
1340 decorators,
1341 accessibility,
1342 key,
1343 false,
1344 None,
1345 is_optional,
1346 false,
1347 false,
1348 false,
1349 false,
1350 );
1351 } else {
1352 Some(p.span(start))
1353 }
1354 } else {
1355 None
1356 };
1357
1358 let static_token = {
1359 let start = p.cur_pos();
1360 if p.input_mut().eat(&P::Token::STATIC) {
1361 Some(p.span(start))
1362 } else {
1363 None
1364 }
1365 };
1366
1367 let accessor_token = if p.syntax().auto_accessors() {
1368 let start = p.cur_pos();
1369 if p.input_mut().eat(&P::Token::ACCESSOR) {
1370 Some(p.span(start))
1371 } else {
1372 None
1373 }
1374 } else {
1375 None
1376 };
1377
1378 if let Some(accessor_token) = accessor_token {
1379 if is_class_method(p) {
1381 let key = Key::Public(PropName::Ident(IdentName::new(
1382 atom!("accessor"),
1383 accessor_token,
1384 )));
1385 let is_optional =
1386 p.input().syntax().typescript() && p.input_mut().eat(&P::Token::QUESTION);
1387 return make_method(
1388 p,
1389 parse_unique_formal_params,
1390 MakeMethodArgs {
1391 start,
1392 accessibility,
1393 decorators,
1394 is_abstract: false,
1395 is_optional,
1396 is_override: false,
1397 is_async: false,
1398 is_generator: false,
1399 static_token,
1400 key,
1401 kind: MethodKind::Method,
1402 },
1403 );
1404 } else if is_class_property(p, true)
1405 || (p.syntax().typescript() && p.input().is(&P::Token::QUESTION))
1406 {
1407 let key = Key::Public(PropName::Ident(IdentName::new(
1410 atom!("accessor"),
1411 accessor_token,
1412 )));
1413 let is_optional =
1414 p.input().syntax().typescript() && p.input_mut().eat(&P::Token::QUESTION);
1415 let is_static = static_token.is_some();
1416 return make_property(
1417 p,
1418 start,
1419 decorators,
1420 accessibility,
1421 key,
1422 is_static,
1423 None,
1424 is_optional,
1425 false,
1426 declare,
1427 false,
1428 false,
1429 );
1430 }
1431 }
1432
1433 if let Some(static_token) = static_token {
1434 if is_class_method(p) {
1436 let key = Key::Public(PropName::Ident(IdentName::new(
1437 atom!("static"),
1438 static_token,
1439 )));
1440 let is_optional =
1441 p.input().syntax().typescript() && p.input_mut().eat(&P::Token::QUESTION);
1442 return make_method(
1443 p,
1444 parse_unique_formal_params,
1445 MakeMethodArgs {
1446 start,
1447 accessibility,
1448 decorators,
1449 is_abstract: false,
1450 is_optional,
1451 is_override: false,
1452 is_async: false,
1453 is_generator: false,
1454 static_token: None,
1455 key,
1456 kind: MethodKind::Method,
1457 },
1458 );
1459 } else if is_class_property(p, false)
1460 || (p.syntax().typescript() && p.input().is(&P::Token::QUESTION))
1461 {
1462 let is_parsing_static_blocks = p.input().is(&P::Token::LBRACE);
1468 if !is_parsing_static_blocks {
1469 let key = Key::Public(PropName::Ident(IdentName::new(
1470 atom!("static"),
1471 static_token,
1472 )));
1473 let is_optional =
1474 p.input().syntax().typescript() && p.input_mut().eat(&P::Token::QUESTION);
1475 return make_property(
1476 p,
1477 start,
1478 decorators,
1479 accessibility,
1480 key,
1481 false,
1482 accessor_token,
1483 is_optional,
1484 false,
1485 declare,
1486 false,
1487 false,
1488 );
1489 }
1490 } else {
1491 }
1493 }
1494
1495 parse_class_member_with_is_static(
1496 p,
1497 start,
1498 declare_token,
1499 accessibility,
1500 static_token,
1501 accessor_token,
1502 decorators,
1503 )
1504}
1505
1506fn parse_class_body<'a, P: Parser<'a>>(p: &mut P) -> PResult<Vec<ClassMember>> {
1507 let mut elems = Vec::with_capacity(32);
1508 let mut has_constructor_with_body = false;
1509 while !p.input().is(&P::Token::RBRACE) {
1510 if p.input_mut().eat(&P::Token::SEMI) {
1511 let span = p.input().prev_span();
1512 debug_assert!(span.lo <= span.hi);
1513 elems.push(ClassMember::Empty(EmptyStmt { span }));
1514 continue;
1515 }
1516 let elem = p.do_inside_of_context(Context::AllowDirectSuper, parse_class_member)?;
1517
1518 if !p.ctx().contains(Context::InDeclare) {
1519 if let ClassMember::Constructor(Constructor {
1520 body: Some(..),
1521 span,
1522 ..
1523 }) = elem
1524 {
1525 if has_constructor_with_body {
1526 p.emit_err(span, SyntaxError::DuplicateConstructor);
1527 }
1528 has_constructor_with_body = true;
1529 }
1530 }
1531 elems.push(elem);
1532 }
1533 Ok(elems)
1534}
1535
1536pub fn parse_class<'a, T>(
1537 p: &mut impl Parser<'a>,
1538 start: BytePos,
1539 class_start: BytePos,
1540 decorators: Vec<Decorator>,
1541 is_abstract: bool,
1542) -> PResult<T>
1543where
1544 T: OutputType,
1545{
1546 let (ident, mut class) = p.do_inside_of_context(Context::InClass, |p| {
1547 parse_class_inner(p, start, class_start, decorators, T::IS_IDENT_REQUIRED)
1548 })?;
1549
1550 if is_abstract {
1551 class.is_abstract = true
1552 } else {
1553 for member in class.body.iter() {
1554 match member {
1555 ClassMember::ClassProp(ClassProp {
1556 is_abstract: true,
1557 span,
1558 ..
1559 })
1560 | ClassMember::Method(ClassMethod {
1561 span,
1562 is_abstract: true,
1563 ..
1564 }) => p.emit_err(*span, SyntaxError::TS1244),
1565 _ => (),
1566 }
1567 }
1568 }
1569
1570 match T::finish_class(p.span(start), ident, class) {
1571 Ok(v) => Ok(v),
1572 Err(kind) => syntax_error!(p, kind),
1573 }
1574}
1575
1576fn parse_class_inner<'a, P: Parser<'a>>(
1578 p: &mut P,
1579 _start: BytePos,
1580 class_start: BytePos,
1581 decorators: Vec<Decorator>,
1582 is_ident_required: bool,
1583) -> PResult<(Option<Ident>, Box<Class>)> {
1584 p.strict_mode(|p| {
1585 expect!(p, &P::Token::CLASS);
1586
1587 let ident = parse_maybe_opt_binding_ident(p, is_ident_required, true)?;
1588 if p.input().syntax().typescript() {
1589 if let Some(span) = ident.invalid_class_name() {
1590 p.emit_err(span, SyntaxError::TS2414);
1591 }
1592 }
1593
1594 let type_params = if p.input().syntax().typescript() {
1595 try_parse_ts_type_params(p, true, true)?
1596 } else {
1597 None
1598 };
1599
1600 let (mut super_class, mut super_type_params) = if p.input_mut().eat(&P::Token::EXTENDS) {
1601 let (super_class, super_type_params) = parse_super_class(p)?;
1602
1603 if p.syntax().typescript() && p.input_mut().eat(&P::Token::COMMA) {
1604 let exprs = parse_ts_heritage_clause(p)?;
1605
1606 for e in &exprs {
1607 p.emit_err(e.span(), SyntaxError::TS1174);
1608 }
1609 }
1610
1611 (Some(super_class), super_type_params)
1612 } else {
1613 (None, None)
1614 };
1615
1616 if p.input_mut().eat(&P::Token::EXTENDS) {
1618 p.emit_err(p.input().prev_span(), SyntaxError::TS1172);
1619
1620 parse_super_class(p)?;
1621 };
1622
1623 let implements =
1624 if p.input().syntax().typescript() && p.input_mut().eat(&P::Token::IMPLEMENTS) {
1625 parse_ts_heritage_clause(p)?
1626 } else {
1627 Vec::with_capacity(4)
1628 };
1629
1630 {
1631 if p.input().syntax().typescript() && p.input_mut().eat(&P::Token::IMPLEMENTS) {
1633 p.emit_err(p.input().prev_span(), SyntaxError::TS1175);
1634
1635 parse_ts_heritage_clause(p)?;
1636 }
1637 }
1638
1639 if p.input().syntax().typescript() && p.input_mut().eat(&P::Token::EXTENDS) {
1641 p.emit_err(p.input().prev_span(), SyntaxError::TS1173);
1642
1643 let (sc, type_params) = parse_super_class(p)?;
1644
1645 if super_class.is_none() {
1646 super_class = Some(sc);
1647 if type_params.is_some() {
1648 super_type_params = type_params;
1649 }
1650 }
1651 }
1652
1653 expect!(p, &P::Token::LBRACE);
1654
1655 let body = if super_class.is_some() {
1656 p.do_inside_of_context(Context::HasSuperClass, parse_class_body)?
1657 } else {
1658 p.do_outside_of_context(Context::HasSuperClass, parse_class_body)?
1659 };
1660
1661 if p.input().cur().is_eof() {
1662 let eof_text = p.input_mut().dump_cur();
1663 p.emit_err(
1664 p.input().cur_span(),
1665 SyntaxError::Expected(format!("{:?}", P::Token::RBRACE), eof_text),
1666 );
1667 } else {
1668 expect!(p, &P::Token::RBRACE);
1669 }
1670
1671 let span = p.span(class_start);
1672 Ok((
1673 ident,
1674 Box::new(Class {
1675 span,
1676 decorators,
1677 is_abstract: false,
1678 type_params,
1679 super_class,
1680 super_type_params,
1681 body,
1682 implements,
1683 ..Default::default()
1684 }),
1685 ))
1686 })
1687}