Support for an external exportStar helper

This commit is contained in:
Ron Buckton 2016-12-31 19:12:57 -08:00
parent 88c68256e6
commit 5999a521f6
19 changed files with 178 additions and 46 deletions

View file

@ -19160,6 +19160,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);
}
}
}
}
@ -20788,7 +20792,7 @@ namespace ts {
function checkExternalEmitHelpers(location: Node, helpers: ExternalEmitHelpers) {
if ((requestedExternalEmitHelpers & helpers) !== helpers && compilerOptions.importHelpers) {
const sourceFile = getSourceFileOfNode(location);
if (isEffectiveExternalModule(sourceFile, compilerOptions)) {
if (!isDeclarationFile(sourceFile) && isEffectiveExternalModule(sourceFile, compilerOptions)) {
const helpersModule = resolveHelpersModule(sourceFile, location);
if (helpersModule !== unknownSymbol) {
const uncheckedHelpers = helpers & ~requestedExternalEmitHelpers;
@ -20817,6 +20821,8 @@ namespace ts {
case ExternalEmitHelpers.Param: return "__param";
case ExternalEmitHelpers.Awaiter: return "__awaiter";
case ExternalEmitHelpers.Generator: return "__generator";
case ExternalEmitHelpers.ExportStar: return "__exportStar";
default: Debug.fail("Unrecognized helper");
}
}

View file

@ -2808,25 +2808,37 @@ 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));
}
}
}
/**
* Adds an EmitHelper to a node.
*/
@ -3293,17 +3305,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:
@ -3414,6 +3415,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 };
}

View file

@ -87,7 +87,7 @@ namespace ts {
addExportEqualsIfNeeded(statements, /*emitAsReturn*/ false);
const updated = updateSourceFileNode(node, createNodeArray(statements, node.statements));
if (currentModuleInfo.hasExportStarsToExportValues) {
if (currentModuleInfo.hasExportStarsToExportValues && !compilerOptions.importHelpers) {
addEmitHelper(updated, exportStarHelper);
}
@ -377,7 +377,7 @@ namespace ts {
addExportEqualsIfNeeded(statements, /*emitAsReturn*/ true);
const body = createBlock(statements, /*location*/ undefined, /*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);
@ -691,15 +691,7 @@ namespace ts {
else {
// export * from "mod";
return createStatement(
createCall(
createIdentifier("__export"),
/*typeArguments*/ undefined,
[
moduleKind !== ModuleKind.AMD
? createRequireCall(node)
: generatedName
]
),
createExportStarHelper(context, moduleKind !== ModuleKind.AMD ? createRequireCall(node) : generatedName),
/*location*/ node
);
}
@ -1441,6 +1433,14 @@ 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]);
}
}

View file

@ -3733,9 +3733,10 @@ namespace ts {
Param = 1 << 5, // __param (used by TypeScript decorators transformation)
Awaiter = 1 << 6, // __awaiter (used by ES2017 async functions transformation)
Generator = 1 << 7, // __generator (used by ES2015 generator transformation)
ExportStar = 1 << 8, // __exportStar (used by CommonJS/AMD/UMD module transformation)
FirstEmitHelper = Extends,
LastEmitHelper = Generator
LastEmitHelper = ExportStar
}
/* @internal */

View file

@ -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) {
@ -27,8 +30,9 @@ 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";
tslib_1.__exportStar(a_2, exports);
var B = (function (_super) {
tslib_1.__extends(B, _super);
function B() {

View file

@ -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, --, --))

View file

@ -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

View file

@ -49,11 +49,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";

View file

@ -99,6 +99,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, --, --))
@ -129,3 +134,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, --, --))

View file

@ -99,6 +99,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[]
@ -129,3 +134,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

View file

@ -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 { }

View file

@ -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,9 +36,13 @@ class C {
export {}
//// [other.js]
"use strict";
exports.x = 1;
//// [external.js]
"use strict";
var tslib_1 = require("tslib");
tslib_1.__exportStar(require("./other"), exports);
var A = (function () {
function A() {
}

View file

@ -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 () {

View file

@ -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 ===

View file

@ -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

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;

View file

@ -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;

View file

@ -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 { }

View file

@ -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