@@ -237,42 +237,35 @@ 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 {{ declarations: ESTree.VariableDeclaration[] , paths: DestructuredAssignment[] } }
240
+ * @returns {{ inserts: Array<{ id: ESTree.Identifier, value: ESTree.Expression }> , paths: DestructuredAssignment[] } }
241
241
*/
242
242
export function extract_paths ( param , initial ) {
243
243
/**
244
244
* When dealing with array destructuring patterns (`let [a, b, c] = $derived(blah())`)
245
245
* we need an intermediate declaration that creates an array, since `blah()` could
246
246
* return a non-array-like iterator
247
- * @type {ESTree.VariableDeclaration[] }
247
+ * @type {Array<{ id: ESTree.Identifier, value: ESTree.Expression }> }
248
248
*/
249
- const declarations = [ ] ;
249
+ const inserts = [ ] ;
250
250
251
251
/** @type {DestructuredAssignment[] } */
252
252
const paths = [ ] ;
253
253
254
- _extract_paths ( paths , declarations , param , initial , initial , false ) ;
254
+ _extract_paths ( paths , inserts , param , initial , initial , false ) ;
255
255
256
- return { declarations , paths } ;
256
+ return { inserts , paths } ;
257
257
}
258
258
259
259
/**
260
260
* @param {DestructuredAssignment[] } paths
261
- * @param {ESTree.VariableDeclaration[] } declarations
261
+ * @param {Array<{ id: ESTree.Identifier, value: ESTree.Expression }> } inserts
262
262
* @param {ESTree.Node } param
263
263
* @param {ESTree.Expression } expression
264
264
* @param {ESTree.Expression } update_expression
265
265
* @param {boolean } has_default_value
266
266
* @returns {DestructuredAssignment[] }
267
267
*/
268
- function _extract_paths (
269
- paths ,
270
- declarations ,
271
- param ,
272
- expression ,
273
- update_expression ,
274
- has_default_value
275
- ) {
268
+ function _extract_paths ( paths , inserts , param , expression , update_expression , has_default_value ) {
276
269
switch ( param . type ) {
277
270
case 'Identifier' :
278
271
case 'MemberExpression' :
@@ -316,7 +309,7 @@ function _extract_paths(
316
309
} else {
317
310
_extract_paths (
318
311
paths ,
319
- declarations ,
312
+ inserts ,
320
313
prop . argument ,
321
314
rest_expression ,
322
315
rest_expression ,
@@ -332,7 +325,7 @@ function _extract_paths(
332
325
333
326
_extract_paths (
334
327
paths ,
335
- declarations ,
328
+ inserts ,
336
329
prop . value ,
337
330
object_expression ,
338
331
object_expression ,
@@ -344,11 +337,26 @@ function _extract_paths(
344
337
break ;
345
338
346
339
case 'ArrayPattern' : {
340
+ // we create an intermediate declaration to convert iterables to arrays if necessary.
341
+ // the consumer is responsible for setting the name of the identifier
342
+ const id = b . id ( '#' ) ;
343
+
344
+ const is_rest = param . elements . at ( - 1 ) ?. type === 'RestElement' ;
345
+ const call = b . call (
346
+ '$.to_array' ,
347
+ expression ,
348
+ is_rest ? undefined : b . literal ( param . elements . length )
349
+ ) ;
350
+
351
+ inserts . push ( { id, value : b . call ( '$.derived' , b . thunk ( call ) ) } ) ;
352
+
353
+ const array = b . call ( '$.get' , id ) ;
354
+
347
355
for ( let i = 0 ; i < param . elements . length ; i += 1 ) {
348
356
const element = param . elements [ i ] ;
349
357
if ( element ) {
350
358
if ( element . type === 'RestElement' ) {
351
- const rest_expression = b . call ( b . member ( expression , 'slice' ) , b . literal ( i ) ) ;
359
+ const rest_expression = b . call ( b . member ( array , 'slice' ) , b . literal ( i ) ) ;
352
360
353
361
if ( element . argument . type === 'Identifier' ) {
354
362
paths . push ( {
@@ -361,19 +369,19 @@ function _extract_paths(
361
369
} else {
362
370
_extract_paths (
363
371
paths ,
364
- declarations ,
372
+ inserts ,
365
373
element . argument ,
366
374
rest_expression ,
367
375
rest_expression ,
368
376
has_default_value
369
377
) ;
370
378
}
371
379
} else {
372
- const array_expression = b . member ( expression , b . literal ( i ) , true ) ;
380
+ const array_expression = b . member ( array , b . literal ( i ) , true ) ;
373
381
374
382
_extract_paths (
375
383
paths ,
376
- declarations ,
384
+ inserts ,
377
385
element ,
378
386
array_expression ,
379
387
array_expression ,
@@ -398,14 +406,7 @@ function _extract_paths(
398
406
update_expression
399
407
} ) ;
400
408
} else {
401
- _extract_paths (
402
- paths ,
403
- declarations ,
404
- param . left ,
405
- fallback_expression ,
406
- update_expression ,
407
- true
408
- ) ;
409
+ _extract_paths ( paths , inserts , param . left , fallback_expression , update_expression , true ) ;
409
410
}
410
411
411
412
break ;
0 commit comments