@@ -11,71 +11,12 @@ import {
1111import { codeFrameColumns } from '@babel/code-frame' ;
1212import { addNamed } from '@babel/helper-module-imports' ;
1313
14- function getTypeAnnotation ( node : BabelCore . types . Node ) {
15- if (
16- 'typeAnnotation' in node &&
17- node . typeAnnotation &&
18- node . typeAnnotation . type === 'TSTypeAnnotation'
19- ) {
20- return node . typeAnnotation . typeAnnotation ;
21- }
22- }
23-
2414export default ( {
2515 types : t ,
2616} : typeof BabelCore ) : BabelCore . PluginObj < SimpleTypeResolveOptions > => {
2717 let ctx : SimpleTypeResolveContext | undefined ;
2818 let helpers : Set < string > | undefined ;
2919
30- function processProps (
31- comp : BabelCore . types . Function ,
32- options : BabelCore . types . ObjectExpression
33- ) {
34- const props = comp . params [ 0 ] ;
35- if ( ! props ) return ;
36-
37- if ( props . type === 'AssignmentPattern' ) {
38- ctx ! . propsTypeDecl = getTypeAnnotation ( props . left ) ;
39- ctx ! . propsRuntimeDefaults = props . right ;
40- } else {
41- ctx ! . propsTypeDecl = getTypeAnnotation ( props ) ;
42- }
43-
44- if ( ! ctx ! . propsTypeDecl ) return ;
45-
46- const runtimeProps = extractRuntimeProps ( ctx ! ) ;
47- if ( ! runtimeProps ) {
48- return ;
49- }
50-
51- const ast = parseExpression ( runtimeProps ) ;
52- options . properties . push ( t . objectProperty ( t . identifier ( 'props' ) , ast ) ) ;
53- }
54-
55- function processEmits (
56- comp : BabelCore . types . Function ,
57- options : BabelCore . types . ObjectExpression
58- ) {
59- const setupCtx = comp . params [ 1 ] && getTypeAnnotation ( comp . params [ 1 ] ) ;
60- if (
61- ! setupCtx ||
62- ! t . isTSTypeReference ( setupCtx ) ||
63- ! t . isIdentifier ( setupCtx . typeName , { name : 'SetupContext' } )
64- )
65- return ;
66-
67- const emitType = setupCtx . typeParameters ?. params [ 0 ] ;
68- if ( ! emitType ) return ;
69-
70- ctx ! . emitsTypeDecl = emitType ;
71- const runtimeEmits = extractRuntimeEmits ( ctx ! ) ;
72-
73- const ast = t . arrayExpression (
74- Array . from ( runtimeEmits ) . map ( ( e ) => t . stringLiteral ( e ) )
75- ) ;
76- options . properties . push ( t . objectProperty ( t . identifier ( 'emits' ) , ast ) ) ;
77- }
78-
7920 return {
8021 name : 'babel-plugin-resolve-type' ,
8122 inherits : typescript ,
@@ -125,8 +66,10 @@ export default ({
12566 ) ;
12667 }
12768
128- const node = path . node ;
69+ const { node } = path ;
70+
12971 if ( ! t . isIdentifier ( node . callee , { name : 'defineComponent' } ) ) return ;
72+ if ( ! checkDefineComponent ( path ) ) return ;
13073
13174 const comp = node . arguments [ 0 ] ;
13275 if ( ! comp || ! t . isFunction ( comp ) ) return ;
@@ -137,14 +80,11 @@ export default ({
13780 node . arguments . push ( options ) ;
13881 }
13982
140- if ( ! t . isObjectExpression ( options ) ) {
141- throw new Error (
142- '[@vue/babel-plugin-resolve-type] Options inside of defineComponent should be an object expression.'
143- ) ;
144- }
145-
146- processProps ( comp , options ) ;
147- processEmits ( comp , options ) ;
83+ node . arguments [ 1 ] = processProps ( comp , options ) || options ;
84+ node . arguments [ 1 ] = processEmits ( comp , node . arguments [ 1 ] ) || options ;
85+ } ,
86+ VariableDeclarator ( path ) {
87+ inferComponentName ( path ) ;
14888 } ,
14989 } ,
15090 post ( file ) {
@@ -153,4 +93,128 @@ export default ({
15393 }
15494 } ,
15595 } ;
96+
97+ function inferComponentName (
98+ path : BabelCore . NodePath < BabelCore . types . VariableDeclarator >
99+ ) {
100+ const id = path . get ( 'id' ) ;
101+ const init = path . get ( 'init' ) ;
102+ if ( ! id || ! id . isIdentifier ( ) || ! init || ! init . isCallExpression ( ) ) return ;
103+
104+ if ( ! init . get ( 'callee' ) ?. isIdentifier ( { name : 'defineComponent' } ) ) return ;
105+ if ( ! checkDefineComponent ( init ) ) return ;
106+
107+ const nameProperty = t . objectProperty (
108+ t . identifier ( 'name' ) ,
109+ t . stringLiteral ( id . node . name )
110+ ) ;
111+ const { arguments : args } = init . node ;
112+ if ( args . length === 0 ) return ;
113+
114+ if ( args . length === 1 ) {
115+ init . node . arguments . push ( t . objectExpression ( [ ] ) ) ;
116+ }
117+ args [ 1 ] = addProperty ( t , args [ 1 ] , nameProperty ) ;
118+ }
119+
120+ function processProps (
121+ comp : BabelCore . types . Function ,
122+ options :
123+ | BabelCore . types . ArgumentPlaceholder
124+ | BabelCore . types . JSXNamespacedName
125+ | BabelCore . types . SpreadElement
126+ | BabelCore . types . Expression
127+ ) {
128+ const props = comp . params [ 0 ] ;
129+ if ( ! props ) return ;
130+
131+ if ( props . type === 'AssignmentPattern' ) {
132+ ctx ! . propsTypeDecl = getTypeAnnotation ( props . left ) ;
133+ ctx ! . propsRuntimeDefaults = props . right ;
134+ } else {
135+ ctx ! . propsTypeDecl = getTypeAnnotation ( props ) ;
136+ }
137+
138+ if ( ! ctx ! . propsTypeDecl ) return ;
139+
140+ const runtimeProps = extractRuntimeProps ( ctx ! ) ;
141+ if ( ! runtimeProps ) {
142+ return ;
143+ }
144+
145+ const ast = parseExpression ( runtimeProps ) ;
146+ return addProperty (
147+ t ,
148+ options ,
149+ t . objectProperty ( t . identifier ( 'props' ) , ast )
150+ ) ;
151+ }
152+
153+ function processEmits (
154+ comp : BabelCore . types . Function ,
155+ options :
156+ | BabelCore . types . ArgumentPlaceholder
157+ | BabelCore . types . JSXNamespacedName
158+ | BabelCore . types . SpreadElement
159+ | BabelCore . types . Expression
160+ ) {
161+ const setupCtx = comp . params [ 1 ] && getTypeAnnotation ( comp . params [ 1 ] ) ;
162+ if (
163+ ! setupCtx ||
164+ ! t . isTSTypeReference ( setupCtx ) ||
165+ ! t . isIdentifier ( setupCtx . typeName , { name : 'SetupContext' } )
166+ )
167+ return ;
168+
169+ const emitType = setupCtx . typeParameters ?. params [ 0 ] ;
170+ if ( ! emitType ) return ;
171+
172+ ctx ! . emitsTypeDecl = emitType ;
173+ const runtimeEmits = extractRuntimeEmits ( ctx ! ) ;
174+
175+ const ast = t . arrayExpression (
176+ Array . from ( runtimeEmits ) . map ( ( e ) => t . stringLiteral ( e ) )
177+ ) ;
178+ return addProperty (
179+ t ,
180+ options ,
181+ t . objectProperty ( t . identifier ( 'emits' ) , ast )
182+ ) ;
183+ }
156184} ;
185+
186+ function getTypeAnnotation ( node : BabelCore . types . Node ) {
187+ if (
188+ 'typeAnnotation' in node &&
189+ node . typeAnnotation &&
190+ node . typeAnnotation . type === 'TSTypeAnnotation'
191+ ) {
192+ return node . typeAnnotation . typeAnnotation ;
193+ }
194+ }
195+
196+ function checkDefineComponent (
197+ path : BabelCore . NodePath < BabelCore . types . CallExpression >
198+ ) {
199+ const defineCompImport =
200+ path . scope . getBinding ( 'defineComponent' ) ?. path . parent ;
201+ if ( ! defineCompImport ) return true ;
202+
203+ return (
204+ defineCompImport . type === 'ImportDeclaration' &&
205+ / ^ @ ? v u e ( \/ | $ ) / . test ( defineCompImport . source . value )
206+ ) ;
207+ }
208+
209+ function addProperty < T extends BabelCore . types . Node > (
210+ t : ( typeof BabelCore ) [ 'types' ] ,
211+ object : T ,
212+ property : BabelCore . types . ObjectProperty
213+ ) {
214+ if ( t . isObjectExpression ( object ) ) {
215+ object . properties . unshift ( property ) ;
216+ } else if ( t . isExpression ( object ) ) {
217+ return t . objectExpression ( [ property , t . spreadElement ( object ) ] ) ;
218+ }
219+ return object ;
220+ }
0 commit comments