Skip to content

Commit

Permalink
Support for-await-of (#1190)
Browse files Browse the repository at this point in the history
Closes gh-2031
  • Loading branch information
Meir017 authored and ariya committed Sep 27, 2020
1 parent deaa653 commit 4f52923
Show file tree
Hide file tree
Showing 22 changed files with 453 additions and 753 deletions.
1 change: 1 addition & 0 deletions docs/syntax-tree-format.md
Expand Up @@ -546,6 +546,7 @@ interface ForInStatement {
```js
interface ForOfStatement {
type: 'ForOfStatement';
await: boolean;
left: Expression | VariableDeclaration;
right: Expression;
body: Statement;
Expand Down
4 changes: 3 additions & 1 deletion src/nodes.ts
Expand Up @@ -381,11 +381,13 @@ export class ForInStatement {

export class ForOfStatement {
readonly type: string;
readonly await: boolean;
readonly left: Expression;
readonly right: Expression;
readonly body: Statement;
constructor(left: Expression, right: Expression, body: Statement) {
constructor(left: Expression, right: Expression, body: Statement, _await: boolean) {
this.type = Syntax.ForOfStatement;
this.await = _await;
this.left = left;
this.right = right;
this.body = body;
Expand Down
13 changes: 11 additions & 2 deletions src/parser.ts
Expand Up @@ -2248,9 +2248,18 @@ export class Parser {
let update: Node.Expression | null = null;
let forIn = true;
let left, right;
let _await = false;

const node = this.createNode();
this.expectKeyword('for');
if (this.matchContextualKeyword('await')) {
if (!this.context.await) {
this.tolerateUnexpectedToken(this.lookahead);
}
_await = true;
this.nextToken();
}

this.expect('(');

if (this.match(';')) {
Expand All @@ -2265,7 +2274,7 @@ export class Parser {
const declarations = this.parseVariableDeclarationList({ inFor: true });
this.context.allowIn = previousAllowIn;

if (declarations.length === 1 && this.matchKeyword('in')) {
if (!_await && declarations.length === 1 && this.matchKeyword('in')) {
const decl = declarations[0];
if (decl.init && (decl.id.type === Syntax.ArrayPattern || decl.id.type === Syntax.ObjectPattern || this.context.strict)) {
this.tolerateError(Messages.ForInOfLoopInitializer, 'for-in');
Expand Down Expand Up @@ -2397,7 +2406,7 @@ export class Parser {
return (typeof left === 'undefined') ?
this.finalize(node, new Node.ForStatement(init, test, update, body)) :
forIn ? this.finalize(node, new Node.ForInStatement(left, right, body)) :
this.finalize(node, new Node.ForOfStatement(left, right, body));
this.finalize(node, new Node.ForOfStatement(left, right, body, _await));
}

// https://tc39.github.io/ecma262/#sec-continue-statement
Expand Down
Expand Up @@ -17,6 +17,7 @@
}
},
"type": "ForOfStatement",
"await": false,
"left": {
"range": [
5,
Expand Down
Expand Up @@ -17,6 +17,7 @@
}
},
"type": "ForOfStatement",
"await": false,
"left": {
"range": [
5,
Expand Down
1 change: 1 addition & 0 deletions test/fixtures/ES6/for-of/for-of-array-pattern.tree.json
Expand Up @@ -17,6 +17,7 @@
}
},
"type": "ForOfStatement",
"await": false,
"left": {
"range": [
5,
Expand Down
1 change: 1 addition & 0 deletions test/fixtures/ES6/for-of/for-of-let.tree.json
Expand Up @@ -31,6 +31,7 @@
}
},
"type": "ForOfStatement",
"await": false,
"left": {
"range": [
5,
Expand Down
Expand Up @@ -17,6 +17,7 @@
}
},
"type": "ForOfStatement",
"await": false,
"left": {
"range": [
5,
Expand Down
Expand Up @@ -17,6 +17,7 @@
}
},
"type": "ForOfStatement",
"await": false,
"left": {
"range": [
5,
Expand Down
1 change: 1 addition & 0 deletions test/fixtures/ES6/for-of/for-of-object-pattern.tree.json
Expand Up @@ -17,6 +17,7 @@
}
},
"type": "ForOfStatement",
"await": false,
"left": {
"range": [
5,
Expand Down
1 change: 1 addition & 0 deletions test/fixtures/ES6/for-of/for-of-with-const.tree.json
Expand Up @@ -17,6 +17,7 @@
}
},
"type": "ForOfStatement",
"await": false,
"left": {
"range": [
5,
Expand Down
1 change: 1 addition & 0 deletions test/fixtures/ES6/for-of/for-of-with-let.tree.json
Expand Up @@ -17,6 +17,7 @@
}
},
"type": "ForOfStatement",
"await": false,
"left": {
"range": [
5,
Expand Down
1 change: 1 addition & 0 deletions test/fixtures/ES6/for-of/for-of-with-var.tree.json
Expand Up @@ -17,6 +17,7 @@
}
},
"type": "ForOfStatement",
"await": false,
"left": {
"range": [
5,
Expand Down
1 change: 1 addition & 0 deletions test/fixtures/ES6/for-of/for-of.tree.json
Expand Up @@ -17,6 +17,7 @@
}
},
"type": "ForOfStatement",
"await": false,
"left": {
"range": [
5,
Expand Down
1 change: 1 addition & 0 deletions test/fixtures/ES6/for-of/let-of-of.tree.json
Expand Up @@ -17,6 +17,7 @@
}
},
"type": "ForOfStatement",
"await": false,
"left": {
"range": [
5,
Expand Down
1 change: 1 addition & 0 deletions test/fixtures/es2018/for-await-of/for-await-of.js
@@ -0,0 +1 @@
async function f() { for await (p of q); }

0 comments on commit 4f52923

Please sign in to comment.