mirror of
https://github.com/jashkenas/coffeescript.git
synced 2022-11-09 12:23:24 -05:00
merge branch 'master' into 'object_rest_spread'
This commit is contained in:
commit
e7f1b07c88
3 changed files with 61 additions and 20 deletions
|
@ -3464,8 +3464,8 @@ this.toVar}`, upperBound = `${this.fromVar} >= ${idx} && ${gt} ${this.toVar}`, `
|
|||
// Sort 'splatsAndExpans' so we can show error at first disallowed token.
|
||||
objects[splatsAndExpans.sort()[1]].error("multiple splats/expansions are disallowed in an assignment");
|
||||
}
|
||||
isSplat = splats.length;
|
||||
isExpans = expans.length;
|
||||
isSplat = (splats != null ? splats.length : void 0) > 0;
|
||||
isExpans = (expans != null ? expans.length : void 0) > 0;
|
||||
isObject = this.variable.isObject();
|
||||
isArray = this.variable.isArray();
|
||||
vvar = value.compileToFragments(o, LEVEL_LIST);
|
||||
|
@ -3537,7 +3537,7 @@ this.toVar}`, upperBound = `${this.fromVar} >= ${idx} && ${gt} ${this.toVar}`, `
|
|||
};
|
||||
// "Complex" `objects` are processed in a loop.
|
||||
// Examples: [a, b, {c, r...}, d], [a, ..., {b, r...}, c, d]
|
||||
loopObjects = (objs, vvarTxt) => {
|
||||
loopObjects = (objs, vvar, vvarTxt) => {
|
||||
var acc, idx, j, len1, message, objSpreads, results, vval;
|
||||
objSpreads = hasObjSpreads(objs);
|
||||
results = [];
|
||||
|
@ -3596,7 +3596,7 @@ this.toVar}`, upperBound = `${this.fromVar} >= ${idx} && ${gt} ${this.toVar}`, `
|
|||
return results;
|
||||
};
|
||||
// "Simple" `objects` can be split and compiled to arrays, [a, b, c] = arr, [a, b, c...] = arr
|
||||
assignObjects = (objs, vvarTxt) => {
|
||||
assignObjects = (objs, vvar, vvarTxt) => {
|
||||
var vval;
|
||||
vvar = new Value(new Arr(objs, true));
|
||||
vval = vvarTxt instanceof Value ? vvarTxt : new Value(new Literal(vvarTxt));
|
||||
|
@ -3605,11 +3605,11 @@ this.toVar}`, upperBound = `${this.fromVar} >= ${idx} && ${gt} ${this.toVar}`, `
|
|||
subpattern: true
|
||||
}).compileToFragments(o, LEVEL_LIST));
|
||||
};
|
||||
processObjects = function(objs, vvarTxt) {
|
||||
processObjects = function(objs, vvar, vvarTxt) {
|
||||
if (complexObjects(objs)) {
|
||||
return loopObjects(objs, vvarTxt);
|
||||
return loopObjects(objs, vvar, vvarTxt);
|
||||
} else {
|
||||
return assignObjects(objs, vvarTxt);
|
||||
return assignObjects(objs, vvar, vvarTxt);
|
||||
}
|
||||
};
|
||||
// In case there is `Splat` or `Expansion` in `objects`,
|
||||
|
@ -3628,7 +3628,7 @@ this.toVar}`, upperBound = `${this.fromVar} >= ${idx} && ${gt} ${this.toVar}`, `
|
|||
leftObjs = objects.slice(0, expIdx + (isSplat ? 1 : 0));
|
||||
rightObjs = objects.slice(expIdx + 1);
|
||||
if (leftObjs.length !== 0) {
|
||||
processObjects(leftObjs, vvarText);
|
||||
processObjects(leftObjs, vvar, vvarText);
|
||||
}
|
||||
if (rightObjs.length !== 0) {
|
||||
// Slice or splice `objects`.
|
||||
|
@ -3645,11 +3645,11 @@ this.toVar}`, upperBound = `${this.fromVar} >= ${idx} && ${gt} ${this.toVar}`, `
|
|||
refExp = o.scope.freeVariable('ref');
|
||||
assigns.push([this.makeCode(refExp + ' = '), ...restVar.compileToFragments(o, LEVEL_LIST)]);
|
||||
}
|
||||
processObjects(rightObjs, refExp);
|
||||
processObjects(rightObjs, vvar, refExp);
|
||||
}
|
||||
} else {
|
||||
// There is no `Splat` or `Expansion` in `objects`.
|
||||
processObjects(objects, vvarText);
|
||||
processObjects(objects, vvar, vvarText);
|
||||
}
|
||||
if (!(top || this.subpattern)) {
|
||||
assigns.push(vvar);
|
||||
|
|
|
@ -2305,8 +2305,8 @@ exports.Assign = class Assign extends Base
|
|||
# Sort 'splatsAndExpans' so we can show error at first disallowed token.
|
||||
objects[splatsAndExpans.sort()[1]].error "multiple splats/expansions are disallowed in an assignment"
|
||||
|
||||
isSplat = splats.length
|
||||
isExpans = expans.length
|
||||
isSplat = splats?.length > 0
|
||||
isExpans = expans?.length > 0
|
||||
isObject = @variable.isObject()
|
||||
isArray = @variable.isArray()
|
||||
|
||||
|
@ -2355,7 +2355,7 @@ exports.Assign = class Assign extends Base
|
|||
|
||||
# "Complex" `objects` are processed in a loop.
|
||||
# Examples: [a, b, {c, r...}, d], [a, ..., {b, r...}, c, d]
|
||||
loopObjects = (objs, vvarTxt) =>
|
||||
loopObjects = (objs, vvar, vvarTxt) =>
|
||||
objSpreads = hasObjSpreads objs
|
||||
for obj, i in objs
|
||||
# `Elision` can be skipped.
|
||||
|
@ -2385,16 +2385,16 @@ exports.Assign = class Assign extends Base
|
|||
assigns.push new Assign(vvar, vval, null, param: @param, subpattern: yes).compileToFragments o, LEVEL_LIST
|
||||
|
||||
# "Simple" `objects` can be split and compiled to arrays, [a, b, c] = arr, [a, b, c...] = arr
|
||||
assignObjects = (objs, vvarTxt) =>
|
||||
assignObjects = (objs, vvar, vvarTxt) =>
|
||||
vvar = new Value new Arr(objs, yes)
|
||||
vval = if vvarTxt instanceof Value then vvarTxt else new Value new Literal(vvarTxt)
|
||||
assigns.push new Assign(vvar, vval, null, param: @param, subpattern: yes).compileToFragments o, LEVEL_LIST
|
||||
|
||||
processObjects = (objs, vvarTxt) ->
|
||||
processObjects = (objs, vvar, vvarTxt) ->
|
||||
if complexObjects objs
|
||||
loopObjects objs, vvarTxt
|
||||
loopObjects objs, vvar, vvarTxt
|
||||
else
|
||||
assignObjects objs, vvarTxt
|
||||
assignObjects objs, vvar, vvarTxt
|
||||
|
||||
# In case there is `Splat` or `Expansion` in `objects`,
|
||||
# we can split array in two simple subarrays.
|
||||
|
@ -2411,7 +2411,7 @@ exports.Assign = class Assign extends Base
|
|||
expIdx = splatsAndExpans[0]
|
||||
leftObjs = objects.slice 0, expIdx + (if isSplat then 1 else 0)
|
||||
rightObjs = objects.slice expIdx + 1
|
||||
processObjects leftObjs, vvarText if leftObjs.length isnt 0
|
||||
processObjects leftObjs, vvar, vvarText if leftObjs.length isnt 0
|
||||
if rightObjs.length isnt 0
|
||||
# Slice or splice `objects`.
|
||||
refExp = switch
|
||||
|
@ -2421,10 +2421,10 @@ exports.Assign = class Assign extends Base
|
|||
restVar = refExp
|
||||
refExp = o.scope.freeVariable 'ref'
|
||||
assigns.push [@makeCode(refExp + ' = '), restVar.compileToFragments(o, LEVEL_LIST)...]
|
||||
processObjects rightObjs, refExp
|
||||
processObjects rightObjs, vvar, refExp
|
||||
else
|
||||
# There is no `Splat` or `Expansion` in `objects`.
|
||||
processObjects objects, vvarText
|
||||
processObjects objects, vvar, vvarText
|
||||
assigns.push vvar unless top or @subpattern
|
||||
fragments = @joinFragmentArrays assigns, ', '
|
||||
if o.level < LEVEL_LIST then fragments else @wrapInParentheses fragments
|
||||
|
|
|
@ -927,3 +927,44 @@ test "#4673: complex destructured object spread variables", ->
|
|||
|
||||
# {{g}...} = g: 1
|
||||
# eq g, 1
|
||||
|
||||
test "#4878: Compile error when using destructuring with a splat or expansion in an array", ->
|
||||
arr = ['a', 'b', 'c', 'd']
|
||||
|
||||
f1 = (list) ->
|
||||
[first, ..., last] = list
|
||||
|
||||
f2 = (list) ->
|
||||
[first..., last] = list
|
||||
|
||||
f3 = (list) ->
|
||||
([first, ...] = list); first
|
||||
|
||||
f4 = (list) ->
|
||||
([first, ...rest] = list); rest
|
||||
|
||||
arrayEq f1(arr), arr
|
||||
arrayEq f2(arr), arr
|
||||
arrayEq f3(arr), 'a'
|
||||
arrayEq f4(arr), ['b', 'c', 'd']
|
||||
|
||||
foo = (list) ->
|
||||
ret =
|
||||
if list?.length > 0
|
||||
[first, ..., last] = list
|
||||
[first, last]
|
||||
else
|
||||
[]
|
||||
|
||||
arrayEq foo(arr), ['a', 'd']
|
||||
|
||||
bar = (list) ->
|
||||
ret =
|
||||
if list?.length > 0
|
||||
[first, ...rest] = list
|
||||
[first, rest]
|
||||
else
|
||||
[]
|
||||
|
||||
arrayEq bar(arr), ['a', ['b', 'c', 'd']]
|
||||
>>>>>>> 794f65fbd74ee9f3839a5f715116e71cf23e24c0
|
||||
|
|
Loading…
Reference in a new issue