Closed Bug 846406 Opened 11 years ago Closed 11 years ago

Implement arrow functions

Categories

(Core :: JavaScript Engine, defect)

Other Branch
defect
Not set
normal

Tracking

()

RESOLVED FIXED
mozilla22

People

(Reporter: jorendorff, Assigned: jorendorff)

References

(Blocks 1 open bug)

Details

(Keywords: dev-doc-complete)

Attachments

(1 file, 4 obsolete files)

As of now this is in sec. 13-2 of the draft spec:
  http://people.mozilla.org/~jorendorff/es6-draft.html#sec-13.2
Attached patch WIP 1 - many broken tests (obsolete) — Splinter Review
Assignee: general → jorendorff
Work to do that I can think of offhand:
- `() => x` arrow functions with no arguments don't work yet
- `(...rest) => x` arrow functions with rest arguments don't work yet
- 'this' should be lexical, unlike other functions
- arrow functions should have no 'arguments' binding, unlike other functions
- FunctionToString is moderately broken
needs tests.
Attachment #719598 - Attachment is obsolete: true
More TODO items:
- tests for arrow-block functions
- Reflect.parse support
- ban yield in arrow functions
fiveop, a volunteer, wants to take on the "() => body" syntax.

Just did Reflect.parse; I'll work on rest arguments next...
Attachment #719637 - Attachment is obsolete: true
Attached patch v5Splinter Review
OK, I'm punting lexical 'this' to follow-up bug 848062 so that this can land.
Attachment #720109 - Attachment is obsolete: true
Attachment #721380 - Flags: review?(bhackett1024)
Comment on attachment 721380 [details] [diff] [review]
v5

Review of attachment 721380 [details] [diff] [review]:
-----------------------------------------------------------------

::: js/src/frontend/Parser.cpp
@@ +1483,4 @@
>  {
> +    FunctionBox *funbox = pc->sc->asFunctionBox();
> +
> +    bool parenFree = false;

Maybe name this 'parenFreeArrow' to be more descriptive.

@@ +1603,5 @@
>                  if (!defineArg(funcpn, name, disallowDuplicateArgs, &duplicatedArg))
>                      return false;
>  
>                  if (tokenStream.matchToken(TOK_ASSIGN)) {
> +                    JS_ASSERT(!parenFree);

What guarantees this assert?

@@ +4803,5 @@
>  #endif
>  
> +    // Save two source locations, both just in case we turn out to be in an
> +    // arrow function. 'offset' is for FunctionToString. 'start' is for
> +    // rewinding and reparsing arguments.

This seems unfortunate, can you describe a bit more in the comment why this is necessary?

@@ +4807,5 @@
> +    // rewinding and reparsing arguments.
> +    if (tokenStream.getToken() == TOK_ERROR)
> +        return null();
> +    size_t offset = tokenStream.offsetOfToken(tokenStream.currentToken());
> +    tokenStream.ungetToken();

It seems like you could just compute offset in the TOK_ARROW case of the switch, since you will be seeking back to the start of the ::assignExpr anyways.
Attachment #721380 - Flags: review?(bhackett1024) → review+
(In reply to Brian Hackett (:bhackett) from comment #9)
> ::: js/src/frontend/Parser.cpp
> >                  if (tokenStream.matchToken(TOK_ASSIGN)) {
> > +                    JS_ASSERT(!parenFree);
> 
> What guarantees this assert?

I added a comment:

                // A default argument without parentheses would look like:
                // a = expr => body, but both operators are right-associative, so
                // that would have been parsed as a = (expr => body) instead.
                // Therefore it's impossible to get here with parenFreeArrow.
                JS_ASSERT(!parenFreeArrow);

> > +    // rewinding and reparsing arguments.
> > +    if (tokenStream.getToken() == TOK_ERROR)
> > +        return null();
> > +    size_t offset = tokenStream.offsetOfToken(tokenStream.currentToken());
> > +    tokenStream.ungetToken();
> 
> It seems like you could just compute offset in the TOK_ARROW case of the
> switch, since you will be seeking back to the start of the ::assignExpr
> anyways.

Yup. Done.
This appears to have landed.  Please add the URL for the patch.
Comment on attachment 721380 [details] [diff] [review]
v5

Review of attachment 721380 [details] [diff] [review]:
-----------------------------------------------------------------

::: js/src/frontend/TokenStream.h
@@ +558,5 @@
>      }
>  
>      TokenKind peekToken() {
>          if (lookahead != 0) {
> +            JS_ASSERT(lookahead <= maxLookahead);

Given the following line, shouldn't this be |1 <= maxLookahead|?

@@ +573,5 @@
>      }
>  
>      TokenKind peekTokenSameLine(unsigned withFlags = 0) {
> +        if (lookahead != 0) {
> +            JS_ASSERT(lookahead <= maxLookahead);

Ditto.
https://hg.mozilla.org/mozilla-central/rev/bf3ce88c6ea3
Status: NEW → RESOLVED
Closed: 11 years ago
Flags: in-testsuite+
Resolution: --- → FIXED
Target Milestone: --- → mozilla22
@Comment 12: I think both asserts are unnecessary. We (should) make sure that |lookahead| stays within bounds in the ungetToken() function. And as soon as |lookahead > 0| holds, we know that in |tokens[cursor + 1]| is the token after current Token, so executing the 'then' clause is fine.
> @Comment 12: I think both asserts are unnecessary.

I agree :)  Feel free to make that change in bug 846933.
Depends on: 852761
Depends on: 848197
Depends on: 848062
Depends on: 852762
Depends on: 882877
Depends on: 1101265
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: