-
Notifications
You must be signed in to change notification settings - Fork 776
Support async generators #2101
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
Support async generators #2101
Conversation
f4713c9 to
c1dcacc
Compare
a770bff to
283aa68
Compare
|
Hi @ariya ! Here's a PR to allow parsing about 6000 more scripts that were unparseable before, basically allowing async generators and couple more error checks. |
|
Great work @lahma, thanks! I will take a look. |
| StrictLHSPrefix: 'Prefix increment/decrement may not have eval or arguments operand in strict mode', | ||
| StrictModeWith: 'Strict mode code may not include a with statement', | ||
| StrictOctalLiteral: 'Octal literals are not allowed in strict mode.', | ||
| StrictParamDupe: 'Strict mode function may not have duplicate parameter names', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed this in favor of DuplicateParameter which aligns with V8
| allowStrictDirective: boolean; | ||
| allowYield: boolean; | ||
| await: boolean; | ||
| isAsync: boolean; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Renamed this as await is keyword and isAsync describes the context
| this.errorHandler.tolerate(this.unexpectedTokenError(token, message)); | ||
| } | ||
|
|
||
| tolerateInvalidLoopStatement() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Had to create separate function as for statement parsing started to fail due to cyclomatic complexity
| switch (this.lookahead.type) { | ||
| case Token.Identifier: | ||
| if ((this.context.isModule || this.context.await) && this.lookahead.value === 'await') { | ||
| if ((this.context.isModule || this.context.isAsync) && this.lookahead.value === 'await') { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this now reads better, isModule, isAsync
| } | ||
|
|
||
| parsePropertyMethodAsyncFunction(): Node.FunctionExpression { | ||
| parsePropertyMethodAsyncFunction(isGenerator: boolean): Node.FunctionExpression { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might make sense at some point to put isGenerator into context
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is Boolean trap, though we already have some cases like that in the same file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So should I put this into context as part of this PR or what changes required?
| } | ||
|
|
||
| parseRestProperty(params, kind): Node.RestElement { | ||
| parseRestProperty(params): Node.RestElement { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed the unused parameter as style checks gave warning and couldn't see a reason to keep
| } | ||
| this.expect(')'); | ||
|
|
||
| if (options.hasDuplicateParameterNames) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moved checks to single place where can validate against context
|
@ariya anything you want me to tweak here? |
|
Thank you @lahma 👍 |
|
You're most welcome, thanks for merging! |
|
@lahma i've merged your changes also in my fork |
| expr = this.inheritCoverGrammar(this.matchKeyword('new') ? this.parseNewExpression : this.parsePrimaryExpression); | ||
| } | ||
|
|
||
| if (isSuper && this.match('(') && !this.context.inClassConstructor) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@lahma:
this condition is not correct when the class is not inherited
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In esprima next there is also context.allowSuper.
I got it from this pull req: #2047
Async generators are valid constructs and went through issues parsing them. Couple issues surfaced on class handling side but unrelated to async generators per se.
Before
✔ 54265 valid programs parsed without error
✔ 6748 invalid programs produced a parsing error
✔ 1101 invalid programs did not produce a parsing error (and allowed by the whitelist file)
✔ 16288 valid programs produced a parsing error (and allowed by the whitelist file)
After
✔ 60262 valid programs parsed without error
✔ 6747 invalid programs produced a parsing error
✔ 1102 invalid programs did not produce a parsing error (and allowed by the whitelist file)
✔ 10291 valid programs produced a parsing error (and allowed by the whitelist file)
fixes #1990