Skip to content
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

Async Iteration and down-level Generators #12346

Merged
merged 51 commits into from
Feb 17, 2017
Merged
Show file tree
Hide file tree
Changes from 46 commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
6453fde
Move emit helpers into related transformers
rbuckton Oct 22, 2016
86091d7
Clean up and consolidate destructuring transform
rbuckton Oct 26, 2016
a2e0b19
Emit for full down-level generators
rbuckton Oct 26, 2016
fea6827
Merge branch 'master' into asyncGenerators
rbuckton Nov 3, 2016
cb85356
Relaxed ES2015 restrictions for generator type check
rbuckton Nov 5, 2016
c6ee25d
Type checking for async iterables and async generators.
rbuckton Nov 6, 2016
74ec093
Merge branch 'emitHelper' into asyncGenerators
rbuckton Nov 9, 2016
bd86778
type checking for pseudoiterable
rbuckton Nov 9, 2016
549ac8f
Updated baselines
rbuckton Nov 9, 2016
b5cc96c
Merge branch 'asyncGeneratorsUpLevel' into asyncGenerators
rbuckton Nov 9, 2016
4b5686a
Added emit transforms for async generators.
rbuckton Nov 10, 2016
4f3fb80
Parse, check, and downlevel emit for for-await-of
rbuckton Nov 10, 2016
a4036c7
Added emit helper checks for async generators
rbuckton Nov 11, 2016
ab1dc52
Merge branch 'emitHelper' into asyncGenerators
rbuckton Nov 16, 2016
d6a5e39
Merge branch 'improveImportHelpersDiagnostics' into asyncGenerators
rbuckton Nov 16, 2016
28d23ce
Add for-await-of, always use Symbol for iterables.
rbuckton Nov 16, 2016
df303c9
Updated baselines
rbuckton Nov 16, 2016
e53263e
Added conformance tests for async generators
rbuckton Nov 18, 2016
42085a6
Conformance tests for for-await-of
rbuckton Nov 18, 2016
c758359
ES6 tests for async generators
rbuckton Nov 18, 2016
281c890
ES5 tests for async generators
rbuckton Nov 18, 2016
1af8ac8
Update es2017 library and baseline
rbuckton Nov 18, 2016
1c0917a
Merge branch 'master' into asyncGenerators
rbuckton Nov 18, 2016
2f6ac58
Fix lint warnings
rbuckton Nov 18, 2016
c72509b
Added iterationMode switch, consolidate some tests, cleanup
rbuckton Nov 19, 2016
32bcc97
Revert diagnostic error number change
rbuckton Nov 19, 2016
38b7757
Tests for iterationMode=iterable
rbuckton Nov 19, 2016
1980334
Merge branch 'master' into asyncGenerators
rbuckton Nov 19, 2016
8af87dc
Merge branch 'master' into asyncGenerators
rbuckton Nov 30, 2016
87eeb57
Merge branch 'master' into asyncGenerators
rbuckton Dec 19, 2016
b0faa92
Merge branch 'es2015-cleanup' into asyncGenerators
rbuckton Dec 20, 2016
0d7c9dc
Merge branch 'master' into asyncGenerators
rbuckton Dec 30, 2016
6a737c8
Move async generators to esnext
rbuckton Dec 30, 2016
30aff2f
Rename and simplify 'iterationMode' option
rbuckton Dec 30, 2016
5e0160b
Reduce number of helpers
rbuckton Jan 1, 2017
2e62d5e
Cleanup emit helper checks
rbuckton Jan 1, 2017
35ef1f7
Merge branch 'master' into asyncGenerators
rbuckton Jan 15, 2017
f9999e9
PR Feedback
rbuckton Jan 18, 2017
74498bb
Remove unnecessary widening, more PR feedback
rbuckton Jan 19, 2017
21bf485
Always descend into loop, fix lint warnings
rbuckton Jan 19, 2017
5d415ca
Merge branch 'master' into asyncGenerators
rbuckton Feb 2, 2017
64be1f2
merge getIteratedTypeOfIterableOrElementTypeOf*
rbuckton Feb 2, 2017
56a360c
Unify getIteratedTypeOf* functions
rbuckton Feb 3, 2017
94b37b1
Inline isThenableType
rbuckton Feb 3, 2017
5ca6665
Typos and other minor PR feedback
rbuckton Feb 3, 2017
e1f8be5
Merge checkIteratedType* functions
rbuckton Feb 3, 2017
3e427f4
Merge branch 'master' into asyncGenerators
rbuckton Feb 10, 2017
dedf4a7
Merge branch 'master' into asyncGenerators
rbuckton Feb 13, 2017
344a9d2
PR feedback
rbuckton Feb 17, 2017
cf72ceb
Merge branch 'master' into asyncGenerators
rbuckton Feb 17, 2017
11f58ea
Minor fixes after merging from master
rbuckton Feb 17, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
11 changes: 10 additions & 1 deletion Gulpfile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,14 @@ const es2017LibrarySourceMap = es2017LibrarySource.map(function(source) {
return { target: "lib." + source, sources: ["header.d.ts", source] };
});

