@@ -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,18 +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- return updateYield (
130- node ,
131- node . asteriskToken ,
132- node . asteriskToken
133- ? createAsyncDelegatorHelper ( context , expression , expression )
134- : createArrayLiteral (
135- expression
136- ? [ createLiteral ( "yield" ) , expression ]
137- : [ createLiteral ( "yield" ) ]
138- )
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
139143 ) ;
140144 }
141145 return visitEachChild ( node , visitor , context ) ;
@@ -347,23 +351,22 @@ namespace ts {
347351 ) ;
348352 }
349353
354+ function awaitAsYield ( expression : Expression ) {
355+ return createYield ( /*asteriskToken*/ undefined , enclosingFunctionFlags & FunctionFlags . Generator ? createAwaitHelper ( context , expression ) : expression ) ;
356+ }
357+
350358 function transformForAwaitOfStatement ( node : ForOfStatement , outermostLabeledStatement : LabeledStatement ) {
351359 const expression = visitNode ( node . expression , visitor , isExpression ) ;
352360 const iterator = isIdentifier ( expression ) ? getGeneratedNameForNode ( expression ) : createTempVariable ( /*recordTempVariable*/ undefined ) ;
353361 const result = isIdentifier ( expression ) ? getGeneratedNameForNode ( iterator ) : createTempVariable ( /*recordTempVariable*/ undefined ) ;
354362 const errorRecord = createUniqueName ( "e" ) ;
355363 const catchVariable = getGeneratedNameForNode ( errorRecord ) ;
356364 const returnMethod = createTempVariable ( /*recordTempVariable*/ undefined ) ;
357- const values = createAsyncValuesHelper ( context , expression , /*location*/ node . expression ) ;
358- const next = createYield (
359- /*asteriskToken*/ undefined ,
360- enclosingFunctionFlags & FunctionFlags . Generator
361- ? createArrayLiteral ( [
362- createLiteral ( "await" ) ,
363- createCall ( createPropertyAccess ( iterator , "next" ) , /*typeArguments*/ undefined , [ ] )
364- ] )
365- : createCall ( createPropertyAccess ( iterator , "next" ) , /*typeArguments*/ undefined , [ ] )
366- ) ;
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 , [ ] ) ;
367370
368371 hoistVariableDeclaration ( errorRecord ) ;
369372 hoistVariableDeclaration ( returnMethod ) ;
@@ -374,16 +377,19 @@ namespace ts {
374377 /*initializer*/ setEmitFlags (
375378 setTextRange (
376379 createVariableDeclarationList ( [
377- setTextRange ( createVariableDeclaration ( iterator , /*type*/ undefined , values ) , node . expression ) ,
378- createVariableDeclaration ( result , /*type*/ undefined , next )
380+ setTextRange ( createVariableDeclaration ( iterator , /*type*/ undefined , callValues ) , node . expression ) ,
381+ createVariableDeclaration ( result )
379382 ] ) ,
380383 node . expression
381384 ) ,
382385 EmitFlags . NoHoisting
383386 ) ,
384- /*condition*/ createLogicalNot ( createPropertyAccess ( result , "done" ) ) ,
385- /*incrementor*/ createAssignment ( result , next ) ,
386- /*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 ) )
387393 ) ,
388394 /*location*/ node
389395 ) ,
@@ -421,26 +427,14 @@ namespace ts {
421427 createLogicalAnd (
422428 createLogicalAnd (
423429 result ,
424- createLogicalNot (
425- createPropertyAccess ( result , "done" )
426- )
430+ createLogicalNot ( getDone )
427431 ) ,
428432 createAssignment (
429433 returnMethod ,
430434 createPropertyAccess ( iterator , "return" )
431435 )
432436 ) ,
433- createStatement (
434- createYield (
435- /*asteriskToken*/ undefined ,
436- enclosingFunctionFlags & FunctionFlags . Generator
437- ? createArrayLiteral ( [
438- createLiteral ( "await" ) ,
439- createFunctionCall ( returnMethod , iterator , [ ] )
440- ] )
441- : createFunctionCall ( returnMethod , iterator , [ ] )
442- )
443- )
437+ createStatement ( awaitAsYield ( callReturn ) )
444438 ) ,
445439 EmitFlags . SingleLine
446440 )
@@ -880,27 +874,39 @@ namespace ts {
880874 ) ;
881875 }
882876
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+
883890 const asyncGeneratorHelper : EmitHelper = {
884891 name : "typescript:asyncGenerator" ,
885892 scoped : false ,
886893 text : `
887894 var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) {
888895 if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
889- var g = generator.apply(thisArg, _arguments || []), q = [], c, i;
890- return i = { next: verb("next"), "throw": verb("throw"), "return": verb("return") }, i[Symbol.asyncIterator] = function () { return this; }, i;
891- function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; }
892- function next() { if (!c && q.length) resume((c = q.shift())[0], c[1]); }
893- function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(c[3], e); } }
894- function step(r) { r.done ? settle(c[2], r) : Promise.resolve(r.value[1]).then(r.value[0] === "yield" ? send : fulfill, reject); }
895- 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); }
896901 function fulfill(value) { resume("next", value); }
897902 function reject(value) { resume("throw", value); }
898- 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] ); }
899904 };
900905 `
901906 } ;
902907
903908 function createAsyncGeneratorHelper ( context : TransformationContext , generatorFunc : FunctionExpression ) {
909+ context . requestEmitHelper ( awaitHelper ) ;
904910 context . requestEmitHelper ( asyncGeneratorHelper ) ;
905911
906912 // Mark this node as originally an async function
@@ -922,16 +928,16 @@ namespace ts {
922928 scoped : false ,
923929 text : `
924930 var __asyncDelegator = (this && this.__asyncDelegator) || function (o) {
925- var i = { next: verb("next"), "throw": verb("throw", function (e) { throw e; }), "return": verb("return", function (v) { return { value: v, done: true }; }) } , p;
926- return o = __asyncValues(o ), i[Symbol.iterator] = function () { return this; }, i;
927- function verb(n, f ) { return function (v) { return v = p && n === "throw" ? f (v) : p && v.done ? v : { value: p ? ["yield", v.value] : ["await", (o[n] || f).call(o, v)] , done: false }, p = !p, v; }; }
931+ var i, p;
932+ return i = {}, verb("next"), verb("throw"), verb("return" ), i[Symbol.iterator] = function () { return this; }, i;
933+ function verb(n) { if (o[n]) i[n] = function (v) { return (p = !p) ? { value: __await (o[n](v)) , done: n === "return" } : v; }; }
928934 };
929935 `
930936 } ;
931937
932938 function createAsyncDelegatorHelper ( context : TransformationContext , expression : Expression , location ?: TextRange ) {
939+ context . requestEmitHelper ( awaitHelper ) ;
933940 context . requestEmitHelper ( asyncDelegator ) ;
934- context . requestEmitHelper ( asyncValues ) ;
935941 return setTextRange (
936942 createCall (
937943 getHelperName ( "__asyncDelegator" ) ,
0 commit comments