@@ -4,7 +4,11 @@ use oxc_span::GetSpan;
44use rustc_hash:: FxHashMap ;
55
66use super :: FunctionKind ;
7- use crate :: { Context , ParserImpl , diagnostics, lexer:: Kind , modifiers:: Modifiers } ;
7+ use crate :: {
8+ Context , ParserImpl , diagnostics,
9+ lexer:: Kind ,
10+ modifiers:: { Modifier , ModifierFlags , ModifierKind , Modifiers } ,
11+ } ;
812
913#[ derive( Debug , Clone , Copy , PartialEq , Eq ) ]
1014enum ImportOrExport {
@@ -548,78 +552,127 @@ impl<'a> ParserImpl<'a> {
548552 decorators : Vec < ' a , Decorator < ' a > > ,
549553 ) -> Box < ' a , ExportDefaultDeclaration < ' a > > {
550554 let exported = self . parse_keyword_identifier ( Kind :: Default ) ;
555+ let declaration = self . parse_export_default_declaration_kind ( decorators) ;
556+ let exported = ModuleExportName :: IdentifierName ( exported) ;
557+ let span = self . end_span ( span) ;
558+ self . ast . alloc_export_default_declaration ( span, exported, declaration)
559+ }
560+
561+ fn parse_export_default_declaration_kind (
562+ & mut self ,
563+ mut decorators : Vec < ' a , Decorator < ' a > > ,
564+ ) -> ExportDefaultDeclarationKind < ' a > {
551565 let decl_span = self . start_span ( ) ;
566+
567+ // export default /* @__NO_SIDE_EFFECTS__ */ ...
552568 let has_no_side_effects_comment =
553569 self . lexer . trivia_builder . previous_token_has_no_side_effects_comment ( ) ;
554- let kind = self . cur_kind ( ) ;
555- if kind != Kind :: Class {
556- for decorator in & decorators {
557- self . error ( diagnostics:: decorators_are_not_valid_here ( decorator. span ) ) ;
570+
571+ // export default @decorator ...
572+ if self . at ( Kind :: At ) {
573+ let after_export_decorators = self . parse_decorators ( ) ;
574+ // @decorator export default @decorator ...
575+ if !decorators. is_empty ( ) {
576+ for decorator in & after_export_decorators {
577+ self . error ( diagnostics:: decorators_in_export_and_class ( decorator. span ) ) ;
578+ }
558579 }
580+ decorators. extend ( after_export_decorators) ;
559581 }
560- let declaration = match kind {
561- Kind :: Class => ExportDefaultDeclarationKind :: ClassDeclaration (
562- self . parse_class_declaration ( decl_span, & Modifiers :: empty ( ) , decorators) ,
563- ) ,
564- Kind :: At => {
565- let decorators = self . parse_decorators ( ) ;
566- let modifiers = self . parse_modifiers ( false , false ) ;
567- ExportDefaultDeclarationKind :: ClassDeclaration (
568- self . parse_class_declaration ( decl_span, & modifiers, decorators) ,
569- )
570- }
571- _ if self . is_ts
572- && self . at ( Kind :: Abstract )
573- && self . lookahead ( |p| {
574- p. bump_any ( ) ;
575- p. at ( Kind :: Class )
576- } ) =>
577- {
578- // `export default abstract class ...`
579- // eat the abstract modifier
580- let modifiers = self . eat_modifiers_before_declaration ( ) ;
581- ExportDefaultDeclarationKind :: ClassDeclaration ( self . parse_class_declaration (
582- decl_span,
583- & modifiers,
584- self . ast . vec ( ) ,
585- ) )
586- }
587- _ if self . is_ts
588- && self . at ( Kind :: Interface )
589- && self . lookahead ( |p| {
590- p. bump_any ( ) ;
591- !p. cur_token ( ) . is_on_new_line ( )
592- } ) =>
593- {
594- // `export default interface [no line break here] ...`
595- let decl = self . parse_ts_interface_declaration ( decl_span, & Modifiers :: empty ( ) ) ;
596- match decl {
597- Declaration :: TSInterfaceDeclaration ( decl) => {
598- ExportDefaultDeclarationKind :: TSInterfaceDeclaration ( decl)
582+
583+ let function_span = self . start_span ( ) ;
584+
585+ let checkpoint = self . checkpoint ( ) ;
586+ let mut is_abstract = false ;
587+ let mut is_async = false ;
588+ let mut is_interface = false ;
589+
590+ match self . cur_kind ( ) {
591+ Kind :: Abstract => is_abstract = true ,
592+ Kind :: Async => is_async = true ,
593+ Kind :: Interface => is_interface = true ,
594+ _ => { }
595+ }
596+
597+ if is_abstract || is_async || is_interface {
598+ let modifier_span = self . start_span ( ) ;
599+ self . bump_any ( ) ;
600+ let cur_token = self . cur_token ( ) ;
601+ let kind = cur_token. kind ( ) ;
602+ if !cur_token. is_on_new_line ( ) {
603+ // export default abstract class ...
604+ if is_abstract && kind == Kind :: Class {
605+ let modifiers = self
606+ . ast
607+ . vec1 ( Modifier :: new ( self . end_span ( modifier_span) , ModifierKind :: Abstract ) ) ;
608+ let modifiers = Modifiers :: new ( Some ( modifiers) , ModifierFlags :: ABSTRACT ) ;
609+ return ExportDefaultDeclarationKind :: ClassDeclaration (
610+ self . parse_class_declaration ( decl_span, & modifiers, decorators) ,
611+ ) ;
612+ }
613+
614+ // export default async function ...
615+ if is_async && kind == Kind :: Function {
616+ for decorator in & decorators {
617+ self . error ( diagnostics:: decorators_are_not_valid_here ( decorator. span ) ) ;
599618 }
600- _ => unreachable ! ( ) ,
619+ let mut func = self . parse_function_impl (
620+ function_span,
621+ /* r#async */ true ,
622+ FunctionKind :: DefaultExport ,
623+ ) ;
624+ if has_no_side_effects_comment {
625+ func. pure = true ;
626+ }
627+ return ExportDefaultDeclarationKind :: FunctionDeclaration ( func) ;
601628 }
602- }
603- _ if self . at_function_with_async ( ) => {
604- let span = self . start_span ( ) ;
605- let r#async = self . eat ( Kind :: Async ) ;
606- let mut func = self . parse_function_impl ( span, r#async, FunctionKind :: DefaultExport ) ;
607- if has_no_side_effects_comment {
608- func. pure = true ;
629+
630+ // export default interface ...
631+ if is_interface {
632+ for decorator in & decorators {
633+ self . error ( diagnostics:: decorators_are_not_valid_here ( decorator. span ) ) ;
634+ }
635+ if let Declaration :: TSInterfaceDeclaration ( decl) =
636+ self . parse_ts_interface_declaration ( modifier_span, & Modifiers :: empty ( ) )
637+ {
638+ return ExportDefaultDeclarationKind :: TSInterfaceDeclaration ( decl) ;
639+ }
609640 }
610- ExportDefaultDeclarationKind :: FunctionDeclaration ( func)
611641 }
612- _ => {
613- let decl = ExportDefaultDeclarationKind :: from (
614- self . parse_assignment_expression_or_higher ( ) ,
615- ) ;
616- self . asi ( ) ;
617- decl
642+ self . rewind ( checkpoint) ;
643+ }
644+
645+ let kind = self . cur_kind ( ) ;
646+ // export default class ...
647+ if kind == Kind :: Class {
648+ return ExportDefaultDeclarationKind :: ClassDeclaration ( self . parse_class_declaration (
649+ decl_span,
650+ & Modifiers :: empty ( ) ,
651+ decorators,
652+ ) ) ;
653+ }
654+
655+ for decorator in & decorators {
656+ self . error ( diagnostics:: decorators_are_not_valid_here ( decorator. span ) ) ;
657+ }
658+
659+ // export default function ...
660+ if kind == Kind :: Function {
661+ let mut func = self . parse_function_impl (
662+ function_span,
663+ /* r#async */ false ,
664+ FunctionKind :: DefaultExport ,
665+ ) ;
666+ if has_no_side_effects_comment {
667+ func. pure = true ;
618668 }
619- } ;
620- let exported = ModuleExportName :: IdentifierName ( exported) ;
621- let span = self . end_span ( span) ;
622- self . ast . alloc_export_default_declaration ( span, exported, declaration)
669+ return ExportDefaultDeclarationKind :: FunctionDeclaration ( func) ;
670+ }
671+
672+ // export default expr
673+ let decl = ExportDefaultDeclarationKind :: from ( self . parse_assignment_expression_or_higher ( ) ) ;
674+ self . asi ( ) ;
675+ decl
623676 }
624677
625678 // export ExportFromClause FromClause ;
0 commit comments