-
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
[CS2] Fix #4651: object spread destructuring bug #4652
Changes from 2 commits
f9367ba
2664c2c
232041d
2149c35
1a6477a
2491d32
5a709ed
c212e6e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2229,8 +2229,11 @@ exports.Assign = class Assign extends Base | |
nestedProperties = prop.value.variable.base.properties | ||
[prop.value.value, nestedSourceDefault] = prop.value.value.cache o | ||
if nestedProperties | ||
nestedSource = new Value source.base, source.properties.concat [new Access getPropKey prop] | ||
nestedSource = new Value new Op '?', nestedSource, nestedSourceDefault if nestedSourceDefault | ||
if source.properties | ||
nestedSource = new Value source.base, source.properties.concat [new Access getPropKey prop] | ||
nestedSource = new Value new Op '?', nestedSource, nestedSourceDefault if nestedSourceDefault | ||
else | ||
nestedSource = source | ||
restElements.push traverseRest(nestedProperties, nestedSource)... | ||
else if prop instanceof Splat | ||
prop.error "multiple rest elements are disallowed in object destructuring" if restIndex? | ||
|
@@ -2247,8 +2250,16 @@ exports.Assign = class Assign extends Base | |
|
||
restElements | ||
|
||
# Cache the value for reuse with rest elements | ||
[@value, valueRef] = @value.cache o | ||
# Cache the value for reuse with rest elements. | ||
# `Obj` should be always cached. | ||
# Examples: | ||
# {a, r...} = {a:1, b:2, c:3} | ||
# {a, r...} = {a:1, obj...} | ||
shouldCache = (value) -> | ||
return yes if value.base instanceof Obj | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we change There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've already tried that, but then tests fail. |
||
value.shouldCache() | ||
|
||
[@value, valueRef] = @value.cache o, false, shouldCache | ||
|
||
# Find all rest elements. | ||
restElements = traverseRest @variable.base.properties, valueRef | ||
|
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.
Is this another case that would work better if whatever
source
is was wrapped in aValue
? @helixbassAlternatively, should the case where there are no
properties
not wrapsource
in aValue
? I can't really remember how this all works, but in the case thatsource
has noproperties
, the next level of key won't be added (source.properties.concat [new Access getPropKey prop]
). It must be working if the tests pass, but I don't really understand why...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.
@connec I’m not sure I follow your comment. Is there something that needs to change here?
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 guess it's just not clear to me why we need to check if
source.properties
is set. I imagine this is roughly equivalent tosource instanceof Value
, and my 2 questions are:source
is aValue
(e.g. in the grammar/whereversource
is created)?source
is not a value (e.g.not source.properties
) then we do not execute the line where we concat the property key. Why does this work?I'll try and find some time to poke around to answer my own questions, since it's probably just my own misunderstandings. Since the tests work etc. this can probably go in, and if I find any issues I can submit a new ticket/fix.
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.
@connec you're right there's some bugginess here, I'm poking around and ran into eg this:
compiles to this:
This would seem to be a case of
nestedSource
not getting set correctly (the first arg toobjectWithoutKeys()
shouldn't beref
, I guess it should beref.c
?)If I can figure it out I'll push a fix to this branch, otherwise I'll at least push breaking tests