@@ -169,26 +169,82 @@ export function analyzePropsScope(
169169 }
170170
171171 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+ }
180208 }
181209 }
182210 }
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+ }
186234 }
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 ) ;
187243 }
188244 }
189245
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 ) {
192248 for ( const variable of scope . variables ) {
193249 if ( variable . name !== node . name ) {
194250 continue ;
0 commit comments