Implement optional chaining for function call #1702
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
PR stacked on top of #1694
It implements the optional chaining operator for function call, i.e.
f?.()
and similar.There is a lot of complexity in this PR caused by the fact that rhino has many different ways of calling a function:
f()
is aNAME_AND_THIS
followed by aCALL
a.b()
is aPROP_AND_THIS
followed by aCALL
a[b]()
is anELEM_AND_THIS
followed by aCALL
a.__parent__()
oreval
.The approach I've used is similar to the one used for optional property access, i.e. for
f?.(x)
it will do something like:This is necessary to do the proper short-circuiting required by the spec (there's a lot of unit test cases to verify them).
There is a little bit of duplication in the code, but I think it makes for much easier reading. Also, the bytecode and runtime code generated for the "normal" function call (non-optional) is exactly the same as before; there are no new branches added.
We pass a lot of test262 cases; the ones we do not are for the following reasons:
call-expression.js
,super-property-optional-call.js
: useclass
early-errors-tail-position-null-optchain-template-string.js
,early-errors-tail-position-null-optchain-template-string-esi.js
,early-errors-tail-position-optchain-template-string.js
,early-errors-tail-position-optchain-template-string-esi.js
,punctuator-decimal-lookahead.js
: these use things likefn``x``?.a
which we do not support because we also do not support the non-optional access, i.e.fn``x
.a` already does not work. Tracked by Syntax rejected when accessing property of literal objects #1703eval-optional-call.js
:eval.?
has a special semantic that I did not implement. Tracked by Indirect eval call semantics #1704optional-chain-prod-arguments.js
: there are some existing problems with the spread syntax, tracked by Support ES2015 Spread syntax #1217new-target-optional-call.js
: usesnew.target
which is unsupported, but the test is not marked as requiring it. Probably needs a fix in test262.member-expression.js
: usesasync
,class
, andnew.target
iteration-statement-for-in.js
,iteration-statement-for-of-type-error.js
: usesfor (const key of xxx)
, which does not work. Tracked by Implement ES2015const
#939