-
Notifications
You must be signed in to change notification settings - Fork 846
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement optional chaining for function call #1702
Open
andreabergia
wants to merge
10
commits into
mozilla:master
Choose a base branch
from
andreabergia:optional-chain-and-nullish-coalesce-fun
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Implement optional chaining for function call #1702
andreabergia
wants to merge
10
commits into
mozilla:master
from
andreabergia:optional-chain-and-nullish-coalesce-fun
+1,149
−521
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Made special ref work with optional chaining Made optional chaining work with expressions, `a?.[b]` Removed useless `++maxStack` Add new token in `AstNode` Fixed bug in interpreter code generation - was jumping a bit too far
`a?.b.c` is `undefined` if `a?.b` is undefined, _not_ a reference error because `c` does not exist! This is called "short circuiting". The implementation is not particularly efficient - we have more than one check "it's undefined? then jump to the end". Ideally we'd generate only one such jump; however, that is quite complicated with our code structure and hopefully this pattern is not super common to be a real problem right now.
All cases are handled: ```js f?.() a.b?.() a[0]?.() a.__parent__() ``` Handled also `eval` (which has special opcodes)
@andreabergia have started some smoke testing with HtmlUnit.... |
@andreabergia smoke test was successful |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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