11use ego_tree:: { NodeId , Tree , NodeMut , NodeRef } ;
22use html5ever:: { Attribute , tendril:: StrTendril } ;
3- use swc_ecma_ast:: { JSXElement , JSXElementName , JSXAttrOrSpread , JSXAttrName , JSXAttrValue , Lit , JSXExpr , Expr , JSXElementChild , Module , Function , Stmt , ExportDefaultExpr , ExportDefaultDecl , DefaultDecl , ClassDecl , ClassMember , PropName , FnDecl , JSXFragment } ;
3+ use swc_ecma_ast:: { JSXElement , JSXElementName , JSXAttrOrSpread , JSXAttrName , JSXAttrValue , Lit , JSXExpr , Expr , JSXElementChild , Module , Function , Stmt , ExportDefaultExpr , ExportDefaultDecl , DefaultDecl , ClassDecl , ClassMember , PropName , FnDecl , Callee , MemberProp } ;
44use swc_ecma_visit:: { Visit , VisitWith } ;
55
66use crate :: { scraper:: { Node , Element , Fragment } , utils:: { recursion_jsx_member, create_qualname, is_starts_with_uppercase} } ;
@@ -119,14 +119,14 @@ impl<'a> Visit for JSXVisitor<'a> {
119119
120120 fn visit_jsx_element_children ( & mut self , n : & [ JSXElementChild ] ) {
121121 let mut nodes = vec ! [ ] ;
122- let mut elements: Vec < JSXElementChild > = vec ! [ ] ;
122+ let mut elements: Vec < & JSXElementChild > = vec ! [ ] ;
123123 for child in n. iter ( ) {
124124 match child {
125125 JSXElementChild :: JSXElement ( element) => {
126126 if let JSXElementName :: Ident ( ident) = & element. opening . name {
127127 let name = ident. sym . to_string ( ) ;
128128 if is_starts_with_uppercase ( name. as_str ( ) ) {
129- let mut visitor = JSXFragmentVisitor :: new ( self . module , name. as_str ( ) ) ;
129+ let mut visitor = JSXFragmentVisitor :: new ( self . module , name. as_str ( ) , SearchType :: Normal ) ;
130130 self . module . visit_with ( & mut visitor) ;
131131 let mut current = self . tree . get_mut ( self . current_node . unwrap ( ) ) . unwrap ( ) ;
132132 // 将 Fragment 的子节点添加到当前节点
@@ -136,22 +136,66 @@ impl<'a> Visit for JSXVisitor<'a> {
136136 let mut current = self . tree . get_mut ( self . current_node . unwrap ( ) ) . unwrap ( ) ;
137137 let tree_node = current. append ( node) ;
138138 nodes. push ( tree_node. id ( ) ) ;
139- elements. push ( JSXElementChild :: JSXElement ( element . clone ( ) ) ) ;
139+ elements. push ( child ) ;
140140 }
141141 } else {
142142 let node = self . create_element ( element) ;
143143 let mut current = self . tree . get_mut ( self . current_node . unwrap ( ) ) . unwrap ( ) ;
144144 let tree_node = current. append ( node) ;
145145 nodes. push ( tree_node. id ( ) ) ;
146- elements. push ( JSXElementChild :: JSXElement ( element . clone ( ) ) ) ;
146+ elements. push ( child ) ;
147147 }
148148 } ,
149- JSXElementChild :: JSXFragment ( fragment ) => {
149+ JSXElementChild :: JSXFragment ( _ ) => {
150150 let node = self . create_fragment ( ) ;
151151 let mut current = self . tree . get_mut ( self . current_node . unwrap ( ) ) . unwrap ( ) ;
152152 let tree_node = current. append ( node) ;
153153 nodes. push ( tree_node. id ( ) ) ;
154- elements. push ( JSXElementChild :: JSXFragment ( fragment. clone ( ) ) ) ;
154+ elements. push ( child) ;
155+ } ,
156+ // 找到函数调用中的 JSX
157+ JSXElementChild :: JSXExprContainer ( expr) => {
158+ match & expr. expr {
159+ JSXExpr :: JSXEmptyExpr ( _) => { } ,
160+ JSXExpr :: Expr ( expr) => {
161+ match & * * expr {
162+ Expr :: Call ( call_expr) => {
163+ match & call_expr. callee {
164+ Callee :: Expr ( expr) => {
165+ match & * * expr {
166+ Expr :: Ident ( ident) => {
167+ let name = ident. sym . to_string ( ) ;
168+ let mut visitor = JSXFragmentVisitor :: new ( self . module , name. as_str ( ) , SearchType :: Normal ) ;
169+ self . module . visit_with ( & mut visitor) ;
170+ let mut current = self . tree . get_mut ( self . current_node . unwrap ( ) ) . unwrap ( ) ;
171+ // 将 Fragment 的子节点添加到当前节点
172+ recursion_sub_tree ( & visitor. tree . root ( ) , & mut current) ;
173+ } ,
174+ Expr :: Member ( member_expr) => {
175+ if let Expr :: This ( _) = & * member_expr. obj {
176+ match & member_expr. prop {
177+ MemberProp :: Ident ( ident) => {
178+ let name = ident. sym . to_string ( ) ;
179+ let mut visitor = JSXFragmentVisitor :: new ( self . module , name. as_str ( ) , SearchType :: Class ) ;
180+ self . module . visit_with ( & mut visitor) ;
181+ let mut current = self . tree . get_mut ( self . current_node . unwrap ( ) ) . unwrap ( ) ;
182+ // 将 Fragment 的子节点添加到当前节点
183+ recursion_sub_tree ( & visitor. tree . root ( ) , & mut current) ;
184+ } ,
185+ _ => { }
186+ }
187+ }
188+ } ,
189+ _ => { }
190+ }
191+ } ,
192+ _ => { }
193+ }
194+ } ,
195+ _ => { }
196+ }
197+ } ,
198+ }
155199 } ,
156200 _ => { }
157201 }
@@ -165,27 +209,35 @@ impl<'a> Visit for JSXVisitor<'a> {
165209 }
166210}
167211
212+ #[ derive( PartialEq ) ]
213+ pub enum SearchType {
214+ Normal ,
215+ Class
216+ }
217+
168218pub struct JSXFragmentVisitor < ' a > {
169219 pub module : & ' a Module ,
170220 pub tree : Tree < Node > ,
171- pub search_fn : & ' a str
221+ pub search_fn : & ' a str ,
222+ pub search_type : SearchType
172223}
173224
174225impl < ' a > JSXFragmentVisitor < ' a > {
175- pub fn new ( module : & ' a Module , search_fn : & ' a str ) -> Self {
226+ pub fn new ( module : & ' a Module , search_fn : & ' a str , search_type : SearchType ) -> Self {
176227 JSXFragmentVisitor {
177228 module,
178229 tree : Tree :: new ( Node :: Fragment (
179230 Fragment :: new ( Some ( create_qualname ( search_fn) ) )
180231 ) ) ,
181- search_fn
232+ search_fn,
233+ search_type
182234 }
183235 }
184236}
185237
186238impl < ' a > Visit for JSXFragmentVisitor < ' a > {
187239 fn visit_fn_decl ( & mut self , n : & FnDecl ) {
188- if n. ident . sym . to_string ( ) == self . search_fn {
240+ if n. ident . sym . to_string ( ) == self . search_fn && self . search_type == SearchType :: Normal {
189241 match & * n. function {
190242 Function { body : Some ( body) , .. } => {
191243 for stmt in & body. stmts {
@@ -202,6 +254,32 @@ impl<'a> Visit for JSXFragmentVisitor<'a> {
202254 }
203255 }
204256 }
257+
258+ fn visit_class_method ( & mut self , n : & swc_ecma_ast:: ClassMethod ) {
259+ if self . search_type == SearchType :: Class {
260+ match & n. key {
261+ PropName :: Ident ( ident) => {
262+ if ident. sym . to_string ( ) == self . search_fn {
263+ match & * n. function {
264+ Function { body : Some ( body) , .. } => {
265+ for stmt in & body. stmts {
266+ match stmt {
267+ Stmt :: Return ( return_stmt) => {
268+ let mut jsx_visitor = JSXVisitor :: new ( & mut self . tree , self . module ) ;
269+ return_stmt. visit_with ( & mut jsx_visitor) ;
270+ } ,
271+ _ => { }
272+ }
273+ }
274+ } ,
275+ _ => { }
276+ }
277+ }
278+ } ,
279+ _ => { }
280+ }
281+ }
282+ }
205283}
206284
207285pub struct AstVisitor < ' a > {
0 commit comments