-
Notifications
You must be signed in to change notification settings - Fork 75
Unwelcome grammar surprise with tagged template literals #56
Comments
Is there a way you can see to change the grammar to avoid this surprise? |
Good catch. The obvious solution is to incorporate TemplateLiteral in the OptionalChain production and to add an early error condition when it matches. Or do you have another suggestion? |
@claudepache That suggestion sounds perfect to me. Are there any other similar hazards? |
Why would it be a good idea to make |
Considering what may occur at the end of MemberExpression or CallExpression, I think not. But we should watch any future syntactical addition that would be valid both at the end of a LeftHandSideExpression and at the beginning of a statement. |
May I ask, which rule of ASI will cause the parser to insert the semicolon? I thought the optional chaining prefix (token, operator, whatever ) just modifies the binary operator from the example, so that the parser after |
I'm a bit confused by this. I agree automatic semi-colon insertion does not apply in the first case (as it's the way JS currently works): // when 'a' is defined
let a = { b([_]) { console.log(_) } };
a.b
`thing` // logs 'thing'
// when 'a' is null
a = null;
a.b // 'TypeError: Cannot read property 'b' of null
`thing` // not evaluated as 'TypeError' was already thrown I'm not sure why in the second case, with optional chaining, ASI would act any differently. There would still be no ASI applied: // when 'a' is defined
let a = { b([_]) { console.log(_) } };
a?.b
`thing` // logs 'thing' - same as above
// when 'a' is null
a = null;
a?.b
`thing` // *nothing logged because a is null* - short circuits to 'undefined' Maybe it's me misunderstanding, but are you saying that there's something in the spec that calls for automatic semi-colon insertion after optional chains (if so, I was not aware). If that's the case it'd be something like: // when 'a' is defined
let a = { b([_]) { console.log(_) } };
a?.b // ASI inserted ';' - this line evaluates to '[Function: b]'
`thing` // *nothing logged* - but this line evaluates to 'thing'
// when 'a' is null
a = null;
a?.b // ASI inserted ';' - this line evaluates to 'undefined' due to short-circuiting
`thing` // *nothing logged either* - but this line also evaluates to 'thing' If that is in fact what we're talking about, I don't think it makes much sense for the optional chaining spec to arbitrarily call for ASI after optional chains. That would change the behavior of how ASI currently works in JS--an entirely separate proposal-able topic. Since it's probable I'm misunderstanding the premise of this issue, I'll take another stab at it. Is the problem actually that some developers might mistakenly assume that ASI should apply when they write In any case, I think it's important that semi-colons are manually inserted where automatic semi-colon insertion does not act, for example, semi-colons are needed just as much when the next line starts with
Despite my misunderstanding (apologies), I love your suggestion that tagged template literals should be addressed now. See #54 for further 💗! I'll leave further pro-template literal support on my part for that issue. 😜 |
It's not specific to optional chains. Per 11.9.1.1, a semi colon is inserted whenever a continuation is invalid grammar. In this case, the grammar doesn't allow for an optional chain in the tag of a tagged template literal. So, it reads the valid
No, the issue is that people will assume it won't apply (a semi will not be inserted, like how the current tagged template literal works). |
So, can we make an optional chain allowed in the tag of a template literal? |
Yeah, that's what I would recommend. |
This is not how it is currently specced (an optional chain supports only a limited set of operators). But I concede that this may be counterintuitive, and it could be adjusted if there is consensus for it. (However, I am very reluctant to accept things like |
@claudepache an optional chain supports only a limited set of operators This means, that syntactical grammar doesn't allow (assumed |
@tenbits That means that |
Then that sounds like a grammar bug; it should be supported. |
My last comment raced with others here so it's unclear what I was referring to. To clarify, I'd recommend that the grammar productions for |
Thanks, I think I get it now. A semicolon is inserted because:
I feel a bit foolish with my previous comment when I simply could have just asked, "[W]hich rule of ASI will cause the parser to insert the semicolon?" Thanks @tenbits. 😅 So to put it in simple terms, for someone not intimately familiar with the language specification, one possible solution is to make <optional chain> <template literal> valid syntax (no matter if the optional chaining operator follows the base object, a nested property, or right before the template literal) so that ASI does not occur, right? |
Consider the following:
This is a single expression statement that uses template with the result of
a.b
. Now make the.
optional:It suddenly splits into two expression statements thanks to semicolon insertion. Whoops!
This also means that, unless you address this now, you won't be able to orthogonally support templates in the future without breaking compatibility.
The text was updated successfully, but these errors were encountered: