-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Spread in objects #4473
Spread in objects #4473
Conversation
@@ -1748,6 +1748,13 @@ exports.Assign = class Assign extends Base | |||
vvarText = fragmentsToText vvar | |||
assigns = [] | |||
expandedIdx = false | |||
# check if variable is object and containes splat, e.g. {a, b, c...} | |||
hasSplat = isObject and (i for obj, i in objects when obj instanceof Splat).length == 1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's better to error out if length>1?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since multiple splats/expansions are disallowed in an assignment, length == 1 should be ok?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No. We need to show a nice error message, like when you try to use multiple splats in array desctructuring or parameter list.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the current status :
./bin/coffee -e "{a, x..., c, y...} = {a:1, b:2, c:3, d:4, e:5}"
[stdin]:1:14: error: multiple splats/expansions are disallowed in an assignment
{a, x..., c, y...} = {a:1, b:2, c:3, d:4, e:5}
test "destructuring assignment with objects and splats: ES2015", -> | ||
obj = {a:1, b:2, c:3, d:4, e:5} | ||
{a:x, b, r...} = obj | ||
{a:y, c..., d} = obj |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The rest element has to be last, according to Babel: http://babeljs.io/repl/#?babili=false&evaluate=false&lineWrap=false&presets=es2015%2Cstage-2%2Cstage-3&targets=&browsers=&builtIns=false&code=const%20%7Ba%3Ay%2C%20...c%2C%20d%7D%20%3D%20obj&experimental=false&loose=false&spec=false&playground=true
I guess CoffeeScript should support it anywhere, though, just like for arrays? I guess we just need to move the splat last in the compiled JS.
eq c.b, b | ||
eq r.e, c.e | ||
|
||
test "destructuring assignment with context (@) properties: ES2015", -> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see any @
s in this test?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a typo. I copied the string.
@@ -1748,6 +1748,13 @@ exports.Assign = class Assign extends Base | |||
vvarText = fragmentsToText vvar | |||
assigns = [] | |||
expandedIdx = false | |||
# check if variable is object and containes splat, e.g. {a, b, c...} | |||
hasSplat = isObject and (i for obj, i in objects when obj instanceof Splat).length == 1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No. We need to show a nice error message, like when you try to use multiple splats in array desctructuring or parameter list.
# obj2 = "#{{obj1..., b: 3}}" | ||
t1 = CoffeeScript.compile "{obj1..., b: 3}", bare: yes | ||
t1 = t1.replace(/\s+/g, "") | ||
eq t1, "({...obj1,b:3});" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The rule has been to never compare strings with the compiled output JS, unless there's no other way to assert that the compiled code works as intended. Also, CoffeeScript always strives to produce readable output. You need to add some spaces in there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Error for multiple splats is already there at line 1791 in lib/nodes.coffee
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you reply to the wrong comment? :)
Anyway, we need a test for the multiple splats error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry. Long hours :(
Anyway, I couldn't find example how to test the output of obj2 = {obj1..., b:5}
CS compiles it to
(function() {
var obj2;
obj2 = {
...obj1,
b: 5
};
}).call(this);
but test fails since the syntax {...obj1, b:5} is currently in stage-3 and requires Babel.
To rephrase the question, can Babel be used for tests?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is our policy to only support ES features that have reached stage 4, and are supported in the Node runtime (modules are the big exception to this). Therefore the test would compile to the finalized ES syntax, and Node should be able to run it.
@zdenko thank you for making this effort! Do you feel like helping with the destructuring branch? The goal there is to output ES2015 destructured syntax whenever possible. Certain Coffee destructuring arrangements aren’t possible in ES, so should stay as they are; and default values should follow the ES style of only getting applied with the variable is undefined, not undefined or null. |
@GeoffreyBooth sure. So, the output of destructuring And, the rest element has to be the last element. |
@zdenko that syntax doesn’t seem to work for me, but in general, yes, whenever there is an ES destructured syntax that is equivalent to a CoffeeScript one, we want to output the ES one. In #4311 I refactored the handling of function parameters to support expansions and splats output as ES; if the splat was the last parameter, the conversion was straightforward, otherwise a placeholder splat became the last parameter and further assignments happened in the function body. We could do something similar for destructuring. |
@GeoffreyBooth this syntax should work. The proposal for object rest/spread properties is in stage-3. Since CS supports only stage-4, the output of object spread should be: Is that correct? |
Closing in favor of #4493 |
Connected to #3894.
In CS2 emit
to
obj1 = {...obj, z: 3}
Improve destructuring assignment for object literal: