@@ -237,30 +237,46 @@ export function extract_identifiers_from_destructuring(node, nodes = []) {
237
237
* Extracts all destructured assignments from a pattern.
238
238
* @param {ESTree.Node } param
239
239
* @param {ESTree.Expression } initial
240
- * @returns {{ paths: DestructuredAssignment[] } }
240
+ * @returns {{ declarations: ESTree.VariableDeclaration[], paths: DestructuredAssignment[] } }
241
241
*/
242
242
export function extract_paths ( param , initial ) {
243
+ /**
244
+ * When dealing with array destructuring patterns (`let [a, b, c] = $derived(blah())`)
245
+ * we need an intermediate declaration that creates an array, since `blah()` could
246
+ * return a non-array-like iterator
247
+ * @type {ESTree.VariableDeclaration[] }
248
+ */
249
+ const declarations = [ ] ;
250
+
243
251
/** @type {DestructuredAssignment[] } */
244
252
const paths = [ ] ;
245
253
246
- _extract_paths ( paths , param , initial , initial , false ) ;
254
+ _extract_paths ( paths , declarations , param , initial , initial , false ) ;
247
255
248
- return { paths } ;
256
+ return { declarations , paths } ;
249
257
}
250
258
251
259
/**
252
- * @param {DestructuredAssignment[] } assignments
260
+ * @param {DestructuredAssignment[] } paths
261
+ * @param {ESTree.VariableDeclaration[] } declarations
253
262
* @param {ESTree.Node } param
254
263
* @param {ESTree.Expression } expression
255
264
* @param {ESTree.Expression } update_expression
256
265
* @param {boolean } has_default_value
257
266
* @returns {DestructuredAssignment[] }
258
267
*/
259
- function _extract_paths ( assignments = [ ] , param , expression , update_expression , has_default_value ) {
268
+ function _extract_paths (
269
+ paths ,
270
+ declarations ,
271
+ param ,
272
+ expression ,
273
+ update_expression ,
274
+ has_default_value
275
+ ) {
260
276
switch ( param . type ) {
261
277
case 'Identifier' :
262
278
case 'MemberExpression' :
263
- assignments . push ( {
279
+ paths . push ( {
264
280
node : param ,
265
281
is_rest : false ,
266
282
has_default_value,
@@ -290,7 +306,7 @@ function _extract_paths(assignments = [], param, expression, update_expression,
290
306
const rest_expression = b . call ( '$.exclude_from_object' , expression , b . array ( props ) ) ;
291
307
292
308
if ( prop . argument . type === 'Identifier' ) {
293
- assignments . push ( {
309
+ paths . push ( {
294
310
node : prop . argument ,
295
311
is_rest : true ,
296
312
has_default_value,
@@ -299,7 +315,8 @@ function _extract_paths(assignments = [], param, expression, update_expression,
299
315
} ) ;
300
316
} else {
301
317
_extract_paths (
302
- assignments ,
318
+ paths ,
319
+ declarations ,
303
320
prop . argument ,
304
321
rest_expression ,
305
322
rest_expression ,
@@ -314,7 +331,8 @@ function _extract_paths(assignments = [], param, expression, update_expression,
314
331
) ;
315
332
316
333
_extract_paths (
317
- assignments ,
334
+ paths ,
335
+ declarations ,
318
336
prop . value ,
319
337
object_expression ,
320
338
object_expression ,
@@ -325,15 +343,15 @@ function _extract_paths(assignments = [], param, expression, update_expression,
325
343
326
344
break ;
327
345
328
- case 'ArrayPattern' :
346
+ case 'ArrayPattern' : {
329
347
for ( let i = 0 ; i < param . elements . length ; i += 1 ) {
330
348
const element = param . elements [ i ] ;
331
349
if ( element ) {
332
350
if ( element . type === 'RestElement' ) {
333
351
const rest_expression = b . call ( b . member ( expression , 'slice' ) , b . literal ( i ) ) ;
334
352
335
353
if ( element . argument . type === 'Identifier' ) {
336
- assignments . push ( {
354
+ paths . push ( {
337
355
node : element . argument ,
338
356
is_rest : true ,
339
357
has_default_value,
@@ -342,7 +360,8 @@ function _extract_paths(assignments = [], param, expression, update_expression,
342
360
} ) ;
343
361
} else {
344
362
_extract_paths (
345
- assignments ,
363
+ paths ,
364
+ declarations ,
346
365
element . argument ,
347
366
rest_expression ,
348
367
rest_expression ,
@@ -353,7 +372,8 @@ function _extract_paths(assignments = [], param, expression, update_expression,
353
372
const array_expression = b . member ( expression , b . literal ( i ) , true ) ;
354
373
355
374
_extract_paths (
356
- assignments ,
375
+ paths ,
376
+ declarations ,
357
377
element ,
358
378
array_expression ,
359
379
array_expression ,
@@ -364,27 +384,35 @@ function _extract_paths(assignments = [], param, expression, update_expression,
364
384
}
365
385
366
386
break ;
387
+ }
367
388
368
389
case 'AssignmentPattern' : {
369
390
const fallback_expression = build_fallback ( expression , param . right ) ;
370
391
371
392
if ( param . left . type === 'Identifier' ) {
372
- assignments . push ( {
393
+ paths . push ( {
373
394
node : param . left ,
374
395
is_rest : false ,
375
396
has_default_value : true ,
376
397
expression : fallback_expression ,
377
398
update_expression
378
399
} ) ;
379
400
} else {
380
- _extract_paths ( assignments , param . left , fallback_expression , update_expression , true ) ;
401
+ _extract_paths (
402
+ paths ,
403
+ declarations ,
404
+ param . left ,
405
+ fallback_expression ,
406
+ update_expression ,
407
+ true
408
+ ) ;
381
409
}
382
410
383
411
break ;
384
412
}
385
413
}
386
414
387
- return assignments ;
415
+ return paths ;
388
416
}
389
417
390
418
/**
0 commit comments