Skip to content

Commit a379b03

Browse files
committed
fix gkz#1096
The minor code optimization of omitting parentheses around a single destructuring assignment is incorrect when the assignment is produced inside a binary expression, as the binary operator interferes with the parsing of the assignment's LHS in the generated JS. This change restricts the optimization to cases where the current precedence level is lower than that of binary operators. Since the number of expressions includes a final expression that captures the original RHS of the destructuring assignment if that value is needed, and since the optimization is always applied to top-level and parenthesis-level expressions by the second half of the if condition, this change only has an effect on single-assignment destructuring assignments that are direct children of a list or conditional expression, where the value of the destructuring assignment expression is not used (which rules out lists and most conditionals as well). gkz#1096 illustrates one of the only ways such a circumstance is likely to arise in natural code.
1 parent bc1c188 commit a379b03

4 files changed

Lines changed: 20 additions & 2 deletions

File tree

lib/ast.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/ast.ls

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1725,7 +1725,7 @@ class exports.Assign extends Node
17251725
for item in list
17261726
code.push item, sep
17271727
code.pop!
1728-
if list.length < 2 or o.level < LEVEL_LIST then sn(this, ...code) else sn(this, "(", ...code, ")")
1728+
if (o.level < LEVEL_OP and list.length < 2) or o.level < LEVEL_LIST then sn(this, ...code) else sn(this, "(", ...code, ")")
17291729

17301730
compileSplice: (o) ->
17311731
[from-exp-node, from-exp] = Chain @left.from .cache-reference o

test/assignment.ls

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,15 @@ o{d, e} &&*= d: 2, e: 3
404404
eq 0 o.d
405405
eq 3 o.e
406406

407+
# https://github.com/gkz/LiveScript/issues/1096
408+
[{a}?] = [a: 1]
409+
eq 1 a
410+
a = null
411+
[{a}?] = []
412+
eq null a
413+
[[[a]?]?] = []
414+
eq null a
415+
407416

408417
### Named Destructuring
409418
[b, c]:a = [0 1]

test/compilation.ls

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -394,3 +394,12 @@ ok compiled.starts-with 'var A;\n'
394394

395395
compiled = LiveScript.compile 'a[b = c + d] **= e' {+bare,-header}
396396
ok compiled.starts-with 'var b;\n'
397+
398+
399+
# Don't wrap single destructuring statements in parentheses under these
400+
# specific conditions:
401+
# * the destructuring is inside a conditional
402+
# * the conditional is in an expression position
403+
# * but the value of the conditional isn't needed
404+
compiled = LiveScript.compile 'a or if b then [@c] = d else 0' {+bare,-header}
405+
eq 'a || (b ? this.c = d[0] : 0);' compiled

0 commit comments

Comments
 (0)