@@ -169,26 +169,82 @@ export function analyzePropsScope(
169
169
}
170
170
171
171
for ( const node of body . body ) {
172
- if ( node . type !== "ExportNamedDeclaration" ) {
173
- continue ;
174
- }
175
- if ( node . declaration ) {
176
- if ( node . declaration . type === "VariableDeclaration" ) {
177
- for ( const decl of node . declaration . declarations ) {
178
- if ( decl . id . type === "Identifier" ) {
179
- addPropsReference ( decl . id , moduleScope ) ;
172
+ if ( node . type === "ExportNamedDeclaration" ) {
173
+ // Process for Svelte v4 style props. e.g. `export let x`;
174
+ if ( node . declaration ) {
175
+ if ( node . declaration . type === "VariableDeclaration" ) {
176
+ for ( const decl of node . declaration . declarations ) {
177
+ for ( const pattern of extractPattern ( decl . id ) ) {
178
+ if ( pattern . type === "Identifier" ) {
179
+ addPropReference ( pattern , moduleScope ) ;
180
+ }
181
+ }
182
+ }
183
+ }
184
+ } else {
185
+ for ( const spec of node . specifiers ) {
186
+ addPropReference ( spec . local , moduleScope ) ;
187
+ }
188
+ }
189
+ } else if ( node . type === "VariableDeclaration" ) {
190
+ // Process for Svelte v5 Runes props. e.g. `let { x = $bindable() } = $props()`;
191
+ for ( const decl of node . declarations ) {
192
+ if (
193
+ decl . init ?. type === "CallExpression" &&
194
+ decl . init . callee . type === "Identifier" &&
195
+ decl . init . callee . name === "$props" &&
196
+ decl . id . type === "ObjectPattern"
197
+ ) {
198
+ for ( const pattern of extractPattern ( decl . id ) ) {
199
+ if (
200
+ pattern . type === "AssignmentPattern" &&
201
+ pattern . left . type === "Identifier" &&
202
+ pattern . right . type === "CallExpression" &&
203
+ pattern . right . callee . type === "Identifier" &&
204
+ pattern . right . callee . name === "$bindable"
205
+ ) {
206
+ addPropReference ( pattern . left , moduleScope ) ;
207
+ }
180
208
}
181
209
}
182
210
}
183
- } else {
184
- for ( const spec of node . specifiers ) {
185
- addPropsReference ( spec . local , moduleScope ) ;
211
+ }
212
+ }
213
+
214
+ function * extractPattern ( node : ESTree . Pattern ) : Iterable < ESTree . Pattern > {
215
+ yield node ;
216
+ if ( node . type === "Identifier" ) {
217
+ return ;
218
+ }
219
+ if ( node . type === "ObjectPattern" ) {
220
+ for ( const prop of node . properties ) {
221
+ if ( prop . type === "Property" ) {
222
+ yield * extractPattern ( prop . value ) ;
223
+ } else {
224
+ yield * extractPattern ( prop ) ;
225
+ }
226
+ }
227
+ return ;
228
+ }
229
+ if ( node . type === "ArrayPattern" ) {
230
+ for ( const elem of node . elements ) {
231
+ if ( elem ) {
232
+ yield * extractPattern ( elem ) ;
233
+ }
186
234
}
235
+ return ;
236
+ }
237
+ if ( node . type === "AssignmentPattern" ) {
238
+ yield * extractPattern ( node . left ) ;
239
+ return ;
240
+ }
241
+ if ( node . type === "RestElement" ) {
242
+ yield * extractPattern ( node . argument ) ;
187
243
}
188
244
}
189
245
190
- /** Add virtual props reference */
191
- function addPropsReference ( node : ESTree . Identifier , scope : Scope ) {
246
+ /** Add virtual prop reference */
247
+ function addPropReference ( node : ESTree . Identifier , scope : Scope ) {
192
248
for ( const variable of scope . variables ) {
193
249
if ( variable . name !== node . name ) {
194
250
continue ;
0 commit comments