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 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 }
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 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 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 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 for param in ¶ms {
271 let span = match ¶m.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 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 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(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 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 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(); 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 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 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 for param in ¶ms {
1038 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 Key::Public(PropName::Ident(ref i))
1105 if (i.sym == "get" || i.sym == "set")
1106 && !self.is_class_property(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(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 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 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 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 let declare = declare || self.syntax().typescript() && self.input_mut().eat(Token::Declare);
1266
1267 let declare_token = if declare {
1268 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(true)
1293 || (self.syntax().typescript() && self.input().is(Token::QuestionMark))
1294 {
1295 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 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(true)
1369 || (self.syntax().typescript() && self.input().is(Token::QuestionMark))
1370 {
1371 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 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(false)
1422 || (self.syntax().typescript() && self.input().is(Token::QuestionMark))
1423 {
1424 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 }
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 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 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 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 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 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}