11import type { ArrowFunctionExpression , ClassMethod , ClassPrivateMethod , Expression , FunctionDeclaration , FunctionExpression , Identifier , ImportDeclaration , MemberExpression , ObjectMethod , Pattern , RestElement , Statement , TSEntityName , TSType , TSTypeAnnotation , TSTypeParameterDeclaration , VariableDeclaration } from "@babel/types" ;
22import type { NodePath , PluginObj , PluginPass } from "@babel/core" ;
33import { assignReturnType , assignTypeAnnotation , assignTypeArguments , assignTypeParameters , importName , isTS , nonNullPath } from "./utils.js" ;
4- import { AnalysisError , analyzeBody , analyzeHead , ComponentBody , ComponentHead , needsProps , LibRef } from "./analysis.js" ;
4+ import { AnalysisError , analyzeBody , preanalyzeClass , ComponentBody , PreAnalysisResult , needsProps , LibRef } from "./analysis.js" ;
55
66type Options = { } ;
77
@@ -12,15 +12,15 @@ export default function plugin(babel: typeof import("@babel/core")): PluginObj<P
1212 visitor : {
1313 ClassDeclaration ( path , state ) {
1414 const ts = isTS ( state ) ;
15- const head = analyzeHead ( path ) ;
16- if ( ! head ) {
15+ const preanalysis = preanalyzeClass ( path ) ;
16+ if ( ! preanalysis ) {
1717 return ;
1818 }
1919 if ( path . parentPath . isExportDefaultDeclaration ( ) ) {
2020 const declPath = path . parentPath ;
2121 try {
22- const body = analyzeBody ( path , head ) ;
23- const { funcNode, typeNode } = transformClass ( head , body , { ts } , babel ) ;
22+ const body = analyzeBody ( path , preanalysis ) ;
23+ const { funcNode, typeNode } = transformClass ( preanalysis , body , { ts } , babel ) ;
2424 if ( path . node . id ) {
2525 // Necessary to avoid false error regarding duplicate declaration.
2626 path . scope . removeBinding ( path . node . id . name ) ;
@@ -47,8 +47,8 @@ export default function plugin(babel: typeof import("@babel/core")): PluginObj<P
4747 }
4848 } else {
4949 try {
50- const body = analyzeBody ( path , head ) ;
51- const { funcNode, typeNode } = transformClass ( head , body , { ts } , babel ) ;
50+ const body = analyzeBody ( path , preanalysis ) ;
51+ const { funcNode, typeNode } = transformClass ( preanalysis , body , { ts } , babel ) ;
5252 // Necessary to avoid false error regarding duplicate declaration.
5353 path . scope . removeBinding ( path . node . id . name ) ;
5454 path . replaceWith (
@@ -77,7 +77,7 @@ type TransformResult = {
7777 typeNode ?: TSType | undefined ;
7878} ;
7979
80- function transformClass ( head : ComponentHead , body : ComponentBody , options : { ts : boolean } , babel : typeof import ( "@babel/core" ) ) : TransformResult {
80+ function transformClass ( preanalysis : PreAnalysisResult , body : ComponentBody , options : { ts : boolean } , babel : typeof import ( "@babel/core" ) ) : TransformResult {
8181 const { types : t } = babel ;
8282 const { ts } = options ;
8383
@@ -207,7 +207,7 @@ function transformClass(head: ComponentHead, body: ComponentBody, options: { ts:
207207 for ( const field of body . state . values ( ) ) {
208208 // State declarations
209209 const call = t . callExpression (
210- getReactImport ( "useState" , babel , head . superClassRef ) ,
210+ getReactImport ( "useState" , babel , preanalysis . superClassRef ) ,
211211 field . init ? [ field . init . valuePath . node ] : [ ]
212212 ) ;
213213 preamble . push ( t . variableDeclaration ( "const" , [
@@ -266,7 +266,7 @@ function transformClass(head: ComponentHead, body: ComponentBody, options: { ts:
266266 } else if ( field . type === "user_defined_ref" ) {
267267 // const foo = useRef(null);
268268 const call = t . callExpression (
269- getReactImport ( "useRef" , babel , head . superClassRef ) ,
269+ getReactImport ( "useRef" , babel , preanalysis . superClassRef ) ,
270270 [ t . nullLiteral ( ) ]
271271 ) ;
272272 preamble . push ( t . variableDeclaration (
@@ -286,7 +286,7 @@ function transformClass(head: ComponentHead, body: ComponentBody, options: { ts:
286286 } else if ( field . type === "user_defined_direct_ref" ) {
287287 // const foo = useRef(init);
288288 const call = t . callExpression (
289- getReactImport ( "useRef" , babel , head . superClassRef ) ,
289+ getReactImport ( "useRef" , babel , preanalysis . superClassRef ) ,
290290 [ field . init . node ]
291291 ) ;
292292 preamble . push ( t . variableDeclaration (
@@ -309,26 +309,26 @@ function transformClass(head: ComponentHead, body: ComponentBody, options: { ts:
309309 bodyNode . body . splice ( 0 , 0 , ...preamble ) ;
310310 // recast is not smart enough to correctly pretty-print type parameters for arrow functions.
311311 // so we fall back to functions when type parameters are present.
312- const functionNeeded = head . isPure || ! ! head . typeParameters ;
312+ const functionNeeded = preanalysis . isPure || ! ! preanalysis . typeParameters ;
313313 const params = needsProps ( body )
314314 ? [ assignTypeAnnotation (
315315 t . identifier ( "props" ) ,
316316 // If the function is generic, put type annotations here instead of the `const` to be defined.
317317 // TODO: take children into account, while being careful about difference between `@types/react` v17 and v18
318- head . typeParameters
319- ? head . props
320- ? t . tsTypeAnnotation ( head . props . node )
318+ preanalysis . typeParameters
319+ ? preanalysis . props
320+ ? t . tsTypeAnnotation ( preanalysis . props . node )
321321 : undefined
322322 : undefined
323323 ) ]
324324 : [ ] ;
325325 // If the function is generic, put type annotations here instead of the `const` to be defined.
326- const returnType = head . typeParameters
326+ const returnType = preanalysis . typeParameters
327327 // Construct `React.ReactElement | null`
328328 ? t . tsTypeAnnotation (
329329 t . tsUnionType ( [
330330 t . tsTypeReference (
331- toTSEntity ( getReactImport ( "ReactElement" , babel , head . superClassRef ) , babel )
331+ toTSEntity ( getReactImport ( "ReactElement" , babel , preanalysis . superClassRef ) , babel )
332332 ) ,
333333 t . tsNullKeyword ( ) ,
334334 ] )
@@ -338,7 +338,7 @@ function transformClass(head: ComponentHead, body: ComponentBody, options: { ts:
338338 assignReturnType (
339339 functionNeeded
340340 ? t . functionExpression (
341- head . name ? t . cloneNode ( head . name ) : undefined ,
341+ preanalysis . name ? t . cloneNode ( preanalysis . name ) : undefined ,
342342 params ,
343343 bodyNode
344344 )
@@ -348,20 +348,20 @@ function transformClass(head: ComponentHead, body: ComponentBody, options: { ts:
348348 ) ,
349349 returnType
350350 ) ,
351- head . typeParameters ?. node
351+ preanalysis . typeParameters ?. node
352352 ) ;
353353 return {
354- funcNode : head . isPure
354+ funcNode : preanalysis . isPure
355355 ? t . callExpression (
356- getReactImport ( "memo" , babel , head . superClassRef ) ,
356+ getReactImport ( "memo" , babel , preanalysis . superClassRef ) ,
357357 [ funcNode ]
358358 )
359359 : funcNode ,
360- typeNode : ts && ! head . typeParameters
360+ typeNode : ts && ! preanalysis . typeParameters
361361 ? t . tsTypeReference (
362- toTSEntity ( getReactImport ( "FC" , babel , head . superClassRef ) , babel ) ,
363- head . props
364- ? t . tsTypeParameterInstantiation ( [ head . props . node ] )
362+ toTSEntity ( getReactImport ( "FC" , babel , preanalysis . superClassRef ) , babel ) ,
363+ preanalysis . props
364+ ? t . tsTypeParameterInstantiation ( [ preanalysis . props . node ] )
365365 : null
366366 )
367367 : undefined ,
0 commit comments