Add support for external helpers module, cleanup, and accept new baselines.

This commit is contained in:
Ron Buckton 2016-06-15 13:49:32 -07:00
parent 4eb2a82dca
commit 278a350add
11 changed files with 273 additions and 128 deletions

View file

@ -17892,6 +17892,9 @@ namespace ts {
}
if (requestedExternalEmitHelpers & NodeFlags.HasAsyncFunctions) {
verifyHelperSymbol(exports, "__awaiter", SymbolFlags.Value);
if (languageVersion < ScriptTarget.ES6) {
verifyHelperSymbol(exports, "__generator", SymbolFlags.Value);
}
}
}
}

View file

@ -73,51 +73,40 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
const generatorHelper = `
var __generator = (this && this.__generator) || function (body) {
var _ = { label: 0, sent: function() { if (sent[0] === 1 /*throw*/) throw sent[1]; return sent[1]; }, trys: [], stack: [] }, sent;
var _ = { label: 0, sent: function() { if (sent[0] === 1) throw sent[1]; return sent[1]; }, trys: [], stack: [] }, sent, f;
function step(op) {
if (_.flag) throw new TypeError("Generator is already executing.");
while (true) {
if (f) throw new TypeError("Generator is already executing.");
while (1) {
if (_.done) switch (op[0]) {
case 0 /*next*/: return { value: void 0, done: true };
case 1 /*throw*/: case 6 /*catch*/: throw op[1];
case 2 /*return*/: return { value: op[1], done: true };
case 0: return { value: void 0, done: true };
case 1: case 6: throw op[1];
case 2: return { value: op[1], done: true };
}
try {
switch (_.flag = true, op[0]) {
case 0 /*next*/: case 1 /*throw*/: sent = op; break;
case 4 /*yield*/: return _.label++, { value: op[1], done: false };
case 7 /*endfinally*/: op = _.stack.pop(), _.trys.pop(); continue;
switch (f = 1, op[0]) {
case 0: case 1: sent = op; break;
case 4: return _.label++, { value: op[1], done: false };
case 7: op = _.stack.pop(), _.trys.pop(); continue;
default:
var r = _.trys.length > 0 && _.trys[_.trys.length - 1];
if (!r && (op[0] === 1 /*throw*/ || op[0] === 6 /*catch*/ || op[0] === 2 /*return*/)) {
_.done = true;
continue;
}
if (op[0] === 3 /*break*/ && (!r || (op[1] > r[0] && op[1] < r[3]))) {
_.label = op[1];
}
else if (op[0] === 6 /*catch*/ && r && _.label < r[1]) {
_.label = r[1], sent = op;
}
else if (r && _.label < r[2]) {
_.label = r[2], _.stack.push(op);
}
else {
if (r[2]) _.stack.pop();
_.trys.pop();
continue;
}
if (!r && (op[0] === 6 || op[0] === 2)) { _.done = 1; continue; }
if (op[0] === 3 && (!r || (op[1] > r[0] && op[1] < r[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < r[1]) { _.label = r[1], sent = op; break; }
if (r && _.label < r[2]) { _.label = r[2], _.stack.push(op); break; }
if (r[2]) { _.stack.pop(); }
_.trys.pop();
continue;
}
op = body(_);
}
catch (e) { op = [6 /*catch*/, e]; }
finally { _.flag = false, sent = void 0; }
catch (e) { op = [6, e]; }
finally { f = 0, sent = void 0; }
}
}
return {
next: function (v) { return step([0 /*next*/, v]); },
"throw": function (v) { return step([1 /*throw*/, v]); },
"return": function (v) { return step([2 /*return*/, v]); }
next: function (v) { return step([0, v]); },
"throw": function (v) { return step([1, v]); },
"return": function (v) { return step([2, v]); }
};
};`;

View file

