11import checkValidOptions from './options'
22
3- export default function ( { types : t } ) {
3+ function isReactFragment ( openingElement ) {
4+ return (
5+ openingElement . node . name . name === 'Fragment' ||
6+ ( openingElement . node . name . type === 'JSXMemberExpression' &&
7+ openingElement . node . name . object . name === 'React' &&
8+ openingElement . node . name . property . name === 'Fragment' )
9+ ) ;
10+ }
11+
12+ function functionBodyPushAttributes ( t , path , options , componentName ) {
13+ let openingElement = null
14+ const functionBody = path . get ( 'body' ) . get ( 'body' )
15+ if ( functionBody . parent && functionBody . parent . type === 'JSXElement' ) {
16+ const jsxElement = functionBody . find ( ( c ) => {
17+ return c . type === 'JSXElement'
18+ } )
19+ if ( ! jsxElement ) return
20+ openingElement = jsxElement . get ( 'openingElement' )
21+ } else {
22+ const returnStatement = functionBody . find ( ( c ) => {
23+ return c . type === 'ReturnStatement'
24+ } )
25+ if ( ! returnStatement ) return
26+
27+ const arg = returnStatement . get ( 'argument' )
28+ if ( ! arg . isJSXElement ( ) ) return
29+
30+ openingElement = arg . get ( 'openingElement' )
31+ }
32+
33+ if ( ! openingElement ) return
34+ if ( isReactFragment ( openingElement ) ) return
35+
36+ openingElement . node . attributes . push (
37+ t . jSXAttribute (
38+ t . jSXIdentifier ( options . attribute ) ,
39+ t . stringLiteral ( options . format ( componentName ) )
40+ )
41+ )
42+ }
43+
44+ export default function ( { types : t } ) {
445 return {
546 visitor : {
47+ FunctionDeclaration ( path , state ) {
48+ if ( ! path . node . id || ! path . node . id . name ) return ;
49+
50+ const options = checkValidOptions ( state )
51+ const componentName = path . node . id . name
52+
53+ functionBodyPushAttributes ( t , path , options , componentName )
54+ } ,
655 ArrowFunctionExpression ( path , state ) {
756 const options = checkValidOptions ( state )
857 if ( ! path . parent . id || ! path . parent . id . name ) return
958 const componentName = path . parent . id . name
1059
11- const functionBody = path . get ( 'body' ) . get ( 'body' )
12- const returnStatement = functionBody . find (
13- c => c . type === 'ReturnStatement'
14- )
15- const arg = returnStatement . get ( 'argument' )
16- if ( ! arg . isJSXElement ( ) ) return
17-
18- let openingElement = arg . get ( 'openingElement' )
19- openingElement . node . attributes . push (
20- t . jSXAttribute (
21- t . jSXIdentifier ( options . attribute ) ,
22- t . stringLiteral ( options . format ( componentName ) )
23- )
24- )
60+ functionBodyPushAttributes ( t , path , options , componentName )
2561 } ,
2662 ClassDeclaration ( path , state ) {
2763 let name = path . get ( 'id' )
@@ -45,7 +81,9 @@ export default function ({ types: t }) {
4581 const arg = returnStatement . get ( 'argument' )
4682 if ( ! arg . isJSXElement ( ) ) return
4783
48- let openingElement = arg . get ( 'openingElement' )
84+ const openingElement = arg . get ( 'openingElement' )
85+ if ( isReactFragment ( openingElement ) ) return
86+
4987 openingElement . node . attributes . push (
5088 t . jSXAttribute (
5189 t . jSXIdentifier ( options . attribute ) ,
0 commit comments