From 1fb8a249dfcd577cc2d519775019f18ac2c7171c Mon Sep 17 00:00:00 2001 From: Dirk Holtwick Date: Tue, 1 Dec 2015 10:26:14 +0100 Subject: [PATCH 1/3] Enable await in ES6 and ES2015 script mode Even though strictly generators are an ES6 feature the real world support is large enough to use the feature in well known environments like node.js or Electron app. Since the previous output was not working at all anyway it feels like a good compromise to at least emit working code while still having the warning in place. The user would also need to add "use strict" on top of her .ts file to make it work with node.js. --- src/compiler/emitter.ts | 54 +++++++++++++++++++++-------------------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 88847999a4..09ae33c4ed 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -4514,32 +4514,34 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi convertedLoopState = undefined; tempFlags = 0; - tempVariables = undefined; - tempParameters = undefined; - - // When targeting ES6, emit arrow function natively in ES6 - if (shouldEmitAsArrowFunction(node)) { - emitSignatureParametersForArrow(node); - write(" =>"); - } - else { - emitSignatureParameters(node); - } - - const isAsync = isAsyncFunctionLike(node); - if (isAsync && languageVersion === ScriptTarget.ES6) { - emitAsyncFunctionBodyForES6(node); - } - else { - emitFunctionBody(node); - } - - if (!isES6ExportedDeclaration(node)) { - emitExportMemberAssignment(node); - } - - Debug.assert(convertedLoopState === undefined); - convertedLoopState = saveConvertedLoopState; + tempVariables = undefined; + tempParameters = undefined; + + // When targeting ES6, emit arrow function natively in ES6 + if (shouldEmitAsArrowFunction(node)) { + emitSignatureParametersForArrow(node); + write(" =>"); + } + else { + emitSignatureParameters(node); + } + + // Even though generators are a ES6 only feature, the functionality is wiedely supported + // in current browsers and latest node, therefore showing some tolerance + const isAsync = isAsyncFunctionLike(node); + if (isAsync && (languageVersion === ScriptTarget.ES6 || languageVersion === ScriptTarget.ES2015 || languageVersion === ScriptTarget.ES5)) { + emitAsyncFunctionBodyForES6(node); + } + else { + emitFunctionBody(node); + } + + if (!isES6ExportedDeclaration(node)) { + emitExportMemberAssignment(node); + } + + Debug.assert(convertedLoopState === undefined); + convertedLoopState = saveConvertedLoopState; tempFlags = saveTempFlags; tempVariables = saveTempVariables; From c12d29bda5fba0efef6473c95bae2c2abd1be996 Mon Sep 17 00:00:00 2001 From: Dirk Holtwick Date: Tue, 1 Dec 2015 20:26:20 +0100 Subject: [PATCH 2/3] Simplifying the pre ES6 async/await change --- src/compiler/emitter.ts | 58 ++++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 30 deletions(-) diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 09ae33c4ed..557c02bf4f 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -2978,7 +2978,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi } else { // this is top level converted loop so we need to create an alias for 'this' here - // NOTE: + // NOTE: // if converted loops were all nested in arrow function then we'll always emit '_this' so convertedLoopState.thisName will not be set. // If it is set this means that all nested loops are not nested in arrow function and it is safe to capture 'this'. write(`var ${convertedLoopState.thisName} = this;`); @@ -4369,7 +4369,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi function emitAsyncFunctionBodyForES6(node: FunctionLikeDeclaration) { const promiseConstructor = getEntityNameFromTypeNode(node.type); - const isArrowFunction = node.kind === SyntaxKind.ArrowFunction; + const isArrowFunction = node.kind === SyntaxKind.ArrowFunction; const hasLexicalArguments = (resolver.getNodeCheckFlags(node) & NodeCheckFlags.CaptureArguments) !== 0; // An async function is emit as an outer function that calls an inner @@ -4514,34 +4514,32 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi convertedLoopState = undefined; tempFlags = 0; - tempVariables = undefined; - tempParameters = undefined; - - // When targeting ES6, emit arrow function natively in ES6 - if (shouldEmitAsArrowFunction(node)) { - emitSignatureParametersForArrow(node); - write(" =>"); - } - else { - emitSignatureParameters(node); - } - - // Even though generators are a ES6 only feature, the functionality is wiedely supported - // in current browsers and latest node, therefore showing some tolerance - const isAsync = isAsyncFunctionLike(node); - if (isAsync && (languageVersion === ScriptTarget.ES6 || languageVersion === ScriptTarget.ES2015 || languageVersion === ScriptTarget.ES5)) { - emitAsyncFunctionBodyForES6(node); - } - else { - emitFunctionBody(node); - } - - if (!isES6ExportedDeclaration(node)) { - emitExportMemberAssignment(node); - } - - Debug.assert(convertedLoopState === undefined); - convertedLoopState = saveConvertedLoopState; + tempVariables = undefined; + tempParameters = undefined; + + // When targeting ES6, emit arrow function natively in ES6 + if (shouldEmitAsArrowFunction(node)) { + emitSignatureParametersForArrow(node); + write(" =>"); + } + else { + emitSignatureParameters(node); + } + + const isAsync = isAsyncFunctionLike(node); + if (isAsync) { + emitAsyncFunctionBodyForES6(node); + } + else { + emitFunctionBody(node); + } + + if (!isES6ExportedDeclaration(node)) { + emitExportMemberAssignment(node); + } + + Debug.assert(convertedLoopState === undefined); + convertedLoopState = saveConvertedLoopState; tempFlags = saveTempFlags; tempVariables = saveTempVariables; From acd1760c8c7fcde17189c517718c13645565ec55 Mon Sep 17 00:00:00 2001 From: Dirk Holtwick Date: Tue, 1 Dec 2015 20:30:50 +0100 Subject: [PATCH 3/3] Fix whitespace issues --- src/compiler/emitter.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 557c02bf4f..641c50a818 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -2978,7 +2978,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi } else { // this is top level converted loop so we need to create an alias for 'this' here - // NOTE: + // NOTE: // if converted loops were all nested in arrow function then we'll always emit '_this' so convertedLoopState.thisName will not be set. // If it is set this means that all nested loops are not nested in arrow function and it is safe to capture 'this'. write(`var ${convertedLoopState.thisName} = this;`); @@ -4369,7 +4369,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi function emitAsyncFunctionBodyForES6(node: FunctionLikeDeclaration) { const promiseConstructor = getEntityNameFromTypeNode(node.type); - const isArrowFunction = node.kind === SyntaxKind.ArrowFunction; + const isArrowFunction = node.kind === SyntaxKind.ArrowFunction; const hasLexicalArguments = (resolver.getNodeCheckFlags(node) & NodeCheckFlags.CaptureArguments) !== 0; // An async function is emit as an outer function that calls an inner