Forced calls of OptionalCalls do not print correctly
See original GitHub issueBug Report
It’s possible to force the calling of an OptionalCallExpression
by wrapping it in parentheses:
foo?.(); // <- That's an optional call
foo?.()(); // <- That's an optional call of an optional call
(foo?.())(); // <- That's a forced call of an optional call
This roughly translates to the following:
foo == null ? undefined : foo(); // <- That's an optional call
foo == null ? undefined : foo()(); // <- That's an optional call of an optional call
(foo == null ? undefined : foo())(); // <- That's a forced call of an optional call
Now, the bug: When we print these without transforming them (meaning we’re going to output ES2020 syntax), the forced call loses its parentheses:
// Input
(foo?.())();
// Output
foo?.()();
This is incorrect! If we were to try parsing that output, it’d be an optional call of an optional call, not a forced call of an optional call.
Current Behavior
Outputs foo?.()()
, which is incorrect
Input Code
(foo?.())();
Expected behavior/code
Outputs (foo?.())()
Possible Solution
We need to check if parenthesis are necessary when outputting an OptionalCallExpression
. We already do this for OptionalMemberExpression
s (which have a very similar behavior).
You can verify that if you input (foo?.bar).baz
(a forced member of an optional member), it will have parenthesis in the output.
Additional context/Screenshots
We need to test the following to cases:
// Forced call of an optional call
(foo?.())();
// Forced member of an optional call
(foo?.()).baz;
Issue Analytics
- State:
- Created 4 years ago
- Comments:8 (8 by maintainers)
That will miss cases that are manually constructed in AST (it’d work fine if you parse from a source string). Setting
node.extra.parenthesized
shouldn’t be required to get the generator to print correct code.Yah, we should sync these changes in both places.
Those are both equivalent code, just has an unnecessary parentheses. The updated
t.MemberExpression
check should fix it.Would love to take a shot if no takers 😃