-
Notifications
You must be signed in to change notification settings - Fork 2k
[CS2] Fix #4260 and #1349: Splat error with soak properties or expressions #4644
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
Conversation
36f0244 to
92a5207
Compare
|
@zdenko This should get some tests. |
|
I’ve added some tests based on #4260 and #1349. Hopefully this PR is ready now. @lydell or @connec, do you care to take a look? Technically this is a tiny breaking change, so it would be better to slip this in before 2.0.0: console.log [a?.b...]
# Old: console.log([...typeof a !== "undefined" && a !== null ? a.b : void 0]);
# New: console.log([...(typeof a !== "undefined" && a !== null ? a.b : [])]);Previously the Interestingly, the tests I added fail in the CS1 version of this PR. I’m not sure we should bother fixing this in 1.x. |
|
Should we add tests for the leading splat variants? |
|
Thanks @connec. Any other notes? |
test/arrays.coffee
Outdated
|
|
||
| # Should not trigger implicit call, e.g. rest ... => rest(...) | ||
| arrayEq [a?.b ...], [3] | ||
| arrayEq [c?.b ...], [] |
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.
Getting a bit pedantic now, but could we add spaced prefix ... as well? Other than that, this LGTM 👍
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.
could we add spaced prefix ... as well
Test added.
test/arrays.coffee
Outdated
|
|
||
| # Should not trigger implicit call, e.g. rest ... => rest(...) | ||
| arrayEq [a if b ...], [3] | ||
| arrayEq [a if c ...], [] |
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.
Absolutely last, final thing: this could also do with a spaced prefixed version.
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.
Added. Sorry, forgot to save the changes.
fd63774 to
47444bf
Compare
|
It does seem kind of funky that It's still possible to generate invalid output by wrapping an if statement in parens and then making a soaked access: [(a if b)?.c ...]
# var ref;
#
# [
# ... if ((ref = (b ? a : void 0)) != null) {
# ref.c;
# }
# ];I feel like this should be fixable by doing something with |
|
@connec I've made some improvements and fixed the issue with wrapped [(a if c)?.b...]
###
[...((ref = (c ? a : void 0)) != null ? ref.b : [])]
### |
Why do you think parens are breaking the change from Even this |
|
I just mean that [(a?.b)...]Compiles to [...(typeof a !== "undefined" && a !== null ? a.b : void 0)] |
|
@connec I’m not sure I follow your last comment. Have all your concerns been addressed? There have been so many bugfixes lately that I think we’re going to release a 2.0.0-beta5 before going straight to 2.0.0. |
|
I've taken a closer look and there are still a couple of problems:
|
Any idea how to do this properly then? My first thought is to take the expression that toss parentheses around it followed by [ f(a?.b)... ]
# Gets mutated in nodes.coffee, before compileNode/compileToFragments, to:
[ ( ( f(a?.b) ) or [] )... ]
# And *then* compiled.This will result in a noisy output: [...(f(typeof a !== "undefined" && a !== null ? a.b : void 0)) || []];but it seems to work. What do you think? |
|
@connec you're right about the if not (@name instanceof Value) or not @isAssignable()
- @name = new Value new Parens @name
- fragments = @name.compileToFragments o
+ fragments = @name.compileToFragments o, LEVEL_OP
else
fragments = @name.compileToFragments 0
[ @makeCode('...')
fragments... ] I've tried to find a 'smart' way to output I did some changes and add additional tests. [a?.b...]
###
[...(typeof a !== "undefined" && a !== null ? a.b : [])]
###
[ f(a?.b)...]
###
[...f(typeof a !== "undefined" && a !== null ? a.b : void 0)]
###
arr.push(a?.b...)
###
arr.push(...(typeof a !== "undefined" && a !== null ? a.b : []))
###
arr.push(f(a?.b)...)
###
arr.push(...f(typeof a !== "undefined" && a !== null ? a.b : void 0))
### |
|
@GeoffreyBooth that would be more robust I think... basically checking if @zdenko I still think the method in Re: |
|
Re `a${undefined}b` // → "aundefinedb"In other words, just like CoffeeScript does. So what about splats/rest? [...undefined] // Uncaught TypeError: undefined is not iterableNow granted, maybe both of these cases are scenarios where CoffeeScript could improve upon JavaScript, but that’s not the goal of this PR; and that’s not a goal of CoffeeScript 2, which is trying to hew closer to ES2015’s way of doing things (like the unfortunate change regarding function parameter default values). So I guess what I’m saying is, we should get rid of the “replace |
|
Agree with the above. |
|
I think this might be one of those cases where we prefer something to behave as we might assume the user always wants it to, e.g. @zdenko if you were to implement the “convert to I made one little change to use |
|
@GeoffreyBooth I think Regarding the "convert []" functionality, I'm not sure this is the way to go. I think it should be up to the user to take care of the correct value, .e.g Anyway, converting to |
connec
left a comment
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 patch looks really clean to me now 👍 (though moving the constructor threw me for a second 😛)
It would be interesting to consider swapping undefined for [] in a separate PR, but @zdenko's example of providing an explicit fallback (arr.push(a?.b ? [c]...)) would need to work also.
|
Thanks @connec. Any opinion on whether we should also merge this into 1.x? We haven’t had any other PRs into that line since 1.12.7, I’m not sure this is significant enough to warrant 1.12.8. Though we could merge it into the 1.x branch and just let that branch sit there unreleased until someday there might be enough patches to make it worth releasing a 1.12.8, or let people use 1.x-latest indefinitely by installing that branch directly from GitHub. Or we could just say no more 1.x releases, period, and leave it at that. |
|
@GeoffreyBooth #4643 - but you've already seen that ;) I'm happy with merging it to 1.x I think, it seems like a pretty simple backwards compatible fix. Whether it's enough to be released I'm not sure. Personally I don't mind tiny releases with simple fixes, but I don't know what the process is. |
This is a fix for #4260 and #1349 when invalid JS is compiled if
Splatcontains soak accessor (?.), orifstatement.Before:
After: