Merge pull request #13272 from Microsoft/externalExportStar

Support for an external exportStar helper
This commit is contained in:
Ron Buckton
2017-06-07 13:59:54 -07:00
committed by GitHub
19 changed files with 177 additions and 46 deletions
+6 -1
View File
@@ -21865,6 +21865,10 @@ namespace ts {
if (moduleSymbol && hasExportAssignmentSymbol(moduleSymbol)) {
error(node.moduleSpecifier, Diagnostics.Module_0_uses_export_and_cannot_be_used_with_export_Asterisk, symbolToString(moduleSymbol));
}
if (modulekind !== ModuleKind.System && modulekind !== ModuleKind.ES2015) {
checkExternalEmitHelpers(node, ExternalEmitHelpers.ExportStar);
}
}
}
}
@@ -23539,7 +23543,8 @@ namespace ts {
case ExternalEmitHelpers.AsyncGenerator: return "__asyncGenerator";
case ExternalEmitHelpers.AsyncDelegator: return "__asyncDelegator";
case ExternalEmitHelpers.AsyncValues: return "__asyncValues";
default: Debug.fail("Unrecognized helper.");
case ExternalEmitHelpers.ExportStar: return "__exportStar";
default: Debug.fail("Unrecognized helper");
}
}
+31 -20
View File
@@ -3850,23 +3850,34 @@ namespace ts {
return emitNode && emitNode.externalHelpersModuleName;
}
export function getOrCreateExternalHelpersModuleNameIfNeeded(node: SourceFile, compilerOptions: CompilerOptions) {
if (compilerOptions.importHelpers && (isExternalModule(node) || compilerOptions.isolatedModules)) {
export function getOrCreateExternalHelpersModuleNameIfNeeded(node: SourceFile, compilerOptions: CompilerOptions, hasExportStarsToExportValues?: boolean) {
if (compilerOptions.importHelpers && isEffectiveExternalModule(node, compilerOptions)) {
const externalHelpersModuleName = getExternalHelpersModuleName(node);
if (externalHelpersModuleName) {
return externalHelpersModuleName;
}
const helpers = getEmitHelpers(node);
if (helpers) {
for (const helper of helpers) {
if (!helper.scoped) {
const parseNode = getOriginalNode(node, isSourceFile);
const emitNode = getOrCreateEmitNode(parseNode);
return emitNode.externalHelpersModuleName || (emitNode.externalHelpersModuleName = createUniqueName(externalHelpersModuleNameText));
const moduleKind = getEmitModuleKind(compilerOptions);
let create = hasExportStarsToExportValues
&& moduleKind !== ModuleKind.System
&& moduleKind !== ModuleKind.ES2015;
if (!create) {
const helpers = getEmitHelpers(node);
if (helpers) {
for (const helper of helpers) {
if (!helper.scoped) {
create = true;
break;
}
}
}
}
if (create) {
const parseNode = getOriginalNode(node, isSourceFile);
const emitNode = getOrCreateEmitNode(parseNode);
return emitNode.externalHelpersModuleName || (emitNode.externalHelpersModuleName = createUniqueName(externalHelpersModuleNameText));
}
}
}
@@ -4249,17 +4260,6 @@ namespace ts {
let exportEquals: ExportAssignment = undefined;
let hasExportStarsToExportValues = false;
const externalHelpersModuleName = getOrCreateExternalHelpersModuleNameIfNeeded(sourceFile, compilerOptions);
const externalHelpersImportDeclaration = externalHelpersModuleName && createImportDeclaration(
/*decorators*/ undefined,
/*modifiers*/ undefined,
createImportClause(/*name*/ undefined, createNamespaceImport(externalHelpersModuleName)),
createLiteral(externalHelpersModuleNameText));
if (externalHelpersImportDeclaration) {
externalImports.push(externalHelpersImportDeclaration);
}
for (const node of sourceFile.statements) {
switch (node.kind) {
case SyntaxKind.ImportDeclaration:
@@ -4370,6 +4370,17 @@ namespace ts {
}
}
const externalHelpersModuleName = getOrCreateExternalHelpersModuleNameIfNeeded(sourceFile, compilerOptions, hasExportStarsToExportValues);
const externalHelpersImportDeclaration = externalHelpersModuleName && createImportDeclaration(
/*decorators*/ undefined,
/*modifiers*/ undefined,
createImportClause(/*name*/ undefined, createNamespaceImport(externalHelpersModuleName)),
createLiteral(externalHelpersModuleNameText));
if (externalHelpersImportDeclaration) {
externalImports.unshift(externalHelpersImportDeclaration);
}
return { externalImports, exportSpecifiers, exportEquals, hasExportStarsToExportValues, exportedBindings, exportedNames, externalHelpersImportDeclaration };
}
+12 -12
View File
@@ -103,7 +103,7 @@ namespace ts {
addRange(statements, endLexicalEnvironment());
const updated = updateSourceFileNode(node, setTextRange(createNodeArray(statements), node.statements));
if (currentModuleInfo.hasExportStarsToExportValues) {
if (currentModuleInfo.hasExportStarsToExportValues && !compilerOptions.importHelpers) {
// If we have any `export * from ...` declarations
// we need to inform the emitter to add the __export helper.
addEmitHelper(updated, exportStarHelper);
@@ -408,7 +408,7 @@ namespace ts {
addRange(statements, endLexicalEnvironment());
const body = createBlock(statements, /*multiLine*/ true);
if (currentModuleInfo.hasExportStarsToExportValues) {
if (currentModuleInfo.hasExportStarsToExportValues && !compilerOptions.importHelpers) {
// If we have any `export * from ...` declarations
// we need to inform the emitter to add the __export helper.
addEmitHelper(body, exportStarHelper);
@@ -833,15 +833,7 @@ namespace ts {
// export * from "mod";
return setTextRange(
createStatement(
createCall(
createIdentifier("__export"),
/*typeArguments*/ undefined,
[
moduleKind !== ModuleKind.AMD
? createRequireCall(node)
: generatedName
]
)
createExportStarHelper(context, moduleKind !== ModuleKind.AMD ? createRequireCall(node) : generatedName)
),
node
);
@@ -1598,9 +1590,17 @@ namespace ts {
text: `
function __export(m) {
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
}`
}
`
};
function createExportStarHelper(context: TransformationContext, module: Expression) {
const compilerOptions = context.getCompilerOptions();
return compilerOptions.importHelpers
? createCall(getHelperName("__exportStar"), /*typeArguments*/ undefined, [module, createIdentifier("exports")])
: createCall(createIdentifier("__export"), /*typeArguments*/ undefined, [module]);
}
// emit helper for dynamic import
const dynamicImportUMDHelper: EmitHelper = {
name: "typescript:dynamicimport-sync-require",
+2 -1
View File
@@ -4097,6 +4097,7 @@ namespace ts {
AsyncGenerator = 1 << 12, // __asyncGenerator (used by ES2017 async generator transformation)
AsyncDelegator = 1 << 13, // __asyncDelegator (used by ES2017 async generator yield* transformation)
AsyncValues = 1 << 14, // __asyncValues (used by ES2017 for..await..of transformation)
ExportStar = 1 << 15, // __exportStar (used by CommonJS/AMD/UMD module transformation)
// Helpers included by ES2015 for..of
ForOfIncludes = Values,
@@ -4114,7 +4115,7 @@ namespace ts {
SpreadIncludes = Read | Spread,
FirstEmitHelper = Extends,
LastEmitHelper = AsyncValues
LastEmitHelper = ExportStar
}
export const enum EmitHint {
@@ -5,16 +5,19 @@ export class A { }
//// [b.ts]
import { A } from "./a";
export * from "./a";
export class B extends A { }
//// [tslib.d.ts]
export declare function __extends(d: Function, b: Function): void;
export declare function __assign(t: any, ...sources: any[]): any;
export declare function __rest(t: any, propertyNames: string[]): 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(thisArg: any, body: Function): any;
export declare function __exportStar(m: any, exports: any): void;
//// [a.js]
define(["require", "exports"], function (require, exports) {
@@ -28,9 +31,10 @@ define(["require", "exports"], function (require, exports) {
exports.A = A;
});
//// [b.js]
define(["require", "exports", "tslib", "./a"], function (require, exports, tslib_1, a_1) {
define(["require", "exports", "tslib", "./a", "./a"], function (require, exports, tslib_1, a_1, a_2) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
tslib_1.__exportStar(a_2, exports);
var B = (function (_super) {
tslib_1.__extends(B, _super);
function B() {
@@ -6,8 +6,9 @@ export class A { }
import { A } from "./a";
>A : Symbol(A, Decl(b.ts, 0, 8))
export * from "./a";
export class B extends A { }
>B : Symbol(B, Decl(b.ts, 0, 24))
>B : Symbol(B, Decl(b.ts, 1, 20))
>A : Symbol(A, Decl(b.ts, 0, 8))
=== tests/cases/compiler/tslib.d.ts ===
@@ -23,6 +24,11 @@ export declare function __assign(t: any, ...sources: any[]): any;
>t : Symbol(t, Decl(tslib.d.ts, --, --))
>sources : Symbol(sources, Decl(tslib.d.ts, --, --))
export declare function __rest(t: any, propertyNames: string[]): any;
>__rest : Symbol(__rest, Decl(tslib.d.ts, --, --))
>t : Symbol(t, Decl(tslib.d.ts, --, --))
>propertyNames : Symbol(propertyNames, 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, --, --))
@@ -53,3 +59,14 @@ export declare function __awaiter(thisArg: any, _arguments: any, P: Function, ge
>generator : Symbol(generator, Decl(tslib.d.ts, --, --))
>Function : Symbol(Function, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
export declare function __generator(thisArg: any, body: Function): any;
>__generator : Symbol(__generator, Decl(tslib.d.ts, --, --))
>thisArg : Symbol(thisArg, Decl(tslib.d.ts, --, --))
>body : Symbol(body, Decl(tslib.d.ts, --, --))
>Function : Symbol(Function, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
export declare function __exportStar(m: any, exports: any): void;
>__exportStar : Symbol(__exportStar, Decl(tslib.d.ts, --, --))
>m : Symbol(m, Decl(tslib.d.ts, --, --))
>exports : Symbol(exports, Decl(tslib.d.ts, --, --))
@@ -6,6 +6,7 @@ export class A { }
import { A } from "./a";
>A : typeof A
export * from "./a";
export class B extends A { }
>B : B
>A : A
@@ -23,6 +24,11 @@ export declare function __assign(t: any, ...sources: any[]): any;
>t : any
>sources : any[]
export declare function __rest(t: any, propertyNames: string[]): any;
>__rest : (t: any, propertyNames: string[]) => any
>t : any
>propertyNames : string[]
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[]
@@ -53,3 +59,14 @@ export declare function __awaiter(thisArg: any, _arguments: any, P: Function, ge
>generator : Function
>Function : Function
export declare function __generator(thisArg: any, body: Function): any;
>__generator : (thisArg: any, body: Function) => any
>thisArg : any
>body : Function
>Function : Function
export declare function __exportStar(m: any, exports: any): void;
>__exportStar : (m: any, exports: any) => void
>m : any
>exports : any
@@ -48,11 +48,13 @@ declare namespace N {
//// [tslib.d.ts]
export declare function __extends(d: Function, b: Function): void;
export declare function __assign(t: any, ...sources: any[]): any;
export declare function __rest(t: any, propertyNames: string[]): 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(thisArg: any, body: Function): any;
export declare function __exportStar(m: any, exports: any): void;
//// [b.js]
"use strict";
@@ -98,6 +98,11 @@ export declare function __assign(t: any, ...sources: any[]): any;
>t : Symbol(t, Decl(tslib.d.ts, --, --))
>sources : Symbol(sources, Decl(tslib.d.ts, --, --))
export declare function __rest(t: any, propertyNames: string[]): any;
>__rest : Symbol(__rest, Decl(tslib.d.ts, --, --))
>t : Symbol(t, Decl(tslib.d.ts, --, --))
>propertyNames : Symbol(propertyNames, 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, --, --))
@@ -128,3 +133,14 @@ export declare function __awaiter(thisArg: any, _arguments: any, P: Function, ge
>generator : Symbol(generator, Decl(tslib.d.ts, --, --))
>Function : Symbol(Function, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
export declare function __generator(thisArg: any, body: Function): any;
>__generator : Symbol(__generator, Decl(tslib.d.ts, --, --))
>thisArg : Symbol(thisArg, Decl(tslib.d.ts, --, --))
>body : Symbol(body, Decl(tslib.d.ts, --, --))
>Function : Symbol(Function, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
export declare function __exportStar(m: any, exports: any): void;
>__exportStar : Symbol(__exportStar, Decl(tslib.d.ts, --, --))
>m : Symbol(m, Decl(tslib.d.ts, --, --))
>exports : Symbol(exports, Decl(tslib.d.ts, --, --))
@@ -98,6 +98,11 @@ export declare function __assign(t: any, ...sources: any[]): any;
>t : any
>sources : any[]
export declare function __rest(t: any, propertyNames: string[]): any;
>__rest : (t: any, propertyNames: string[]) => any
>t : any
>propertyNames : string[]
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[]
@@ -128,3 +133,14 @@ export declare function __awaiter(thisArg: any, _arguments: any, P: Function, ge
>generator : Function
>Function : Function
export declare function __generator(thisArg: any, body: Function): any;
>__generator : (thisArg: any, body: Function) => any
>thisArg : any
>body : Function
>Function : Function
export declare function __exportStar(m: any, exports: any): void;
>__exportStar : (m: any, exports: any) => void
>m : any
>exports : any
@@ -1,12 +1,16 @@
tests/cases/compiler/external.ts(2,16): error TS2343: This syntax requires an imported helper named '__extends', but module 'tslib' has no exported member '__extends'.
tests/cases/compiler/external.ts(6,1): error TS2343: This syntax requires an imported helper named '__decorate', but module 'tslib' has no exported member '__decorate'.
tests/cases/compiler/external.ts(6,1): error TS2343: This syntax requires an imported helper named '__metadata', but module 'tslib' has no exported member '__metadata'.
tests/cases/compiler/external.ts(8,12): error TS2343: This syntax requires an imported helper named '__param', but module 'tslib' has no exported member '__param'.
tests/cases/compiler/external.ts(13,13): error TS2343: This syntax requires an imported helper named '__assign', but module 'tslib' has no exported member '__assign'.
tests/cases/compiler/external.ts(14,12): error TS2343: This syntax requires an imported helper named '__rest', but module 'tslib' has no exported member '__rest'.
tests/cases/compiler/external.ts(1,1): error TS2343: This syntax requires an imported helper named '__exportStar', but module 'tslib' has no exported member '__exportStar'.
tests/cases/compiler/external.ts(3,16): error TS2343: This syntax requires an imported helper named '__extends', but module 'tslib' has no exported member '__extends'.
tests/cases/compiler/external.ts(7,1): error TS2343: This syntax requires an imported helper named '__decorate', but module 'tslib' has no exported member '__decorate'.
tests/cases/compiler/external.ts(7,1): error TS2343: This syntax requires an imported helper named '__metadata', but module 'tslib' has no exported member '__metadata'.
tests/cases/compiler/external.ts(9,12): error TS2343: This syntax requires an imported helper named '__param', but module 'tslib' has no exported member '__param'.
tests/cases/compiler/external.ts(14,13): error TS2343: This syntax requires an imported helper named '__assign', but module 'tslib' has no exported member '__assign'.
tests/cases/compiler/external.ts(15,12): error TS2343: This syntax requires an imported helper named '__rest', but module 'tslib' has no exported member '__rest'.
==== tests/cases/compiler/external.ts (6 errors) ====
==== tests/cases/compiler/external.ts (7 errors) ====
export * from "./other";
~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2343: This syntax requires an imported helper named '__exportStar', but module 'tslib' has no exported member '__exportStar'.
export class A { }
export class B extends A { }
~~~~~~~~~
@@ -34,6 +38,9 @@ tests/cases/compiler/external.ts(14,12): error TS2343: This syntax requires an i
~
!!! error TS2343: This syntax requires an imported helper named '__rest', but module 'tslib' has no exported member '__rest'.
==== tests/cases/compiler/other.ts (0 errors) ====
export const x = 1;
==== tests/cases/compiler/script.ts (0 errors) ====
class A { }
class B extends A { }
@@ -1,6 +1,7 @@
//// [tests/cases/compiler/importHelpersNoHelpers.ts] ////
//// [external.ts]
export * from "./other";
export class A { }
export class B extends A { }
@@ -16,6 +17,9 @@ const o = { a: 1 };
const y = { ...o };
const { ...x } = y;
//// [other.ts]
export const x = 1;
//// [script.ts]
class A { }
class B extends A { }
@@ -32,10 +36,15 @@ class C {
export {}
//// [other.js]
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.x = 1;
//// [external.js]
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
tslib_1.__exportStar(require("./other"), exports);
var A = (function () {
function A() {
}
@@ -5,6 +5,7 @@ export class A { }
//// [b.ts]
import { A } from "./a";
export * from "./a";
export class B extends A { }
//// [tslib.d.ts]
@@ -38,6 +39,16 @@ System.register(["tslib", "./a"], function (exports_1, context_1) {
"use strict";
var __moduleName = context_1 && context_1.id;
var tslib_1, a_1, B;
var exportedNames_1 = {
"B": true
};
function exportStar_1(m) {
var exports = {};
for (var n in m) {
if (n !== "default" && !exportedNames_1.hasOwnProperty(n)) exports[n] = m[n];
}
exports_1(exports);
}
return {
setters: [
function (tslib_1_1) {
@@ -45,6 +56,7 @@ System.register(["tslib", "./a"], function (exports_1, context_1) {
},
function (a_1_1) {
a_1 = a_1_1;
exportStar_1(a_1_1);
}
],
execute: function () {
@@ -6,8 +6,9 @@ export class A { }
import { A } from "./a";
>A : Symbol(A, Decl(b.ts, 0, 8))
export * from "./a";
export class B extends A { }
>B : Symbol(B, Decl(b.ts, 0, 24))
>B : Symbol(B, Decl(b.ts, 1, 20))
>A : Symbol(A, Decl(b.ts, 0, 8))
=== tests/cases/compiler/tslib.d.ts ===
@@ -6,6 +6,7 @@ export class A { }
import { A } from "./a";
>A : typeof A
export * from "./a";
export class B extends A { }
>B : B
>A : A
+4
View File
@@ -6,12 +6,16 @@ export class A { }
// @filename: b.ts
import { A } from "./a";
export * from "./a";
export class B extends A { }
// @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 __rest(t: any, propertyNames: string[]): 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(thisArg: any, body: Function): any;
export declare function __exportStar(m: any, exports: any): void;
@@ -49,7 +49,10 @@ declare namespace N {
// @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 __rest(t: any, propertyNames: string[]): 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(thisArg: any, body: Function): any;
export declare function __exportStar(m: any, exports: any): void;
@@ -5,6 +5,7 @@
// @experimentalDecorators: true
// @emitDecoratorMetadata: true
// @filename: external.ts
export * from "./other";
export class A { }
export class B extends A { }
@@ -20,6 +21,9 @@ const o = { a: 1 };
const y = { ...o };
const { ...x } = y;
// @filename: other.ts
export const x = 1;
// @filename: script.ts
class A { }
class B extends A { }
@@ -6,6 +6,7 @@ export class A { }
// @filename: b.ts
import { A } from "./a";
export * from "./a";
export class B extends A { }
// @filename: tslib.d.ts