const esnextLibrarySource = [
"esnext.asynciterable.d.ts"
];

const esnextLibrarySourceMap = esnextLibrarySource.map(function (source) {
Copy link
Member

@sandersn sandersn Jan 17, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not use an arrow function here? #Closed

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consistency with the surrounding code.

return { target: "lib." + source, sources: ["header.d.ts", source] };
});

const hostsLibrarySources = ["dom.generated.d.ts", "webworker.importscripts.d.ts", "scripthost.d.ts"];

const librarySourceMap = [
Expand All @@ -152,11 +160,12 @@ const librarySourceMap = [
{ target: "lib.es2015.d.ts", sources: ["header.d.ts", "es2015.d.ts"] },
{ target: "lib.es2016.d.ts", sources: ["header.d.ts", "es2016.d.ts"] },
{ target: "lib.es2017.d.ts", sources: ["header.d.ts", "es2017.d.ts"] },
{ target: "lib.esnext.d.ts", sources: ["header.d.ts", "esnext.d.ts"] },

// JavaScript + all host library
{ target: "lib.d.ts", sources: ["header.d.ts", "es5.d.ts"].concat(hostsLibrarySources) },
{ target: "lib.es6.d.ts", sources: ["header.d.ts", "es5.d.ts"].concat(es2015LibrarySources, hostsLibrarySources, "dom.iterable.d.ts") }
].concat(es2015LibrarySourceMap, es2016LibrarySourceMap, es2017LibrarySourceMap);
].concat(es2015LibrarySourceMap, es2016LibrarySourceMap, es2017LibrarySourceMap, esnextLibrarySourceMap);

