-
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 #3199: throw multiline implicit object #4599
[CS2] Fix #3199: throw multiline implicit object #4599
Conversation
@helixbass Thank you for tackling this knotty, difficult bug! I agree with everything you’ve written above. Yes, functions, If I had to guess, I suppose that @jashkenas’ objection to fn
arg Is more that he doesn’t want people to get in the habit of putting each argument on its own line, e.g. fn
arg1
arg2
arg3 and then we lose the idea of the indentation signifying a new block, such as an object. So if we can fix #3199 and get these three calling tokens to behave similarly, and still avoid allowing a confusing syntax that would lead to lots of ambiguity problems, that sounds like an ideal solution. Does this PR do that? I’m totally fine with disallowing return
x but I wonder if we should make that change on The PR itself looks good to me. @lydell? |
I have no opinion. I guess it's fine, but I'm not really sure what this is all about anyway. |
@helixbass can you please retarget this to |
51f9bba
to
cf3b9f3
Compare
@GeoffreyBooth retargeted to As far as only allowing implicit objects/trying to align with function-call syntax, a couple thoughts:
compiles to:
and similarly for
As far as I'm aware, yes, this PR won't introduce ambiguity and using a grammar-based solution avoids some of these problems (like #3199) that using |
@GeoffreyBooth just played around with postfix Currently (on
compiles to:
ie the same as
But what about postfix
compiles to the unintuitive
And with
compiles to
and similarly with postfix So these kinds of cases have made me think it's actually a really good idea to restrict it to just
But at that point I think it needs to be targeted against However, there's no reason that I can see not to go ahead and make the So I'll go ahead and retarget this back to At that point, here's my assessment of parity with function-call syntax:
would work. If it's worth disallowing this, the cleanest way I can think of would be to pass an additional flag to both
since the allowance of implicit-object first arguments is token-based (in |
cf3b9f3
to
36222ee
Compare
Just to quickly chime in — yes, I think that @GeoffreyBooth characterized my objection correctly.
and
... are both poor CoffeeScript style, and we shouldn't really be encouraging them. |
Thanks @helixbass, you’ve put more thought into this than I have. Your recommendation sounds good. The code looks good too, though I have one suggestion: should we add some tests to confirm the function/ |
@GeoffreyBooth sure, added a couple tests each for "bad" forms of @jashkenas' and your opinion reinforces that restricting to just allowing indented |
In other words, excluding this? return
{key: 1} as opposed to implicit (braceless) or the This PR looks good to me. @vendethiel or @jashkenas or @lydell or anyone else have any notes? |
Seems good. I think it's fine not to differentiate between |
@helixbass do you mind answering my last question, and resolving conflicts? Aside from that I think we’re ready to merge. |
@GeoffreyBooth merged |
Thanks @helixbass! |
Fixes #3199
The reason the kind of implicit object "splitting" described in #3199 happens is b/c the suppression of the
INDENT
followingthrow
doesn't play nicely with the rewriter (normalizeLines()
specifically). So to me it seems cleaner to preserve theINDENT
and just add grammar ruleTHROW INDENT Expression OUTDENT
@GeoffreyBooth this relates to #1263 and your comment there - as you found,
throw
with implicit object worked b/c ofINDENT
/TERMINATOR
suppression (viaunfinished()
). But then #3199 shows that it doesn't always work. And the same breakage applies to how you implementedreturn
ing implicit objects in #4532, ie this breaks:So I applied the same idea here to
return
and replaced yourINDENT
-suppressing implementation in #4532 with a grammar ruleRETURN INDENT Expression OUTDENT
which un-breaks the above exampleIn a more general way, #3199 and #1263 seem to reflect our feeling that we should be able to pass indented implicit object literals to function-call-ish things like
throw
andreturn
the way that we can pass them to an actual function call. I definitely feel that way and am glad that #4532 was added. This PR just changes the way that it's supported to avoid bugs like #3199, I'm unaware if there's any additional downside to doing it via grammar rules allowingINDENT...OUTDENT
variationsBut then it does feel a little weird that both how this PR supports it and the existing behavior for
throw
and forreturn
(since #4532) allow anything to be passed on following lines, not just implicit objects (which is what I think our brains tell us we should be able to do). Eg this has been legal:And as of #4532, you can do eg:
I don't have a big problem with either of these but it does seem akin to how @jashkenas apparently doesn't like the idea of this being legal:
Because basically all three of these (
throw
,return
, and actual function calls) all "feel" like function calls, so it would make sense that they follow similar rulesThere's some interesting related discussion in #3098 and #1263 - this comment warns against allowing implicit indented objects with
return
and mentionsthrow
, but given that the way it's supported for function calls is different from both existing support forthrow
(which the commenter @satyr added)/return
(as of #4532) and from how this PR supports it, I'm not inclined to heed itPut list of tokens in
UNFINISHED
per @jashkenas' request