@ -137,11 +137,7 @@ namespace ts {
Endfinally // Marks the end of a `finally` block
}
type OperationArguments = [Label]
| [Label, Expression]
| [Statement]
| [Expression]
| [Expression, Expression];
type OperationArguments = [Label] | [Label, Expression] | [Statement] | [Expression] | [Expression, Expression];
// whether a generated code block is opening or closing at the current operation for a FunctionBuilder
const enum BlockAction {
@ -245,6 +241,7 @@ namespace ts {
const previousOnSubstituteNode = context.onSubstituteNode;
context.onSubstituteNode = onSubstituteNode;
let currentSourceFile: SourceFile;
let renamedCatchVariables: Map<boolean>;
let renamedCatchVariableDeclarations: Map<Identifier>;
@ -297,7 +294,9 @@ namespace ts {
function transformSourceFile(node: SourceFile) {
if (node.transformFlags & TransformFlags.ContainsGenerator) {
return visitEachChild(node, visitor, context);
currentSourceFile = node;
node = visitEachChild(node, visitor, context);
currentSourceFile = undefined;
}
return node;
@ -2550,7 +2549,7 @@ namespace ts {
const buildResult = buildStatements();
return createCall(
createIdentifier("__generator"),
createHelperName(currentSourceFile.externalHelpersModuleName, "__generator"),
/*typeArguments*/ undefined,
[setNodeEmitFlags(
createFunctionExpression(

View file

@ -1,27 +0,0 @@
error TS2318: Cannot find global type 'Promise'.
tests/cases/compiler/disallowAsyncModifierInES5.ts(2,1): error TS1311: Async functions are only available when targeting ECMAScript 2015 or higher.
tests/cases/compiler/disallowAsyncModifierInES5.ts(2,16): error TS1057: An async function or method must have a valid awaitable return type.
tests/cases/compiler/disallowAsyncModifierInES5.ts(3,11): error TS1057: An async function or method must have a valid awaitable return type.
tests/cases/compiler/disallowAsyncModifierInES5.ts(3,11): error TS1311: Async functions are only available when targeting ECMAScript 2015 or higher.
tests/cases/compiler/disallowAsyncModifierInES5.ts(4,11): error TS1311: Async functions are only available when targeting ECMAScript 2015 or higher.
tests/cases/compiler/disallowAsyncModifierInES5.ts(4,11): error TS1057: An async function or method must have a valid awaitable return type.
!!! error TS2318: Cannot find global type 'Promise'.
==== tests/cases/compiler/disallowAsyncModifierInES5.ts (6 errors) ====
async function foo() { return 42; } // ERROR: Async functions are only available in ES6+
~~~~~
!!! error TS1311: Async functions are only available when targeting ECMAScript 2015 or higher.
~~~
!!! error TS1057: An async function or method must have a valid awaitable return type.
let bar = async function () { return 42; } // OK, but should be an error
~~~~~
!!! error TS1057: An async function or method must have a valid awaitable return type.
~~~~~
!!! error TS1311: Async functions are only available when targeting ECMAScript 2015 or higher.
let baz = async () => 42; // OK, but should be an error
~~~~~
!!! error TS1311: Async functions are only available when targeting ECMAScript 2015 or higher.
~~~~~~~~~~~~~~
!!! error TS1057: An async function or method must have a valid awaitable return type.

View file

@ -1,23 +0,0 @@
//// [disallowAsyncModifierInES5.ts]
async function foo() { return 42; } // ERROR: Async functions are only available in ES6+
let bar = async function () { return 42; } // OK, but should be an error
let baz = async () => 42; // OK, but should be an error
//// [disallowAsyncModifierInES5.js]
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator.throw(value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments)).next());
});
};
var _this = this;
function foo() {
return __awaiter(this, void 0, void 0, function* () { return 42; });
} // ERROR: Async functions are only available in ES6+
var bar = function () {
return __awaiter(this, void 0, void 0, function* () { return 42; });
}; // OK, but should be an error
var baz = function () { return __awaiter(_this, void 0, void 0, function* () { return 42; }); }; // OK, but should be an error

View file

@ -18,51 +18,40 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
});
};
var __generator = (this && this.__generator) || function (body) {
var _ = { label: 0, sent: function() { if (sent[0] === 1 /*throw*/) throw sent[1]; return sent[1]; }, trys: [], stack: [] }, sent;
var _ = { label: 0, sent: function() { if (sent[0] === 1) throw sent[1]; return sent[1]; }, trys: [], stack: [] }, sent, f;
function step(op) {
if (_.flag) throw new TypeError("Generator is already executing.");
while (true) {
if (f) throw new TypeError("Generator is already executing.");
while (1) {
if (_.done) switch (op[0]) {
case 0 /*next*/: return { value: void 0, done: true };
case 1 /*throw*/: case 6 /*catch*/: throw op[1];
case 2 /*return*/: return { value: op[1], done: true };
case 0: return { value: void 0, done: true };
case 1: case 6: throw op[1];
case 2: return { value: op[1], done: true };
}
try {
switch (_.flag = true, op[0]) {
case 0 /*next*/: case 1 /*throw*/: sent = op; break;
case 4 /*yield*/: return _.label++, { value: op[1], done: false };
case 7 /*endfinally*/: op = _.stack.pop(), _.trys.pop(); continue;
switch (f = 1, op[0]) {
case 0: case 1: sent = op; break;
case 4: return _.label++, { value: op[1], done: false };
case 7: op = _.stack.pop(), _.trys.pop(); continue;
default:
var r = _.trys.length > 0 && _.trys[_.trys.length - 1];
if (!r && (op[0] === 1 /*throw*/ || op[0] === 6 /*catch*/ || op[0] === 2 /*return*/)) {
_.done = true;
continue;
}
if (op[0] === 3 /*break*/ && (!r || (op[1] > r[0] && op[1] < r[3]))) {
_.label = op[1];
}
else if (op[0] === 6 /*catch*/ && r && _.label < r[1]) {
_.label = r[1], sent = op;
}
else if (r && _.label < r[2]) {
_.label = r[2], _.stack.push(op);
}
else {
if (r[2]) _.stack.pop();
_.trys.pop();
continue;
}
if (!r && (op[0] === 6 || op[0] === 2)) { _.done = 1; continue; }
if (op[0] === 3 && (!r || (op[1] > r[0] && op[1] < r[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < r[1]) { _.label = r[1], sent = op; break; }
if (r && _.label < r[2]) { _.label = r[2], _.stack.push(op); break; }
if (r[2]) { _.stack.pop(); }
_.trys.pop();
continue;
}
op = body(_);
}
catch (e) { op = [6 /*catch*/, e]; }
finally { _.flag = false, sent = void 0; }
catch (e) { op = [6, e]; }
finally { f = 0, sent = void 0; }
}
}
return {
next: function (v) { return step([0 /*next*/, v]); },
"throw": function (v) { return step([1 /*throw*/, v]); },
"return": function (v) { return step([2 /*return*/, v]); }
next: function (v) { return step([0, v]); },
"throw": function (v) { return step([1, v]); },
"return": function (v) { return step([2, v]); }
};
};
function empty() {

View file

@ -0,0 +1,83 @@
//// [tests/cases/compiler/es5-importHelpersAsyncFunctions.ts] ////
//// [external.ts]
export async function foo() {
}
//// [script.ts]
async function foo() {
}
//// [tslib.d.ts]
export declare function __extends(d: Function, b: Function): void;
export declare function __assign(t: any, ...sources: any[]): any;
export declare function __decorate(decorators: Function[], target: any, key?: string | symbol, desc?: any): any;
export declare function __param(paramIndex: number, decorator: Function): Function;
export declare function __metadata(metadataKey: any, metadataValue: any): Function;
export declare function __awaiter(thisArg: any, _arguments: any, P: Function, generator: Function): any;
export declare function __generator(body: Function): any;
//// [external.js]
"use strict";
var tslib_1 = require("tslib");
function foo() {
return tslib_1.__awaiter(this, void 0, void 0, function () {
return tslib_1.__generator(function (_a) {
return [2 /*return*/];
});
});
}
exports.foo = foo;
//// [script.js]
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator.throw(value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments)).next());
});
};
var __generator = (this && this.__generator) || function (body) {
var _ = { label: 0, sent: function() { if (sent[0] === 1) throw sent[1]; return sent[1]; }, trys: [], stack: [] }, sent, f;
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (1) {
if (_.done) switch (op[0]) {
case 0: return { value: void 0, done: true };
case 1: case 6: throw op[1];
case 2: return { value: op[1], done: true };
}
try {
switch (f = 1, op[0]) {
case 0: case 1: sent = op; break;
case 4: return _.label++, { value: op[1], done: false };
case 7: op = _.stack.pop(), _.trys.pop(); continue;
default:
var r = _.trys.length > 0 && _.trys[_.trys.length - 1];
if (!r && (op[0] === 6 || op[0] === 2)) { _.done = 1; continue; }
if (op[0] === 3 && (!r || (op[1] > r[0] && op[1] < r[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < r[1]) { _.label = r[1], sent = op; break; }
if (r && _.label < r[2]) { _.label = r[2], _.stack.push(op); break; }
if (r[2]) { _.stack.pop(); }
_.trys.pop();
continue;
}
op = body(_);
}
catch (e) { op = [6, e]; }
finally { f = 0, sent = void 0; }
}
}
return {
next: function (v) { return step([0, v]); },
"throw": function (v) { return step([1, v]); },
"return": function (v) { return step([2, v]); }
};
};
function foo() {
return __awaiter(this, void 0, void 0, function () {
return __generator(function (_a) {
return [2 /*return*/];
});
});
}

View file

@ -0,0 +1,58 @@
=== tests/cases/compiler/external.ts ===
export async function foo() {
>foo : Symbol(foo, Decl(external.ts, 0, 0))
}
=== tests/cases/compiler/script.ts ===
async function foo() {
>foo : Symbol(foo, Decl(script.ts, 0, 0))
}
=== tests/cases/compiler/tslib.d.ts ===
export declare function __extends(d: Function, b: Function): void;
>__extends : Symbol(__extends, Decl(tslib.d.ts, --, --))
>d : Symbol(d, Decl(tslib.d.ts, --, --))
>Function : Symbol(Function, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
>b : Symbol(b, Decl(tslib.d.ts, --, --))
>Function : Symbol(Function, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
export declare function __assign(t: any, ...sources: any[]): any;
>__assign : Symbol(__assign, Decl(tslib.d.ts, --, --))
>t : Symbol(t, Decl(tslib.d.ts, --, --))
>sources : Symbol(sources, Decl(tslib.d.ts, --, --))
export declare function __decorate(decorators: Function[], target: any, key?: string | symbol, desc?: any): any;
>__decorate : Symbol(__decorate, Decl(tslib.d.ts, --, --))
>decorators : Symbol(decorators, Decl(tslib.d.ts, --, --))
>Function : Symbol(Function, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
>target : Symbol(target, Decl(tslib.d.ts, --, --))
>key : Symbol(key, Decl(tslib.d.ts, --, --))
>desc : Symbol(desc, Decl(tslib.d.ts, --, --))
export declare function __param(paramIndex: number, decorator: Function): Function;
>__param : Symbol(__param, Decl(tslib.d.ts, --, --))
>paramIndex : Symbol(paramIndex, Decl(tslib.d.ts, --, --))
>decorator : Symbol(decorator, Decl(tslib.d.ts, --, --))
>Function : Symbol(Function, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
>Function : Symbol(Function, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
export declare function __metadata(metadataKey: any, metadataValue: any): Function;
>__metadata : Symbol(__metadata, Decl(tslib.d.ts, --, --))
>metadataKey : Symbol(metadataKey, Decl(tslib.d.ts, --, --))
>metadataValue : Symbol(metadataValue, Decl(tslib.d.ts, --, --))
>Function : Symbol(Function, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
export declare function __awaiter(thisArg: any, _arguments: any, P: Function, generator: Function): any;
>__awaiter : Symbol(__awaiter, Decl(tslib.d.ts, --, --))
>thisArg : Symbol(thisArg, Decl(tslib.d.ts, --, --))
>_arguments : Symbol(_arguments, Decl(tslib.d.ts, --, --))
>P : Symbol(P, Decl(tslib.d.ts, --, --))
>Function : Symbol(Function, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
>generator : Symbol(generator, Decl(tslib.d.ts, --, --))
>Function : Symbol(Function, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
export declare function __generator(body: Function): any;
>__generator : Symbol(__generator, Decl(tslib.d.ts, --, --))
>body : Symbol(body, Decl(tslib.d.ts, --, --))
>Function : Symbol(Function, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))

View file

@ -0,0 +1,58 @@
=== tests/cases/compiler/external.ts ===
export async function foo() {
>foo : () => Promise<void>
}
=== tests/cases/compiler/script.ts ===
async function foo() {
>foo : () => Promise<void>
}
=== tests/cases/compiler/tslib.d.ts ===
export declare function __extends(d: Function, b: Function): void;
>__extends : (d: Function, b: Function) => void
>d : Function
>Function : Function
>b : Function
>Function : Function
export declare function __assign(t: any, ...sources: any[]): any;
>__assign : (t: any, ...sources: any[]) => any
>t : any
>sources : any[]
export declare function __decorate(decorators: Function[], target: any, key?: string | symbol, desc?: any): any;
>__decorate : (decorators: Function[], target: any, key?: string | symbol, desc?: any) => any
>decorators : Function[]
>Function : Function
>target : any
>key : string | symbol
>desc : any
export declare function __param(paramIndex: number, decorator: Function): Function;
>__param : (paramIndex: number, decorator: Function) => Function
>paramIndex : number
>decorator : Function
>Function : Function
>Function : Function
export declare function __metadata(metadataKey: any, metadataValue: any): Function;
>__metadata : (metadataKey: any, metadataValue: any) => Function
>metadataKey : any
>metadataValue : any
>Function : Function
export declare function __awaiter(thisArg: any, _arguments: any, P: Function, generator: Function): any;
>__awaiter : (thisArg: any, _arguments: any, P: Function, generator: Function) => any
>thisArg : any
>_arguments : any
>P : Function
>Function : Function
>generator : Function
>Function : Function
export declare function __generator(body: Function): any;
>__generator : (body: Function) => any
>body : Function
>Function : Function

View file

@ -1,5 +0,0 @@
// @target: es5
async function foo() { return 42; } // ERROR: Async functions are only available in ES6+
let bar = async function () { return 42; } // OK, but should be an error
let baz = async () => 42; // OK, but should be an error

View file

@ -0,0 +1,21 @@
// @lib: es5,es2015.promise
// @importHelpers: true
// @target: es5
// @module: commonjs
// @moduleResolution: classic
// @filename: external.ts
export async function foo() {
}
// @filename: script.ts
async function foo() {
}
// @filename: tslib.d.ts
export declare function __extends(d: Function, b: Function): void;
export declare function __assign(t: any, ...sources: any[]): any;
export declare function __decorate(decorators: Function[], target: any, key?: string | symbol, desc?: any): any;
export declare function __param(paramIndex: number, decorator: Function): Function;
export declare function __metadata(metadataKey: any, metadataValue: any): Function;
export declare function __awaiter(thisArg: any, _arguments: any, P: Function, generator: Function): any;
export declare function __generator(body: Function): any;