1- import type { ArrowFunctionExpression , ClassMethod , ClassPrivateMethod , Expression , FunctionDeclaration , FunctionExpression , Identifier , ImportDeclaration , MemberExpression , ObjectMethod , Pattern , RestElement , Statement , TSEntityName , TSType , TSTypeAnnotation } from "@babel/types" ;
1+ import 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" ;
44import { AnalysisError , analyzeBody , analyzeHead , ComponentBody , ComponentHead , needsProps , LibRef } from "./analysis.js" ;
@@ -22,18 +22,15 @@ export default function plugin(babel: typeof import("@babel/core")): PluginObj<P
2222 const body = analyzeBody ( path , head ) ;
2323 const { funcNode, typeNode } = transformClass ( head , body , { ts } , babel ) ;
2424 if ( path . node . id ) {
25+ // Necessary to avoid false error regarding duplicate declaration.
26+ path . scope . removeBinding ( path . node . id . name ) ;
2527 declPath . replaceWithMultiple ( [
26- t . variableDeclaration ( "const" , [
27- t . variableDeclarator (
28- typeNode
29- ? assignTypeAnnotation (
30- t . cloneNode ( path . node . id ) ,
31- t . tsTypeAnnotation ( typeNode ) ,
32- )
33- : t . cloneNode ( path . node . id ) ,
34- funcNode ,
35- )
36- ] ) ,
28+ constDeclaration (
29+ babel ,
30+ t . cloneNode ( path . node . id ) ,
31+ funcNode ,
32+ typeNode ? t . tsTypeAnnotation ( typeNode ) : undefined
33+ ) ,
3734 t . exportDefaultDeclaration (
3835 t . cloneNode ( path . node . id )
3936 )
@@ -52,17 +49,16 @@ export default function plugin(babel: typeof import("@babel/core")): PluginObj<P
5249 try {
5350 const body = analyzeBody ( path , head ) ;
5451 const { funcNode, typeNode } = transformClass ( head , body , { ts } , babel ) ;
55- path . replaceWith ( t . variableDeclaration ( "const" , [
56- t . variableDeclarator (
57- typeNode
58- ? assignTypeAnnotation (
59- t . cloneNode ( path . node . id ) ,
60- t . tsTypeAnnotation ( typeNode ) ,
61- )
62- : t . cloneNode ( path . node . id ) ,
52+ // Necessary to avoid false error regarding duplicate declaration.
53+ path . scope . removeBinding ( path . node . id . name ) ;
54+ path . replaceWith (
55+ constDeclaration (
56+ babel ,
57+ t . cloneNode ( path . node . id ) ,
6358 funcNode ,
59+ typeNode ? t . tsTypeAnnotation ( typeNode ) : undefined
6460 )
65- ] ) ) ;
61+ ) ;
6662 } catch ( e ) {
6763 if ( ! ( e instanceof AnalysisError ) ) {
6864 throw e ;
@@ -437,19 +433,22 @@ function functionDeclarationFrom(
437433 name ?: Identifier | null
438434) {
439435 const { types : t } = babel ;
440- return assignReturnType (
441- t . functionDeclaration (
442- name ?? functionName ( node ) ,
443- node . params as ( Identifier | RestElement | Pattern ) [ ] ,
444- node . body . type === "BlockStatement"
445- ? node . body
446- : t . blockStatement ( [
447- t . returnStatement ( node . body )
448- ] ) ,
449- node . generator ,
450- node . async ,
436+ return assignTypeParameters (
437+ assignReturnType (
438+ t . functionDeclaration (
439+ name ?? functionName ( node ) ,
440+ node . params as ( Identifier | RestElement | Pattern ) [ ] ,
441+ node . body . type === "BlockStatement"
442+ ? node . body
443+ : t . blockStatement ( [
444+ t . returnStatement ( node . body )
445+ ] ) ,
446+ node . generator ,
447+ node . async ,
448+ ) ,
449+ node . returnType
451450 ) ,
452- node . returnType
451+ node . typeParameters as TSTypeParameterDeclaration | null | undefined
453452 ) ;
454453}
455454
@@ -459,19 +458,22 @@ function functionExpressionFrom(
459458 name ?: Identifier | null
460459) {
461460 const { types : t } = babel ;
462- return assignReturnType (
463- t . functionExpression (
464- name ?? functionName ( node ) ,
465- node . params as ( Identifier | RestElement | Pattern ) [ ] ,
466- node . body . type === "BlockStatement"
467- ? node . body
468- : t . blockStatement ( [
469- t . returnStatement ( node . body )
470- ] ) ,
471- node . generator ,
472- node . async ,
461+ return assignTypeParameters (
462+ assignReturnType (
463+ t . functionExpression (
464+ name ?? functionName ( node ) ,
465+ node . params as ( Identifier | RestElement | Pattern ) [ ] ,
466+ node . body . type === "BlockStatement"
467+ ? node . body
468+ : t . blockStatement ( [
469+ t . returnStatement ( node . body )
470+ ] ) ,
471+ node . generator ,
472+ node . async ,
473+ ) ,
474+ node . returnType
473475 ) ,
474- node . returnType
476+ node . typeParameters as TSTypeParameterDeclaration | null | undefined
475477 ) ;
476478}
477479
@@ -480,13 +482,39 @@ function arrowFunctionExpressionFrom(
480482 node : FunctionLike
481483) {
482484 const { types : t } = babel ;
483- return assignReturnType (
484- t . arrowFunctionExpression (
485- node . params as ( Identifier | RestElement | Pattern ) [ ] ,
486- node . body ,
487- node . async ,
485+ return assignTypeParameters (
486+ assignReturnType (
487+ t . arrowFunctionExpression (
488+ node . params as ( Identifier | RestElement | Pattern ) [ ] ,
489+ node . body ,
490+ node . async ,
491+ ) ,
492+ node . returnType
488493 ) ,
489- node . returnType
494+ node . typeParameters as TSTypeParameterDeclaration | null | undefined
495+ ) ;
496+ }
497+
498+ function constDeclaration (
499+ babel : typeof import ( "@babel/core" ) ,
500+ id : Identifier ,
501+ init : Expression ,
502+ typeAnnotation ?: TSTypeAnnotation ,
503+ ) : VariableDeclaration | FunctionDeclaration {
504+ const { types : t } = babel ;
505+ if (
506+ init . type === "FunctionExpression"
507+ && ( ! init . id || init . id . name === id . name )
508+ && ! typeAnnotation
509+ ) {
510+ return functionDeclarationFrom ( babel , init , id ) ;
511+ }
512+ return t . variableDeclaration (
513+ "const" ,
514+ [ t . variableDeclarator (
515+ assignTypeAnnotation ( id , typeAnnotation ) ,
516+ init
517+ ) ]
490518 ) ;
491519}
492520
0 commit comments