@@ -1458,13 +1458,23 @@ exports.Assign = class Assign extends Base
1458
1458
top = o .level is LEVEL_TOP
1459
1459
{value } = this
1460
1460
{objects } = @variable .base
1461
+
1462
+ # Special-case for `{} = a` and `[] = a` (empty patterns). Compile to simply
1463
+ # `a`.
1461
1464
unless olen = objects .length
1462
1465
code = value .compileToFragments o
1463
1466
return if o .level >= LEVEL_OP then @ wrapInBraces code else code
1467
+
1464
1468
[obj ] = objects
1469
+
1470
+ # Disallow `[...] = a` for some reason. (Could be equivalent to `[] = a`?)
1465
1471
if olen is 1 and obj instanceof Expansion
1466
1472
obj .error ' Destructuring assignment has no target'
1473
+
1467
1474
isObject = @variable .isObject ()
1475
+
1476
+ # Special case for when there's only one thing destructured off of
1477
+ # something. `{b} = a` and `[b] = a`.
1468
1478
if top and olen is 1 and obj not instanceof Splat
1469
1479
# Pick the property straight off the value when there’s just one to pick
1470
1480
# (no need to cache the value into a variable).
@@ -1495,15 +1505,30 @@ exports.Assign = class Assign extends Base
1495
1505
obj .error message if message
1496
1506
value = new Op ' ?' , value, defaultValue if defaultValue
1497
1507
return new Assign (obj, value, null , param : @param ).compileToFragments o, LEVEL_TOP
1508
+
1498
1509
vvar = value .compileToFragments o, LEVEL_LIST
1499
1510
vvarText = fragmentsToText vvar
1500
1511
assigns = []
1501
1512
expandedIdx = false
1502
- # Make vvar into a simple variable if it isn't already.
1513
+
1514
+ # At this point, there are several things to destructure. So the `fn()` in
1515
+ # `{a, b} = fn()` must be cached, for example. Make vvar into a simple
1516
+ # variable if it isn't already.
1503
1517
if value .unwrap () not instanceof IdentifierLiteral or @variable .assigns (vvarText)
1504
1518
assigns .push [@ makeCode (" #{ ref = o .scope .freeVariable ' ref' } = " ), vvar... ]
1505
1519
vvar = [@ makeCode ref]
1506
1520
vvarText = ref
1521
+
1522
+ # And here comes the big loop that handles all of these cases:
1523
+ # `[a, b] = c`
1524
+ # `[a..., b] = c`
1525
+ # `[..., a, b] = c`
1526
+ # `[@a, b] = c`
1527
+ # `[a = 1, b] = c`
1528
+ # `{a, b} = c`
1529
+ # `{@a, b} = c`
1530
+ # `{a = 1, b} = c`
1531
+ # etc.
1507
1532
for obj, i in objects
1508
1533
idx = i
1509
1534
if not expandedIdx and obj instanceof Splat
@@ -1558,6 +1583,7 @@ exports.Assign = class Assign extends Base
1558
1583
message = isUnassignable name
1559
1584
obj .error message if message
1560
1585
assigns .push new Assign (obj, val, null , param : @param , subpattern : yes ).compileToFragments o, LEVEL_LIST
1586
+
1561
1587
assigns .push vvar unless top or @subpattern
1562
1588
fragments = @ joinFragmentArrays assigns, ' , '
1563
1589
if o .level < LEVEL_LIST then fragments else @ wrapInBraces fragments
0 commit comments