3
3
babelParse ,
4
4
generateTransform ,
5
5
getLang ,
6
+ importHelperFn ,
6
7
walkAST ,
7
8
} from '@vue-macros/common'
8
9
import { walkIdentifiers } from '@vue-vapor/compiler-core'
@@ -18,12 +19,25 @@ export function transformRestructure(code: string, id: string) {
18
19
enter ( node ) {
19
20
if ( isFunctionExpression ( node ) ) {
20
21
const result = new Map ( )
22
+ const restResult = new Map ( )
21
23
for ( const param of node . params ) {
22
24
const paths = `_ctx${ index ++ } `
23
- if ( resolveParams ( param , paths , result ) ) {
25
+ if ( resolveParam ( param , paths , result , restResult ) ) {
24
26
s . overwrite ( param . start ! , param . end ! , paths )
25
27
}
26
28
}
29
+
30
+ if ( restResult . size ) {
31
+ for ( const [ key , value ] of restResult ) {
32
+ const result = `${ key } = ${ importHelperFn ( s , 0 , 'createPropsRestProxy' , 'vue' ) } (${ value } )`
33
+ if ( node . body . type === 'BlockStatement' ) {
34
+ s . appendRight ( node . body . start ! + 1 , `const ${ result } ;` )
35
+ } else {
36
+ s . appendRight ( node . body . start ! , `(${ result } ,` )
37
+ s . appendRight ( node . body . end ! , ')' )
38
+ }
39
+ }
40
+ }
27
41
if ( ! result . size ) return
28
42
29
43
walkIdentifiers (
@@ -48,30 +62,47 @@ export function transformRestructure(code: string, id: string) {
48
62
return generateTransform ( s , id )
49
63
}
50
64
51
- function resolveParams (
65
+ function resolveParam (
52
66
param : Node ,
53
67
paths : string = '' ,
54
68
result : Map < string , string > ,
69
+ restResult : Map < string , string > ,
55
70
) {
56
- const elements =
71
+ const properties =
57
72
param . type === 'ObjectPattern'
58
73
? param . properties
59
74
: param . type === 'ArrayPattern'
60
75
? param . elements
61
76
: [ ]
62
- if ( ! elements . length ) return
77
+ if ( ! properties . length ) return
63
78
64
- elements . forEach ( ( element , index ) => {
65
- if ( element ?. type === 'Identifier' ) {
66
- result . set ( element . name , `${ paths } [${ index } ]` )
79
+ const propNames : string [ ] = [ ]
80
+ properties . forEach ( ( prop , index ) => {
81
+ if ( prop ?. type === 'Identifier' ) {
82
+ result . set ( prop . name , `${ paths } [${ index } ]` )
83
+ propNames . push ( `'${ prop . name } '` )
84
+ } else if (
85
+ prop ?. type === 'ObjectProperty' &&
86
+ prop . key . type === 'Identifier'
87
+ ) {
88
+ if (
89
+ ! resolveParam (
90
+ prop . value ,
91
+ `${ paths } .${ prop . key . name } ` ,
92
+ result ,
93
+ restResult ,
94
+ )
95
+ ) {
96
+ result . set ( prop . key . name , `${ paths } .${ prop . key . name } ` )
97
+ propNames . push ( `'${ prop . key . name } '` )
98
+ }
67
99
} else if (
68
- element ?. type === 'ObjectProperty ' &&
69
- element . key . type === 'Identifier'
100
+ prop ?. type === 'RestElement ' &&
101
+ prop ?. argument . type === 'Identifier'
70
102
) {
71
- if ( ! resolveParams ( element . value , `${ paths } .${ element . key . name } ` , result ) )
72
- result . set ( element . key . name , `${ paths } .${ element . key . name } ` )
73
- } else if ( element ) {
74
- resolveParams ( element , `${ paths } [${ index } ]` , result )
103
+ restResult . set ( prop . argument . name , `${ paths } , [${ propNames . join ( ', ' ) } ]` )
104
+ } else if ( prop ) {
105
+ resolveParam ( prop , `${ paths } [${ index } ]` , result , restResult )
75
106
}
76
107
} )
77
108
return true
0 commit comments