question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Forced calls of OptionalCalls do not print correctly

See original GitHub issue

Bug 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 OptionalMemberExpressions (which have a very similar behavior).

https://github.com/babel/babel/blob/d13fd7c7bdb51995e8c9171b7047fc93402f8c3a/packages/babel-generator/src/node/parentheses.js#L254-L259

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:closed
  • Created 4 years ago
  • Comments:8 (8 by maintainers)

github_iconTop GitHub Comments

1reaction
jridgewellcommented, Feb 28, 2020

I wonder if you saw my edited comment regarding this approach

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.

I realized we probably need to modify the OptionalMemberExpression function as well

Yah, we should sync these changes in both places.

This case foo[bar?.baz]; transforms to this (before my change)

Those are both equivalent code, just has an unnecessary parentheses. The updated t.MemberExpression check should fix it.

1reaction
sag1vcommented, Feb 28, 2020

Would love to take a shot if no takers 😃

Read more comments on GitHub >

github_iconTop Results From Across the Web

Java Optional Tutorial with Examples - CalliCoder
In this tutorial, You'll learn what Optional is, how it helps you mitigate the risk of running into NullPointerExceptions and how to use...
Read more >
How to execute logic on Optional if not present? - Stack Overflow
With ifPresentOrElse I'm forced to use a present function that does nothing in the later case. – hbobenicio. Jun 21, 2017 at 20:19....
Read more >
26 Reasons Why Using Optional Correctly Is Not Optional
Don't force call sites to create Optionals . Do not use Optional as fields or in setters and constructors' arguments.
Read more >
Tired of Null Pointer Exceptions? Consider Using Java SE 8's ...
The variable computer is of type Optional<Computer> , so it is perfectly correct to call the map method. However, getSoundcard() returns an object...
Read more >
10 Examples of Optional in Java 8 - Javarevisited
1) The Optional class is a container object which may or may not contain a non-null value. · 2) If a non-value is...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found