@@ -106,15 +106,11 @@ namespace ts {
106106 }
107107 }
108108
109- function visitAwaitExpression ( node : AwaitExpression ) {
109+ function visitAwaitExpression ( node : AwaitExpression ) : Expression {
110110 if ( enclosingFunctionFlags & FunctionFlags . Async && enclosingFunctionFlags & FunctionFlags . Generator ) {
111- const expression = visitNode ( node . expression , visitor , isExpression ) ;
112111 return setOriginalNode (
113112 setTextRange (
114- createYield (
115- /*asteriskToken*/ undefined ,
116- createArrayLiteral ( [ createLiteral ( "await" ) , expression ] )
117- ) ,
113+ createYield ( createAwaitHelper ( context , visitNode ( node . expression , visitor , isExpression ) ) ) ,
118114 /*location*/ node
119115 ) ,
120116 node
@@ -124,21 +120,26 @@ namespace ts {
124120 }
125121
126122 function visitYieldExpression ( node : YieldExpression ) {
127- if ( enclosingFunctionFlags & FunctionFlags . Async && enclosingFunctionFlags & FunctionFlags . Generator ) {
123+ if ( enclosingFunctionFlags & FunctionFlags . Async && enclosingFunctionFlags & FunctionFlags . Generator && node . asteriskToken ) {
128124 const expression = visitNode ( node . expression , visitor , isExpression ) ;
129- const delegator = node . asteriskToken && updateYield (
130- node ,
131- node . asteriskToken ,
132- createAsyncDelegatorHelper ( context , expression , expression )
133- ) ;
134- return updateYield (
135- node ,
136- /*asteriskToken*/ undefined ,
137- createArrayLiteral (
138- delegator ? [ createLiteral ( "await" ) , delegator ] :
139- expression ? [ createLiteral ( "yield" ) , expression ] :
140- [ createLiteral ( "yield" ) ]
141- )
125+ return setOriginalNode (
126+ setTextRange (
127+ createYield (
128+ createAwaitHelper ( context ,
129+ updateYield (
130+ node ,
131+ node . asteriskToken ,
132+ createAsyncDelegatorHelper (
133+ context ,
134+ createAsyncValuesHelper ( context , expression , expression ) ,
135+ expression
136+ )
137+ )
138+ )
139+ ) ,
140+ node
141+ ) ,
142+ node
142143 ) ;
143144 }
144145 return visitEachChild ( node , visitor , context ) ;
@@ -350,23 +351,22 @@ namespace ts {
350351 ) ;
351352 }
352353
354+ function awaitAsYield ( expression : Expression ) {
355+ return createYield ( /*asteriskToken*/ undefined , enclosingFunctionFlags & FunctionFlags . Generator ? createAwaitHelper ( context , expression ) : expression ) ;
356+ }
357+
353358 function transformForAwaitOfStatement ( node : ForOfStatement , outermostLabeledStatement : LabeledStatement ) {
354359 const expression = visitNode ( node . expression , visitor , isExpression ) ;
355360 const iterator = isIdentifier ( expression ) ? getGeneratedNameForNode ( expression ) : createTempVariable ( /*recordTempVariable*/ undefined ) ;
356361 const result = isIdentifier ( expression ) ? getGeneratedNameForNode ( iterator ) : createTempVariable ( /*recordTempVariable*/ undefined ) ;
357362 const errorRecord = createUniqueName ( "e" ) ;
358363 const catchVariable = getGeneratedNameForNode ( errorRecord ) ;
359364 const returnMethod = createTempVariable ( /*recordTempVariable*/ undefined ) ;
360- const values = createAsyncValuesHelper ( context , expression , /*location*/ node . expression ) ;
361- const next = createYield (
362- /*asteriskToken*/ undefined ,
363- enclosingFunctionFlags & FunctionFlags . Generator
364- ? createArrayLiteral ( [
365- createLiteral ( "await" ) ,
366- createCall ( createPropertyAccess ( iterator , "next" ) , /*typeArguments*/ undefined , [ ] )
367- ] )
368- : createCall ( createPropertyAccess ( iterator , "next" ) , /*typeArguments*/ undefined , [ ] )
369- ) ;
365+ const callValues = createAsyncValuesHelper ( context , expression , /*location*/ node . expression ) ;
366+ const callNext = createCall ( createPropertyAccess ( iterator , "next" ) , /*typeArguments*/ undefined , [ ] ) ;
367+ const getDone = createPropertyAccess ( result , "done" ) ;
368+ const getValue = createPropertyAccess ( result , "value" ) ;
369+ const callReturn = createFunctionCall ( returnMethod , iterator , [ ] ) ;
370370
371371 hoistVariableDeclaration ( errorRecord ) ;
372372 hoistVariableDeclaration ( returnMethod ) ;
@@ -377,16 +377,19 @@ namespace ts {
377377 /*initializer*/ setEmitFlags (
378378 setTextRange (
379379 createVariableDeclarationList ( [
380- setTextRange ( createVariableDeclaration ( iterator , /*type*/ undefined , values ) , node . expression ) ,
381- createVariableDeclaration ( result , /*type*/ undefined , next )
380+ setTextRange ( createVariableDeclaration ( iterator , /*type*/ undefined , callValues ) , node . expression ) ,
381+ createVariableDeclaration ( result )
382382 ] ) ,
383383 node . expression
384384 ) ,
385385 EmitFlags . NoHoisting
386386 ) ,
387- /*condition*/ createLogicalNot ( createPropertyAccess ( result , "done" ) ) ,
388- /*incrementor*/ createAssignment ( result , next ) ,
389- /*statement*/ convertForOfStatementHead ( node , createPropertyAccess ( result , "value" ) )
387+ /*condition*/ createComma (
388+ createAssignment ( result , awaitAsYield ( callNext ) ) ,
389+ createLogicalNot ( getDone )
390+ ) ,
391+ /*incrementor*/ undefined ,
392+ /*statement*/ convertForOfStatementHead ( node , awaitAsYield ( getValue ) )
390393 ) ,
391394 /*location*/ node
392395 ) ,
@@ -424,26 +427,14 @@ namespace ts {
424427 createLogicalAnd (
425428 createLogicalAnd (
426429 result ,
427- createLogicalNot (
428- createPropertyAccess ( result , "done" )
429- )
430+ createLogicalNot ( getDone )
430431 ) ,
431432 createAssignment (
432433 returnMethod ,
433434 createPropertyAccess ( iterator , "return" )
434435 )
435436 ) ,
436- createStatement (
437- createYield (
438- /*asteriskToken*/ undefined ,
439- enclosingFunctionFlags & FunctionFlags . Generator
440- ? createArrayLiteral ( [
441- createLiteral ( "await" ) ,
442- createFunctionCall ( returnMethod , iterator , [ ] )
443- ] )
444- : createFunctionCall ( returnMethod , iterator , [ ] )
445- )
446- )
437+ createStatement ( awaitAsYield ( callReturn ) )
447438 ) ,
448439 EmitFlags . SingleLine
449440 )
@@ -883,27 +874,39 @@ namespace ts {
883874 ) ;
884875 }
885876
877+ const awaitHelper : EmitHelper = {
878+ name : "typescript:await" ,
879+ scoped : false ,
880+ text : `
881+ var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); }
882+ `
883+ } ;
884+
885+ function createAwaitHelper ( context : TransformationContext , expression : Expression ) {
886+ context . requestEmitHelper ( awaitHelper ) ;
887+ return createCall ( createIdentifier ( "__await" ) , /*typeArguments*/ undefined , [ expression ] ) ;
888+ }
889+
886890 const asyncGeneratorHelper : EmitHelper = {
887891 name : "typescript:asyncGenerator" ,
888892 scoped : false ,
889893 text : `
890894 var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) {
891895 if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
892- var g = generator.apply(thisArg, _arguments || []), q = [], c, i;
893- return i = { next: verb("next"), "throw": verb("throw"), "return": verb("return") }, i[Symbol.asyncIterator] = function () { return this; }, i;
894- function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; }
895- function next() { if (!c && q.length) resume((c = q.shift())[0], c[1]); }
896- function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(c[3], e); } }
897- function step(r) { r.done ? settle(c[2], r) : Promise.resolve(r.value[1]).then(r.value[0] === "yield" ? send : fulfill, reject); }
898- function send(value) { settle(c[2], { value: value, done: false }); }
896+ var g = generator.apply(thisArg, _arguments || []), i, q = [];
897+ return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i;
898+ function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }
899+ function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }
900+ function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
899901 function fulfill(value) { resume("next", value); }
900902 function reject(value) { resume("throw", value); }
901- function settle(f, v) { c = void 0, f(v), next( ); }
903+ function settle(f, v) { if ( f(v), q.shift(), q.length) resume(q[0][0], q[0][1] ); }
902904 };
903905 `
904906 } ;
905907
906908 function createAsyncGeneratorHelper ( context : TransformationContext , generatorFunc : FunctionExpression ) {
909+ context . requestEmitHelper ( awaitHelper ) ;
907910 context . requestEmitHelper ( asyncGeneratorHelper ) ;
908911
909912 // Mark this node as originally an async function
@@ -925,16 +928,16 @@ namespace ts {
925928 scoped : false ,
926929 text : `
927930 var __asyncDelegator = (this && this.__asyncDelegator) || function (o) {
928- var i, f ;
929- return o = __asyncValues(o), i = { next: verb("next"), "throw": verb("throw"), "return": verb("return") }, i[Symbol.iterator] = function () { return this; }, i;
930- function verb(n) { return o[n] && function (b ) { return (f = !f ) ? { value: ["await", new Promise(function(r) { r( o[n](b)); })] , done: n === "return" } : b.done ? b : { value: ["yield", b.value], done: false } ; }; }
931+ var i = { next: verb("next"), "throw": verb("throw"), "return": verb("return") }, p ;
932+ return i[Symbol.iterator] = function () { return this; }, i;
933+ function verb(n) { return o[n] && function (v ) { return (p = !p ) ? { value: __await( o[n](v)) , done: n === "return" } : v ; }; }
931934 };
932935 `
933936 } ;
934937
935938 function createAsyncDelegatorHelper ( context : TransformationContext , expression : Expression , location ?: TextRange ) {
939+ context . requestEmitHelper ( awaitHelper ) ;
936940 context . requestEmitHelper ( asyncDelegator ) ;
937- context . requestEmitHelper ( asyncValues ) ;
938941 return setTextRange (
939942 createCall (
940943 getHelperName ( "__asyncDelegator" ) ,
0 commit comments