@@ -8,11 +8,13 @@ use swc_core::{
8
8
BinExpr , BlockStmt , BlockStmtOrExpr , CallExpr , Callee , CatchClause , Class , ClassExpr ,
9
9
ClassMember , CondExpr , DefaultDecl , DoWhileStmt , ExportDefaultDecl , Expr , ExprOrSpread ,
10
10
ExprStmt , FnExpr , ForHead , ForInStmt , ForOfStmt , ForStmt , Function , GetterProp , Ident , IfStmt ,
11
- KeyValueProp , LabeledStmt , MemberExpr , MemberProp , MetaPropExpr , ModuleDecl , ModuleItem ,
12
- NewExpr , ObjectLit , ObjectPat , ObjectPatProp , OptCall , OptChainExpr , Param , Pat , Prop ,
13
- PropName , PropOrSpread , RestPat , ReturnStmt , SeqExpr , SetterProp , SimpleAssignTarget , Stmt ,
14
- SwitchCase , SwitchStmt , TaggedTpl , ThisExpr , ThrowStmt , Tpl , TryStmt , UnaryExpr , UnaryOp ,
15
- UpdateExpr , VarDeclOrExpr , WhileStmt , WithStmt , YieldExpr ,
11
+ JSXAttr , JSXAttrOrSpread , JSXAttrValue , JSXElement , JSXElementChild , JSXElementName , JSXExpr ,
12
+ JSXExprContainer , JSXFragment , JSXMemberExpr , JSXNamespacedName , JSXObject , KeyValueProp ,
13
+ LabeledStmt , MemberExpr , MemberProp , MetaPropExpr , ModuleDecl , ModuleItem , NewExpr , ObjectLit ,
14
+ ObjectPat , ObjectPatProp , OptCall , OptChainExpr , Param , Pat , Prop , PropName , PropOrSpread ,
15
+ RestPat , ReturnStmt , SeqExpr , SetterProp , SimpleAssignTarget , Stmt , SwitchCase , SwitchStmt ,
16
+ TaggedTpl , ThisExpr , ThrowStmt , Tpl , TryStmt , UnaryExpr , UnaryOp , UpdateExpr , VarDeclOrExpr ,
17
+ WhileStmt , WithStmt , YieldExpr , IdentName ,
16
18
} ,
17
19
} ;
18
20
@@ -431,12 +433,18 @@ impl JavascriptParser<'_> {
431
433
Expr :: Update ( expr) => self . walk_update_expression ( expr) ,
432
434
Expr :: Yield ( expr) => self . walk_yield_expression ( expr) ,
433
435
Expr :: SuperProp ( _) | Expr :: Lit ( _) | Expr :: PrivateName ( _) | Expr :: Invalid ( _) => ( ) ,
436
+ Expr :: JSXMember ( _) | Expr :: JSXNamespacedName ( _) | Expr :: JSXEmpty ( _) => {
437
+ self . ensure_jsx_enabled ( ) ;
438
+ }
439
+ Expr :: JSXElement ( element) => {
440
+ self . ensure_jsx_enabled ( ) ;
441
+ self . walk_jsx_element ( element) ;
442
+ }
443
+ Expr :: JSXFragment ( fragment) => {
444
+ self . ensure_jsx_enabled ( ) ;
445
+ self . walk_jsx_fragment ( fragment) ;
446
+ }
434
447
Expr :: Paren ( _)
435
- | Expr :: JSXMember ( _)
436
- | Expr :: JSXNamespacedName ( _)
437
- | Expr :: JSXEmpty ( _)
438
- | Expr :: JSXElement ( _)
439
- | Expr :: JSXFragment ( _)
440
448
| Expr :: TsTypeAssertion ( _)
441
449
| Expr :: TsConstAssertion ( _)
442
450
| Expr :: TsNonNull ( _)
@@ -516,6 +524,103 @@ impl JavascriptParser<'_> {
516
524
}
517
525
}
518
526
527
+ fn ensure_jsx_enabled ( & self ) {
528
+ if !self . javascript_options . jsx . unwrap_or_default ( ) {
529
+ unreachable ! ( ) ;
530
+ }
531
+ }
532
+
533
+ fn walk_jsx_element ( & mut self , element : & JSXElement ) {
534
+ self . walk_jsx_element_name ( & element. opening . name ) ;
535
+ if element. opening . type_args . is_some ( ) {
536
+ // JSX type arguments only exist in TSX; this walker assumes pure JSX input.
537
+ unreachable ! ( ) ;
538
+ }
539
+ for attr in & element. opening . attrs {
540
+ self . walk_jsx_attr_or_spread ( attr) ;
541
+ }
542
+ for child in & element. children {
543
+ self . walk_jsx_child ( child) ;
544
+ }
545
+ if let Some ( closing) = & element. closing {
546
+ self . walk_jsx_element_name ( & closing. name ) ;
547
+ }
548
+ }
549
+
550
+ fn walk_jsx_fragment ( & mut self , fragment : & JSXFragment ) {
551
+ for child in & fragment. children {
552
+ self . walk_jsx_child ( child) ;
553
+ }
554
+ }
555
+
556
+ fn walk_jsx_child ( & mut self , child : & JSXElementChild ) {
557
+ match child {
558
+ JSXElementChild :: JSXElement ( element) => self . walk_jsx_element ( element) ,
559
+ JSXElementChild :: JSXFragment ( fragment) => self . walk_jsx_fragment ( fragment) ,
560
+ JSXElementChild :: JSXExprContainer ( container) => self . walk_jsx_expr_container ( container) ,
561
+ JSXElementChild :: JSXSpreadChild ( spread) => self . walk_expression ( & spread. expr ) ,
562
+ JSXElementChild :: JSXText ( _) => ( ) ,
563
+ }
564
+ }
565
+
566
+ fn walk_jsx_expr_container ( & mut self , container : & JSXExprContainer ) {
567
+ match & container. expr {
568
+ JSXExpr :: Expr ( expr) => self . walk_expression ( expr) ,
569
+ JSXExpr :: JSXEmptyExpr ( _) => ( ) ,
570
+ }
571
+ }
572
+
573
+ fn walk_jsx_attr_or_spread ( & mut self , attr : & JSXAttrOrSpread ) {
574
+ match attr {
575
+ JSXAttrOrSpread :: JSXAttr ( attr) => self . walk_jsx_attr ( attr) ,
576
+ JSXAttrOrSpread :: SpreadElement ( spread) => self . walk_expression ( & spread. expr ) ,
577
+ }
578
+ }
579
+
580
+ fn walk_jsx_attr ( & mut self , attr : & JSXAttr ) {
581
+ if let Some ( value) = & attr. value {
582
+ self . walk_jsx_attr_value ( value) ;
583
+ }
584
+ }
585
+
586
+ fn walk_jsx_attr_value ( & mut self , value : & JSXAttrValue ) {
587
+ match value {
588
+ JSXAttrValue :: Lit ( _) => ( ) ,
589
+ JSXAttrValue :: JSXExprContainer ( container) => self . walk_jsx_expr_container ( container) ,
590
+ JSXAttrValue :: JSXElement ( element) => self . walk_jsx_element ( element) ,
591
+ JSXAttrValue :: JSXFragment ( fragment) => self . walk_jsx_fragment ( fragment) ,
592
+ }
593
+ }
594
+
595
+ fn walk_jsx_element_name ( & mut self , name : & JSXElementName ) {
596
+ match name {
597
+ JSXElementName :: Ident ( ident) => self . walk_identifier ( ident) ,
598
+ JSXElementName :: JSXMemberExpr ( member) => self . walk_jsx_member_expr ( member) ,
599
+ JSXElementName :: JSXNamespacedName ( namespaced) => self . walk_jsx_namespaced_name ( namespaced) ,
600
+ }
601
+ }
602
+
603
+ fn walk_jsx_member_expr ( & mut self , member : & JSXMemberExpr ) {
604
+ self . walk_jsx_object ( & member. obj ) ;
605
+ }
606
+
607
+ fn walk_jsx_object ( & mut self , obj : & JSXObject ) {
608
+ match obj {
609
+ JSXObject :: Ident ( ident) => self . walk_identifier ( ident) ,
610
+ JSXObject :: JSXMemberExpr ( member) => self . walk_jsx_member_expr ( member) ,
611
+ }
612
+ }
613
+
614
+ fn walk_jsx_namespaced_name ( & mut self , name : & JSXNamespacedName ) {
615
+ self . walk_ident_name ( & name. ns ) ;
616
+ self . walk_ident_name ( & name. name ) ;
617
+ }
618
+
619
+ fn walk_ident_name ( & mut self , name : & IdentName ) {
620
+ let ident: Ident = name. clone ( ) . into ( ) ;
621
+ self . walk_identifier ( & ident) ;
622
+ }
623
+
519
624
fn walk_object_expression ( & mut self , expr : & ObjectLit ) {
520
625
for prop in & expr. props {
521
626
self . walk_property_or_spread ( prop) ;
0 commit comments