1
0
Fork 0
mirror of https://github.com/jashkenas/coffeescript.git synced 2022-11-09 12:23:24 -05:00

[CS2] destructured nested defaults [fixes #4566] (#4574)

* destructured nested defaults [fixes #4566]

* don't parenthesize nested assigns
This commit is contained in:
Julian Rosse 2017-06-20 23:53:37 -05:00 committed by Geoffrey Booth
parent 0619a7a76c
commit 26f6fa6570
4 changed files with 47 additions and 6 deletions

View file

@ -1544,7 +1544,7 @@
}
compileNode(o) {
var answer, i, idt, indent, isCompact, j, join, k, key, l, lastNoncom, len1, len2, len3, node, prop, props, ref1, value;
var answer, i, idt, indent, isCompact, j, join, k, key, l, lastNoncom, len1, len2, len3, len4, node, p, prop, props, ref1, unwrappedVal, value;
props = this.properties;
if (this.generated) {
for (j = 0, len1 = props.length; j < len1; j++) {
@ -1556,17 +1556,32 @@
}
idt = o.indent += TAB;
lastNoncom = this.lastNonComment(this.properties);
if (this.lhs) {
for (k = 0, len2 = props.length; k < len2; k++) {
prop = props[k];
if (!(prop instanceof Assign)) {
continue;
}
({value} = prop);
unwrappedVal = value.unwrapAll();
if (unwrappedVal instanceof Arr || unwrappedVal instanceof Obj) {
unwrappedVal.lhs = true;
} else if (unwrappedVal instanceof Assign) {
unwrappedVal.nestedLhs = true;
}
}
}
isCompact = true;
ref1 = this.properties;
for (k = 0, len2 = ref1.length; k < len2; k++) {
prop = ref1[k];
for (l = 0, len3 = ref1.length; l < len3; l++) {
prop = ref1[l];
if (prop instanceof Comment || (prop instanceof Assign && prop.context === 'object' && !this.csx)) {
isCompact = false;
}
}
answer = [];
answer.push(this.makeCode(isCompact ? '' : '\n'));
for (i = l = 0, len3 = props.length; l < len3; i = ++l) {
for (i = p = 0, len4 = props.length; p < len4; i = ++p) {
prop = props[i];
join = i === props.length - 1 ? '' : isCompact && this.csx ? ' ' : isCompact ? ', ' : prop === lastNoncom || prop instanceof Comment || this.csx ? '\n' : ',\n';
indent = isCompact || prop instanceof Comment ? '' : idt;
@ -2486,7 +2501,7 @@
return compiledName.concat(this.makeCode(this.csx ? '=' : ': '), val);
}
answer = compiledName.concat(this.makeCode(` ${this.context || '='} `), val);
if (o.level > LEVEL_LIST || (isValue && this.variable.base instanceof Obj && !this.param)) {
if (o.level > LEVEL_LIST || (isValue && this.variable.base instanceof Obj && !this.nestedLhs && !this.param)) {
return this.wrapInParentheses(answer);
} else {
return answer;

View file

@ -1165,6 +1165,17 @@ exports.Obj = class Obj extends Base
idt = o.indent += TAB
lastNoncom = @lastNonComment @properties
# If this object is the left-hand side of an assignment, all its children
# are too.
if @lhs
for prop in props when prop instanceof Assign
{value} = prop
unwrappedVal = value.unwrapAll()
if unwrappedVal instanceof Arr or unwrappedVal instanceof Obj
unwrappedVal.lhs = yes
else if unwrappedVal instanceof Assign
unwrappedVal.nestedLhs = yes
isCompact = yes
for prop in @properties
if prop instanceof Comment or (prop instanceof Assign and prop.context is 'object' and not @csx)
@ -1828,7 +1839,7 @@ 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 were destructuring without declaring, the destructuring assignment must be wrapped in parentheses.
if o.level > LEVEL_LIST or (isValue and @variable.base instanceof Obj and not @param)
if o.level > LEVEL_LIST or (isValue and @variable.base instanceof Obj and not @nestedLhs and not @param)
@wrapInParentheses answer
else
answer

View file

@ -571,3 +571,13 @@ test "Assignment to variables similar to helper functions", ->
indexOf = [1, 2, 3]
ok 2 in indexOf
test "#4566: destructuring with nested default values", ->
{a: {b = 1}} = a: {}
eq 1, b
{c: {d} = {}} = c: d: 3
eq 3, d
{e: {f = 5} = {}} = {}
eq 5, f

View file

@ -362,3 +362,8 @@ test "Destructured parameter with default value, that itself has a default value
y: 30
radius: 30
eq output, 'big-18-30-30'
test "#4566: destructuring with nested default values", ->
f = ({a: {b = 1}}) ->
b
eq 2, f a: b: 2