const libraryTargets = librarySourceMap.map(function(f) {
return path.join(builtLocalDirectory, f.target);
Expand Down
13 changes: 11 additions & 2 deletions Jakefile.js
Original file line number Diff line number Diff line change
Expand Up @@ -311,13 +311,21 @@ var es2016LibrarySourceMap = es2016LibrarySource.map(function (source) {
var es2017LibrarySource = [
"es2017.object.d.ts",
"es2017.sharedmemory.d.ts",
"es2017.string.d.ts",
"es2017.string.d.ts"
];

var es2017LibrarySourceMap = es2017LibrarySource.map(function (source) {
return { target: "lib." + source, sources: ["header.d.ts", source] };
});

var esnextLibrarySource = [
"esnext.asynciterable.d.ts"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we need to update VS setup to include this file as well.

];

var esnextLibrarySourceMap = esnextLibrarySource.map(function (source) {
return { target: "lib." + source, sources: ["header.d.ts", source] };
});

var hostsLibrarySources = ["dom.generated.d.ts", "webworker.importscripts.d.ts", "scripthost.d.ts"];

var librarySourceMap = [
Expand All @@ -332,11 +340,12 @@ var librarySourceMap = [
{ target: "lib.es2015.d.ts", sources: ["header.d.ts", "es2015.d.ts"] },
{ target: "lib.es2016.d.ts", sources: ["header.d.ts", "es2016.d.ts"] },
{ target: "lib.es2017.d.ts", sources: ["header.d.ts", "es2017.d.ts"] },
{ target: "lib.esnext.d.ts", sources: ["header.d.ts", "esnext.d.ts"] },

// JavaScript + all host library
{ target: "lib.d.ts", sources: ["header.d.ts", "es5.d.ts"].concat(hostsLibrarySources) },
{ target: "lib.es6.d.ts", sources: ["header.d.ts", "es5.d.ts"].concat(es2015LibrarySources, hostsLibrarySources, "dom.iterable.d.ts") }
].concat(es2015LibrarySourceMap, es2016LibrarySourceMap, es2017LibrarySourceMap);
].concat(es2015LibrarySourceMap, es2016LibrarySourceMap, es2017LibrarySourceMap, esnextLibrarySourceMap);

var libraryTargets = librarySourceMap.map(function (f) {
return path.join(builtLocalDirectory, f.target);
Expand Down
45 changes: 25 additions & 20 deletions src/compiler/binder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -956,6 +956,9 @@ namespace ts {
const postLoopLabel = createBranchLabel();
addAntecedent(preLoopLabel, currentFlow);
currentFlow = preLoopLabel;
if (node.kind === SyntaxKind.ForOfStatement) {
bind(node.awaitModifier);
}
bind(node.expression);
addAntecedent(postLoopLabel, currentFlow);
bind(node.initializer);
Expand Down Expand Up @@ -2331,7 +2334,7 @@ namespace ts {

function bindFunctionDeclaration(node: FunctionDeclaration) {
if (!isDeclarationFile(file) && !isInAmbientContext(node)) {
if (isAsyncFunctionLike(node)) {
if (isAsyncFunction(node)) {
emitFlags |= NodeFlags.HasAsyncFunctions;
}
}
Expand All @@ -2348,7 +2351,7 @@ namespace ts {

function bindFunctionExpression(node: FunctionExpression) {
if (!isDeclarationFile(file) && !isInAmbientContext(node)) {
if (isAsyncFunctionLike(node)) {
if (isAsyncFunction(node)) {
emitFlags |= NodeFlags.HasAsyncFunctions;
}
}
Expand All @@ -2362,7 +2365,7 @@ namespace ts {

function bindPropertyOrMethodOrAccessor(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags) {
if (!isDeclarationFile(file) && !isInAmbientContext(node)) {
if (isAsyncFunctionLike(node)) {
if (isAsyncFunction(node)) {
emitFlags |= NodeFlags.HasAsyncFunctions;
}
}
Expand Down Expand Up @@ -2796,11 +2799,10 @@ namespace ts {

// An async method declaration is ES2017 syntax.
if (hasModifier(node, ModifierFlags.Async)) {
transformFlags |= TransformFlags.AssertES2017;
transformFlags |= node.asteriskToken ? TransformFlags.AssertESNext : TransformFlags.AssertES2017;
}

// Currently, we only support generators that were originally async function bodies.
if (node.asteriskToken && getEmitFlags(node) & EmitFlags.AsyncFunctionBody) {
if (node.asteriskToken) {
transformFlags |= TransformFlags.AssertGenerator;
}

Expand Down Expand Up @@ -2866,7 +2868,7 @@ namespace ts {

// An async function declaration is ES2017 syntax.
if (modifierFlags & ModifierFlags.Async) {
transformFlags |= TransformFlags.AssertES2017;
transformFlags |= node.asteriskToken ? TransformFlags.AssertESNext : TransformFlags.AssertES2017;
}

// function declarations with object rest destructuring are ES Next syntax
Expand All @@ -2886,7 +2888,7 @@ namespace ts {
// down-level generator.
// Currently we do not support transforming any other generator fucntions
// down level.
if (node.asteriskToken && getEmitFlags(node) & EmitFlags.AsyncFunctionBody) {
if (node.asteriskToken) {
transformFlags |= TransformFlags.AssertGenerator;
}
}
Expand All @@ -2908,7 +2910,7 @@ namespace ts {

// An async function expression is ES2017 syntax.
if (hasModifier(node, ModifierFlags.Async)) {
transformFlags |= TransformFlags.AssertES2017;
transformFlags |= node.asteriskToken ? TransformFlags.AssertESNext : TransformFlags.AssertES2017;
}

// function expressions with object rest destructuring are ES Next syntax
Expand All @@ -2927,9 +2929,7 @@ namespace ts {
// If a FunctionExpression is generator function and is the body of a
// transformed async function, then this node can be transformed to a
// down-level generator.
// Currently we do not support transforming any other generator fucntions
// down level.
if (node.asteriskToken && getEmitFlags(node) & EmitFlags.AsyncFunctionBody) {
if (node.asteriskToken) {
Copy link
Member

@sandersn sandersn Jan 17, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove comment on line 2922-2926 #Closed

transformFlags |= TransformFlags.AssertGenerator;
}

Expand Down Expand Up @@ -3097,8 +3097,8 @@ namespace ts {
switch (kind) {
case SyntaxKind.AsyncKeyword:
case SyntaxKind.AwaitExpression:
// async/await is ES2017 syntax
transformFlags |= TransformFlags.AssertES2017;
// async/await is ES2017 syntax, but may be ESNext syntax (for async generators)
transformFlags |= TransformFlags.AssertESNext | TransformFlags.AssertES2017;
break;

case SyntaxKind.PublicKeyword:
Expand Down Expand Up @@ -3129,10 +3129,6 @@ namespace ts {
transformFlags |= TransformFlags.AssertJsx;
break;

case SyntaxKind.ForOfStatement:
// for-of might be ESNext if it has a rest destructuring
transformFlags |= TransformFlags.AssertESNext;
// FALLTHROUGH
case SyntaxKind.NoSubstitutionTemplateLiteral:
case SyntaxKind.TemplateHead:
case SyntaxKind.TemplateMiddle:
Expand All @@ -3146,9 +3142,18 @@ namespace ts {
transformFlags |= TransformFlags.AssertES2015;
break;

case SyntaxKind.ForOfStatement:
// This node is either ES2015 syntax or ES2017 syntax (if it is a for-await-of).
if ((<ForOfStatement>node).awaitModifier) {
transformFlags |= TransformFlags.AssertESNext;
Copy link
Member

@sandersn sandersn Jan 17, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what about rest destructuring? Is that no longer handled by the ESNext transformer? #Resolved

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The way that the esnext transformer works now is to always descend through the tree if some node is marked ESNext. The SpreadAssignment case handles that further down, so we can reduce false positives in for..of triggering the esnext transform when it isn't needed.

}
transformFlags |= TransformFlags.AssertES2015;
break;

case SyntaxKind.YieldExpression:
// This node is ES6 syntax.
transformFlags |= TransformFlags.AssertES2015 | TransformFlags.ContainsYield;
// This node is either ES2015 syntax (in a generator) or ES2017 syntax (in an async
// generator).
transformFlags |= TransformFlags.AssertESNext | TransformFlags.AssertES2015 | TransformFlags.ContainsYield;
break;

case SyntaxKind.AnyKeyword:
Expand Down
Loading