Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 28d23ce

Browse filesBrowse files
committed
Add for-await-of, always use Symbol for iterables.
1 parent d6a5e39 commit 28d23ce
Copy full SHA for 28d23ce

20 files changed

+223-169Lines changed: 223 additions & 169 deletions
Expand file treeCollapse file tree
Open diff view settings
Collapse file

‎src/compiler/binder.ts‎

Copy file name to clipboardExpand all lines: src/compiler/binder.ts
+19-5Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -954,7 +954,7 @@ namespace ts {
954954
addAntecedent(preLoopLabel, currentFlow);
955955
currentFlow = preLoopLabel;
956956
if (node.kind === SyntaxKind.ForOfStatement) {
957-
bind(node.awaitKeyword);
957+
bind(node.modifierToken);
958958
}
959959
bind(node.expression);
960960
addAntecedent(postLoopLabel, currentFlow);
@@ -3125,9 +3125,13 @@ namespace ts {
31253125
break;
31263126

31273127
case SyntaxKind.ForOfStatement:
3128-
// for-of might be ESNext if it has a rest destructuring
3129-
transformFlags |= TransformFlags.AssertESNext;
3130-
// FALLTHROUGH
3128+
if ((<ForOfStatement>node).modifierToken) {
3129+
transformFlags |= TransformFlags.AssertES2017;
3130+
}
3131+
3132+
transformFlags |= TransformFlags.AssertES2015;
3133+
break;
3134+
31313135
case SyntaxKind.NoSubstitutionTemplateLiteral:
31323136
case SyntaxKind.TemplateHead:
31333137
case SyntaxKind.TemplateMiddle:
@@ -3142,7 +3146,17 @@ namespace ts {
31423146

31433147
case SyntaxKind.ForOfStatement:
31443148
// This node is either ES2015 syntax or ES2017 syntax (if it is a for-await-of).
3145-
transformFlags |= (<ForOfStatement>node).awaitKeyword ? TransformFlags.AssertES2017 : TransformFlags.AssertES2015;
3149+
switch (getForOfModifierKind(<ForOfStatement>node)) {
3150+
case SyntaxKind.AwaitKeyword:
3151+
transformFlags |= TransformFlags.AssertES2017;
3152+
break;
3153+
case SyntaxKind.EachKeyword:
3154+
transformFlags |= TransformFlags.AssertTypeScript;
3155+
break;
3156+
default:
3157+
transformFlags |= TransformFlags.AssertES2015;
3158+
break;
3159+
}
31463160
break;
31473161

31483162
case SyntaxKind.YieldExpression:
Collapse file

‎src/compiler/checker.ts‎

Copy file name to clipboardExpand all lines: src/compiler/checker.ts
+107-99Lines changed: 107 additions & 99 deletions
Large diffs are not rendered by default.
Collapse file

‎src/compiler/diagnosticMessages.json‎

Copy file name to clipboardExpand all lines: src/compiler/diagnosticMessages.json
+10-2Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1463,7 +1463,7 @@
14631463
"category": "Error",
14641464
"code": 2460
14651465
},
1466-
"Type '{0}' is not an array type or does not have an '__iterator__()' method that returns an iterator.": {
1466+
"Type '{0}' is not an array type.": {
14671467
"category": "Error",
14681468
"code": 2461
14691469
},
@@ -1587,7 +1587,7 @@
15871587
"category": "Error",
15881588
"code": 2494
15891589
},
1590-
"Type '{0}' is not an array type or a string type or does not have an '__iterator__()' method that returns an iterator.": {
1590+
"Type '{0}' is not an array type or a string type.": {
15911591
"category": "Error",
15921592
"code": 2495
15931593
},
@@ -1783,6 +1783,14 @@
17831783
"category": "Error",
17841784
"code": 2543
17851785
},
1786+
"Type '{0}' is not an array type or does not have a '[Symbol.iterator]()' method that returns an iterator.": {
1787+
"category": "Error",
1788+
"code": 2544
1789+
},
1790+
"Type '{0}' is not an array type or a string type or does not have a '[Symbol.iterator]()' method that returns an iterator.": {
1791+
"category": "Error",
1792+
"code": 2545
1793+
},
17861794
"JSX element attributes type '{0}' may not be a union type.": {
17871795
"category": "Error",
17881796
"code": 2600
Collapse file

‎src/compiler/emitter.ts‎

Copy file name to clipboardExpand all lines: src/compiler/emitter.ts
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1368,7 +1368,7 @@ namespace ts {
13681368
function emitForOfStatement(node: ForOfStatement) {
13691369
const openParenPos = writeToken(SyntaxKind.ForKeyword, node.pos);
13701370
write(" ");
1371-
emitWithSuffix(node.awaitKeyword, " ");
1371+
emitWithSuffix(node.modifierToken, " ");
13721372
writeToken(SyntaxKind.OpenParenToken, openParenPos);
13731373
emitForBinding(node.initializer);
13741374
write(" of ");
Collapse file

‎src/compiler/factory.ts‎

Copy file name to clipboardExpand all lines: src/compiler/factory.ts
+15-8Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -926,17 +926,18 @@ namespace ts {
926926
return node;
927927
}
928928

929-
export function createForOf(initializer: ForInitializer, expression: Expression, statement: Statement, location?: TextRange) {
929+
export function createForOf(modifierToken: AwaitKeywordToken | EachKeywordToken, initializer: ForInitializer, expression: Expression, statement: Statement, location?: TextRange) {
930930
const node = <ForOfStatement>createNode(SyntaxKind.ForOfStatement, location);
931+
node.modifierToken = modifierToken;
931932
node.initializer = initializer;
932933
node.expression = expression;
933934
node.statement = statement;
934935
return node;
935936
}
936937

937-
export function updateForOf(node: ForOfStatement, initializer: ForInitializer, expression: Expression, statement: Statement) {
938-
if (node.initializer !== initializer || node.expression !== expression || node.statement !== statement) {
939-
return updateNode(createForOf(initializer, expression, statement, node), node);
938+
export function updateForOf(node: ForOfStatement, modifierToken: AwaitKeywordToken | EachKeywordToken, initializer: ForInitializer, expression: Expression, statement: Statement) {
939+
if (node.modifierToken !== modifierToken || node.initializer !== initializer || node.expression !== expression || node.statement !== statement) {
940+
return updateNode(createForOf(modifierToken, initializer, expression, statement, node), node);
940941
}
941942
return node;
942943
}
@@ -1768,7 +1769,7 @@ namespace ts {
17681769
scoped: false,
17691770
text: `
17701771
var __values = (this && this.__values) || function (o) {
1771-
var i = o.__iterator__ || 0, d;
1772+
var i = typeof Symbol === "function" && o[Symbol.iterator] || 0, d;
17721773
return i ? i.call(o) : { next: function () { return { done: d = d || i >= o.length, value: d ? void 0 : o[i++] }; } };
17731774
};`
17741775
};
@@ -1827,7 +1828,7 @@ namespace ts {
18271828
scoped: false,
18281829
text: `
18291830
var __read = (this && this.__read) || function (o, n) {
1830-
if (!(m = o.__iterator__)) return o;
1831+
if (!(m = typeof Symbol === "function" && o[Symbol.iterator])) return o;
18311832
var m, i = m.call(o), ar = [], r, e;
18321833
try { while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); }
18331834
catch (error) { e = { error: error }; }
@@ -1906,8 +1907,14 @@ namespace ts {
19061907
}
19071908
}
19081909

1909-
1910-
// Utilities
1910+
export function insertLeadingStatement(dest: Statement, source: Statement) {
1911+
if (isBlock(dest)) {
1912+
return updateBlock(dest, createNodeArray([source, ...dest.statements], dest.statements));
1913+
}
1914+
else {
1915+
return createBlock(createNodeArray([dest, source]), /*location*/ undefined, /*multiLine*/ true);
1916+
}
1917+
}
19111918

19121919
export interface CallBinding {
19131920
target: LeftHandSideExpression;
Collapse file

‎src/compiler/parser.ts‎

Copy file name to clipboardExpand all lines: src/compiler/parser.ts
+4-4Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ namespace ts {
240240
visitNode(cbNode, (<ForInStatement>node).expression) ||
241241
visitNode(cbNode, (<ForInStatement>node).statement);
242242
case SyntaxKind.ForOfStatement:
243-
return visitNode(cbNode, (<ForOfStatement>node).awaitKeyword) ||
243+
return visitNode(cbNode, (<ForOfStatement>node).modifierToken) ||
244244
visitNode(cbNode, (<ForOfStatement>node).initializer) ||
245245
visitNode(cbNode, (<ForOfStatement>node).expression) ||
246246
visitNode(cbNode, (<ForOfStatement>node).statement);
@@ -4427,7 +4427,7 @@ namespace ts {
44274427
function parseForOrForInOrForOfStatement(): Statement {
44284428
const pos = getNodePos();
44294429
parseExpected(SyntaxKind.ForKeyword);
4430-
const awaitKeyword = parseOptionalToken(SyntaxKind.AwaitKeyword);
4430+
const modifierToken = parseOptionalToken(SyntaxKind.AwaitKeyword) || parseOptionalToken(SyntaxKind.EachKeyword);
44314431
parseExpected(SyntaxKind.OpenParenToken);
44324432

44334433
let initializer: VariableDeclarationList | Expression = undefined;
@@ -4440,9 +4440,9 @@ namespace ts {
44404440
}
44414441
}
44424442
let forOrForInOrForOfStatement: IterationStatement;
4443-
if (awaitKeyword ? parseExpected(SyntaxKind.OfKeyword) : parseOptional(SyntaxKind.OfKeyword)) {
4443+
if (modifierToken ? parseExpected(SyntaxKind.OfKeyword) : parseOptional(SyntaxKind.OfKeyword)) {
44444444
const forOfStatement = <ForOfStatement>createNode(SyntaxKind.ForOfStatement, pos);
4445-
forOfStatement.awaitKeyword = awaitKeyword;
4445+
forOfStatement.modifierToken = modifierToken;
44464446
forOfStatement.initializer = initializer;
44474447
forOfStatement.expression = allowInAnd(parseAssignmentExpressionOrHigher);
44484448
parseExpected(SyntaxKind.CloseParenToken);
Collapse file

‎src/compiler/scanner.ts‎

Copy file name to clipboardExpand all lines: src/compiler/scanner.ts
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ namespace ts {
126126
"yield": SyntaxKind.YieldKeyword,
127127
"async": SyntaxKind.AsyncKeyword,
128128
"await": SyntaxKind.AwaitKeyword,
129+
"each": SyntaxKind.EachKeyword,
129130
"of": SyntaxKind.OfKeyword,
130131
"{": SyntaxKind.OpenBraceToken,
131132
"}": SyntaxKind.CloseBraceToken,
Collapse file

‎src/compiler/transformers/es2017.ts‎

Copy file name to clipboardExpand all lines: src/compiler/transformers/es2017.ts
+9-9Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -154,15 +154,15 @@ namespace ts {
154154
function visitLabeledStatement(node: LabeledStatement): VisitResult<Statement> {
155155
const enclosedStatement = getEnclosedStatement(node);
156156
if (enclosedStatement.statement.kind === SyntaxKind.ForOfStatement &&
157-
(<ForOfStatement>enclosedStatement.statement).awaitKeyword) {
157+
(<ForOfStatement>enclosedStatement.statement).modifierToken) {
158158
return visitForOfStatement(<ForOfStatement>node.statement, enclosedStatement.enclosingLabeledStatements);
159159
}
160160

161161
return restoreEnclosingLabels(visitEachChild(node, visitor, context), enclosedStatement.enclosingLabeledStatements);
162162
}
163163

164164
function visitForOfStatement(node: ForOfStatement, enclosingLabeledStatements: LabeledStatement[]): VisitResult<Statement> {
165-
if (!node.awaitKeyword) return visitEachChild(node, visitor, context);
165+
if (!node.modifierToken) return visitEachChild(node, visitor, context);
166166

167167
let bodyLocation: TextRange;
168168
let statementsLocation: TextRange;
@@ -774,8 +774,8 @@ namespace ts {
774774
scoped: false,
775775
text: `
776776
var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) {
777-
var g = generator.apply(thisArg, _arguments || []), q = [], c;
778-
return { next: verb("next"), "throw": verb("throw"), "return": verb("return"), __asyncIterator__: function () { return this; } };
777+
var g = generator.apply(thisArg, _arguments || []), q = [], c, i;
778+
return i = { next: verb("next"), "throw": verb("throw"), "return": verb("return") }, i[Symbol.asyncIterator] = function () { return this; }, i;
779779
function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; }
780780
function next() { if (!c && q.length) resume((c = q.shift())[0], c[1]); }
781781
function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(c[3], e); } }
@@ -808,9 +808,9 @@ namespace ts {
808808
name: "typescript:asyncValues",
809809
scoped: false,
810810
text: `
811-
var __asyncValues = (this && this.__asyncIterator) || function (o, iterator) {
812-
var m;
813-
return (m = o.__asyncIterator__) ? m.call(o) : typeof __values === "function" ? __values(o) : o[iterator || Symbol.iterator]();
811+
var __asyncValues = (this && this.__asyncIterator) || function (o) {
812+
var m = o[Symbol.asyncIterator];
813+
return m ? m.call(o) : typeof __values === "function" ? __values(o) : o[Symbol.iterator]();
814814
};`
815815
};
816816

@@ -832,9 +832,9 @@ namespace ts {
832832
name: "typescript:asyncDelegator",
833833
scoped: false,
834834
text: `
835-
var __asyncDelegator = (this && this.__asyncDelegator) || function (o, iterator) {
835+
var __asyncDelegator = (this && this.__asyncDelegator) || function (o) {
836836
var i = { next: verb("next"), "throw": verb("throw", function (e) { throw e; }), "return": verb("return", function (v) { return { value: v, done: true }; }) };
837-
return o = __asyncValues(o, iterator), i[iterator || Symbol.iterator] = function () { return this; }, i;
837+
return o = __asyncValues(o), i[Symbol.iterator] = function () { return this; }, i;
838838
function verb(n, f) { return function (v) { return { value: ["delegate", (o[n] || f).call(o, v)], done: false }; }; }
839839
};`
840840
};
Collapse file

‎src/compiler/transformers/esnext.ts‎

Copy file name to clipboardExpand all lines: src/compiler/transformers/esnext.ts
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,7 @@ namespace ts {
234234
: createBlock(append(leadingStatements, statement), statement, /*multiLine*/ true);
235235
return updateForOf(
236236
node,
237+
node.modifierToken,
237238
createVariableDeclarationList(
238239
[
239240
createVariableDeclaration(temp, /*type*/ undefined, /*initializer*/ undefined, node.initializer)
Collapse file

‎src/compiler/transformers/generators.ts‎

Copy file name to clipboardExpand all lines: src/compiler/transformers/generators.ts
+2-2Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3169,8 +3169,8 @@ namespace ts {
31693169
priority: 6,
31703170
text: `
31713171
var __generator = (this && this.__generator) || function (thisArg, body) {
3172-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t;
3173-
return { next: verb(0), "throw": verb(1), "return": verb(2), __iterator__: function () { return this; } };
3172+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
3173+
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
31743174
function verb(n) { return function (v) { return step([n, v]); }; }
31753175
function step(op) {
31763176
if (f) throw new TypeError("Generator is already executing.");

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.