diff --git a/lib/coffeescript/nodes.js b/lib/coffeescript/nodes.js index 22539765..0746ca6e 100644 --- a/lib/coffeescript/nodes.js +++ b/lib/coffeescript/nodes.js @@ -3286,7 +3286,9 @@ answer = compiledName.concat(this.makeCode(` ${this.context || '='} `), val); // Per https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Assignment_without_declaration, // if we’re destructuring without declaring, the destructuring assignment must be wrapped in parentheses. - if (o.level > LEVEL_LIST || o.level === LEVEL_TOP && isValue && this.variable.base instanceof Obj && !this.nestedLhs && !(this.param === true)) { + // The assignment is wrapped in parentheses if 'o.level' has lower precedence than LEVEL_LIST (3) + // (i.e. LEVEL_COND (4), LEVEL_OP (5) or LEVEL_ACCESS (6)), or if we're destructuring object, e.g. {a,b} = obj. + if (o.level > LEVEL_LIST || isValue && this.variable.base instanceof Obj && !this.nestedLhs && !(this.param === true)) { return this.wrapInParentheses(answer); } else { return answer; diff --git a/src/nodes.coffee b/src/nodes.coffee index edc095bd..1ea828e9 100644 --- a/src/nodes.coffee +++ b/src/nodes.coffee @@ -2209,7 +2209,9 @@ exports.Assign = class Assign extends Base answer = compiledName.concat @makeCode(" #{ @context or '=' } "), val # Per https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Assignment_without_declaration, # if we’re destructuring without declaring, the destructuring assignment must be wrapped in parentheses. - if o.level > LEVEL_LIST or o.level is LEVEL_TOP and isValue and @variable.base instanceof Obj and not @nestedLhs and not (@param is yes) + # The assignment is wrapped in parentheses if 'o.level' has lower precedence than LEVEL_LIST (3) + # (i.e. LEVEL_COND (4), LEVEL_OP (5) or LEVEL_ACCESS (6)), or if we're destructuring object, e.g. {a,b} = obj. + if o.level > LEVEL_LIST or isValue and @variable.base instanceof Obj and not @nestedLhs and not (@param is yes) @wrapInParentheses answer else answer diff --git a/test/assignment.coffee b/test/assignment.coffee index b62f6cd1..b2bf3e35 100644 --- a/test/assignment.coffee +++ b/test/assignment.coffee @@ -178,6 +178,13 @@ test "#713: destructuring assignment should return right-hand-side value", -> eq nonceB, b eq nonceB, d +test "#4787 destructuring of objects within arrays", -> + arr = [1, {a:1, b:2}] + [...,{a, b}] = arr + eq a, 1 + eq b, arr[1].b + deepEqual {a, b}, arr[1] + test "destructuring assignment with splats", -> a = {}; b = {}; c = {}; d = {}; e = {} [x,y...,z] = [a,b,c,d,e]