Moving discussion from https://github.com/microsoft/TypeScript/issues/40916.
Quoting @DanielRosenwasser:
I can't seem to find a derivation for ExponentiationExpression to
await 1 ** 1.
ExponentiationExpression seems to need an UpdateExpression on the left, which does not include an AwaitExpression. On the other hand, UnaryExpression does, but that's kind of the point of the syntax split.
My reading (now that I look) matches his. But V8, SpiderMonkey, JavaScriptCore, engine262, babel, shift, flow, and acorn all seem to have missed this. (But not TypeScript or XS!) We should probably call it out with a big note in the spec, or, since it might now be web reality, possibly change the spec to match implementations.
Incidentally I'd be happy with making this legal, since await a + 2 definitely is.
My vote is more to keep things as is and fix implementations if possible, as it's more inconsistent otherwise.
As an extra step, this proves that each browser is parsing it as (await X) ** 2 and not await (X ** 2):
(async function f() {
const obj = {
valueOf() {
console.log('Parsed as `await (X ** 2)`');
return 1;
},
then(f) {
console.log('Parsed as `(await X) ** 2`');
f(2);
},
};
const value = await obj ** 2;
return value;
})()
Does it the same order for "await x + y" (await x) + y not await (x + y)?
Does it the same order for "await x + y" (await x) + y not await (x + y)?
Yes, await x + y is equivalent to (await x) + y.
Another fun case:
(async () => {
await -x ** 2;
})();
The tools which forbid await x ** 2 also forbid the above, but of those which allow that case, only V8 forbids this one.
Are there test262 tests for this case?
Most helpful comment
As an extra step, this proves that each browser is parsing it as
(await X) ** 2and notawait (X ** 2):