@@ -17,7 +17,7 @@ import {
17
17
isCallOf ,
18
18
unwrapTSNode
19
19
} from '@vue/compiler-core'
20
- import { hasOwn , genPropsAccessExp } from '@vue/shared'
20
+ import { genPropsAccessExp } from '@vue/shared'
21
21
import { PropsDestructureBindings } from './compileScript'
22
22
23
23
/**
@@ -47,6 +47,15 @@ export function transformDestructuredProps(
47
47
propsLocalToPublicMap [ local ] = key
48
48
}
49
49
50
+ function pushScope ( ) {
51
+ scopeStack . push ( ( currentScope = Object . create ( currentScope ) ) )
52
+ }
53
+
54
+ function popScope ( ) {
55
+ scopeStack . pop ( )
56
+ currentScope = scopeStack [ scopeStack . length - 1 ] || null
57
+ }
58
+
50
59
function registerLocalBinding ( id : Identifier ) {
51
60
excludedIds . add ( id )
52
61
if ( currentScope ) {
@@ -108,54 +117,41 @@ export function transformDestructuredProps(
108
117
}
109
118
}
110
119
111
- function rewriteId (
112
- scope : Scope ,
113
- id : Identifier ,
114
- parent : Node ,
115
- parentStack : Node [ ]
116
- ) : boolean {
117
- if ( hasOwn ( scope , id . name ) ) {
118
- const binding = scope [ id . name ]
119
-
120
- if ( binding ) {
121
- if (
122
- ( parent . type === 'AssignmentExpression' && id === parent . left ) ||
123
- parent . type === 'UpdateExpression'
124
- ) {
125
- error ( `Cannot assign to destructured props as they are readonly.` , id )
126
- }
120
+ function rewriteId ( id : Identifier , parent : Node , parentStack : Node [ ] ) {
121
+ if (
122
+ ( parent . type === 'AssignmentExpression' && id === parent . left ) ||
123
+ parent . type === 'UpdateExpression'
124
+ ) {
125
+ error ( `Cannot assign to destructured props as they are readonly.` , id )
126
+ }
127
127
128
- if ( isStaticProperty ( parent ) && parent . shorthand ) {
129
- // let binding used in a property shorthand
130
- // skip for destructure patterns
131
- if (
132
- ! ( parent as any ) . inPattern ||
133
- isInDestructureAssignment ( parent , parentStack )
134
- ) {
135
- // { prop } -> { prop: __props.prop }
136
- s . appendLeft (
137
- id . end ! + offset ,
138
- `: ${ genPropsAccessExp ( propsLocalToPublicMap [ id . name ] ) } `
139
- )
140
- }
141
- } else {
142
- // x --> __props.x
143
- s . overwrite (
144
- id . start ! + offset ,
145
- id . end ! + offset ,
146
- genPropsAccessExp ( propsLocalToPublicMap [ id . name ] )
147
- )
148
- }
128
+ if ( isStaticProperty ( parent ) && parent . shorthand ) {
129
+ // let binding used in a property shorthand
130
+ // skip for destructure patterns
131
+ if (
132
+ ! ( parent as any ) . inPattern ||
133
+ isInDestructureAssignment ( parent , parentStack )
134
+ ) {
135
+ // { prop } -> { prop: __props.prop }
136
+ s . appendLeft (
137
+ id . end ! + offset ,
138
+ `: ${ genPropsAccessExp ( propsLocalToPublicMap [ id . name ] ) } `
139
+ )
149
140
}
150
- return true
141
+ } else {
142
+ // x --> __props.x
143
+ s . overwrite (
144
+ id . start ! + offset ,
145
+ id . end ! + offset ,
146
+ genPropsAccessExp ( propsLocalToPublicMap [ id . name ] )
147
+ )
151
148
}
152
- return false
153
149
}
154
150
155
151
function checkUsage ( node : Node , method : string , alias = method ) {
156
152
if ( isCallOf ( node , alias ) ) {
157
153
const arg = unwrapTSNode ( node . arguments [ 0 ] )
158
- if ( arg . type === 'Identifier' ) {
154
+ if ( arg . type === 'Identifier' && currentScope [ arg . name ] ) {
159
155
error (
160
156
`"${ arg . name } " is a destructured prop and should not be passed directly to ${ method } (). ` +
161
157
`Pass a getter () => ${ arg . name } instead.` ,
@@ -187,7 +183,7 @@ export function transformDestructuredProps(
187
183
188
184
// function scopes
189
185
if ( isFunctionType ( node ) ) {
190
- scopeStack . push ( ( currentScope = { } ) )
186
+ pushScope ( )
191
187
walkFunctionParams ( node , registerLocalBinding )
192
188
if ( node . body . type === 'BlockStatement' ) {
193
189
walkScope ( node . body )
@@ -197,7 +193,7 @@ export function transformDestructuredProps(
197
193
198
194
// catch param
199
195
if ( node . type === 'CatchClause' ) {
200
- scopeStack . push ( ( currentScope = { } ) )
196
+ pushScope ( )
201
197
if ( node . param && node . param . type === 'Identifier' ) {
202
198
registerLocalBinding ( node . param )
203
199
}
@@ -207,7 +203,7 @@ export function transformDestructuredProps(
207
203
208
204
// non-function block scopes
209
205
if ( node . type === 'BlockStatement' && ! isFunctionType ( parent ! ) ) {
210
- scopeStack . push ( ( currentScope = { } ) )
206
+ pushScope ( )
211
207
walkScope ( node )
212
208
return
213
209
}
@@ -217,12 +213,8 @@ export function transformDestructuredProps(
217
213
isReferencedIdentifier ( node , parent ! , parentStack ) &&
218
214
! excludedIds . has ( node )
219
215
) {
220
- // walk up the scope chain to check if id should be appended .value
221
- let i = scopeStack . length
222
- while ( i -- ) {
223
- if ( rewriteId ( scopeStack [ i ] , node , parent ! , parentStack ) ) {
224
- return
225
- }
216
+ if ( currentScope [ node . name ] ) {
217
+ rewriteId ( node , parent ! , parentStack )
226
218
}
227
219
}
228
220
}
@@ -233,8 +225,7 @@ export function transformDestructuredProps(
233
225
( node . type === 'BlockStatement' && ! isFunctionType ( parent ! ) ) ||
234
226
isFunctionType ( node )
235
227
) {
236
- scopeStack . pop ( )
237
- currentScope = scopeStack [ scopeStack . length - 1 ] || null
228
+ popScope ( )
238
229
}
239
230
}
240
231
} )
0 commit comments