Skip to content

Commit d450b8b

Browse files
authored
Merge pull request #13272 from Microsoft/externalExportStar
Support for an external exportStar helper
2 parents abb9681 + 9250d0a commit d450b8b

19 files changed

+177
-46
lines changed

src/compiler/checker.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21865,6 +21865,10 @@ namespace ts {
2186521865
if (moduleSymbol && hasExportAssignmentSymbol(moduleSymbol)) {
2186621866
error(node.moduleSpecifier, Diagnostics.Module_0_uses_export_and_cannot_be_used_with_export_Asterisk, symbolToString(moduleSymbol));
2186721867
}
21868+
21869+
if (modulekind !== ModuleKind.System && modulekind !== ModuleKind.ES2015) {
21870+
checkExternalEmitHelpers(node, ExternalEmitHelpers.ExportStar);
21871+
}
2186821872
}
2186921873
}
2187021874
}
@@ -23539,7 +23543,8 @@ namespace ts {
2353923543
case ExternalEmitHelpers.AsyncGenerator: return "__asyncGenerator";
2354023544
case ExternalEmitHelpers.AsyncDelegator: return "__asyncDelegator";
2354123545
case ExternalEmitHelpers.AsyncValues: return "__asyncValues";
23542-
default: Debug.fail("Unrecognized helper.");
23546+
case ExternalEmitHelpers.ExportStar: return "__exportStar";
23547+
default: Debug.fail("Unrecognized helper");
2354323548
}
2354423549
}
2354523550

src/compiler/factory.ts

Lines changed: 31 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3850,23 +3850,34 @@ namespace ts {
38503850
return emitNode && emitNode.externalHelpersModuleName;
38513851
}
38523852

3853-
export function getOrCreateExternalHelpersModuleNameIfNeeded(node: SourceFile, compilerOptions: CompilerOptions) {
3854-
if (compilerOptions.importHelpers && (isExternalModule(node) || compilerOptions.isolatedModules)) {
3853+
export function getOrCreateExternalHelpersModuleNameIfNeeded(node: SourceFile, compilerOptions: CompilerOptions, hasExportStarsToExportValues?: boolean) {
3854+
if (compilerOptions.importHelpers && isEffectiveExternalModule(node, compilerOptions)) {
38553855
const externalHelpersModuleName = getExternalHelpersModuleName(node);
38563856
if (externalHelpersModuleName) {
38573857
return externalHelpersModuleName;
38583858
}
38593859

3860-
const helpers = getEmitHelpers(node);
3861-
if (helpers) {
3862-
for (const helper of helpers) {
3863-
if (!helper.scoped) {
3864-
const parseNode = getOriginalNode(node, isSourceFile);
3865-
const emitNode = getOrCreateEmitNode(parseNode);
3866-
return emitNode.externalHelpersModuleName || (emitNode.externalHelpersModuleName = createUniqueName(externalHelpersModuleNameText));
3860+
const moduleKind = getEmitModuleKind(compilerOptions);
3861+
let create = hasExportStarsToExportValues
3862+
&& moduleKind !== ModuleKind.System
3863+
&& moduleKind !== ModuleKind.ES2015;
3864+
if (!create) {
3865+
const helpers = getEmitHelpers(node);
3866+
if (helpers) {
3867+
for (const helper of helpers) {
3868+
if (!helper.scoped) {
3869+
create = true;
3870+
break;
3871+
}
38673872
}
38683873
}
38693874
}
3875+
3876+
if (create) {
3877+
const parseNode = getOriginalNode(node, isSourceFile);
3878+
const emitNode = getOrCreateEmitNode(parseNode);
3879+
return emitNode.externalHelpersModuleName || (emitNode.externalHelpersModuleName = createUniqueName(externalHelpersModuleNameText));
3880+
}
38703881
}
38713882
}
38723883

@@ -4249,17 +4260,6 @@ namespace ts {
42494260
let exportEquals: ExportAssignment = undefined;
42504261
let hasExportStarsToExportValues = false;
42514262

4252-
const externalHelpersModuleName = getOrCreateExternalHelpersModuleNameIfNeeded(sourceFile, compilerOptions);
4253-
const externalHelpersImportDeclaration = externalHelpersModuleName && createImportDeclaration(
4254-
/*decorators*/ undefined,
4255-
/*modifiers*/ undefined,
4256-
createImportClause(/*name*/ undefined, createNamespaceImport(externalHelpersModuleName)),
4257-
createLiteral(externalHelpersModuleNameText));
4258-
4259-
if (externalHelpersImportDeclaration) {
4260-
externalImports.push(externalHelpersImportDeclaration);
4261-
}
4262-
42634263
for (const node of sourceFile.statements) {
42644264
switch (node.kind) {
42654265
case SyntaxKind.ImportDeclaration:
@@ -4370,6 +4370,17 @@ namespace ts {
43704370
}
43714371
}
43724372

4373+
const externalHelpersModuleName = getOrCreateExternalHelpersModuleNameIfNeeded(sourceFile, compilerOptions, hasExportStarsToExportValues);
4374+
const externalHelpersImportDeclaration = externalHelpersModuleName && createImportDeclaration(
4375+
/*decorators*/ undefined,
4376+
/*modifiers*/ undefined,
4377+
createImportClause(/*name*/ undefined, createNamespaceImport(externalHelpersModuleName)),
4378+
createLiteral(externalHelpersModuleNameText));
4379+
4380+
if (externalHelpersImportDeclaration) {
4381+
externalImports.unshift(externalHelpersImportDeclaration);
4382+
}
4383+
43734384
return { externalImports, exportSpecifiers, exportEquals, hasExportStarsToExportValues, exportedBindings, exportedNames, externalHelpersImportDeclaration };
43744385
}
43754386

src/compiler/transformers/module/module.ts

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ namespace ts {
103103
addRange(statements, endLexicalEnvironment());
104104

105105
const updated = updateSourceFileNode(node, setTextRange(createNodeArray(statements), node.statements));
106-
if (currentModuleInfo.hasExportStarsToExportValues) {
106+
if (currentModuleInfo.hasExportStarsToExportValues && !compilerOptions.importHelpers) {
107107
// If we have any `export * from ...` declarations
108108
// we need to inform the emitter to add the __export helper.
109109
addEmitHelper(updated, exportStarHelper);
@@ -408,7 +408,7 @@ namespace ts {
408408
addRange(statements, endLexicalEnvironment());
409409

410410
const body = createBlock(statements, /*multiLine*/ true);
411-
if (currentModuleInfo.hasExportStarsToExportValues) {
411+
if (currentModuleInfo.hasExportStarsToExportValues && !compilerOptions.importHelpers) {
412412
// If we have any `export * from ...` declarations
413413
// we need to inform the emitter to add the __export helper.
414414
addEmitHelper(body, exportStarHelper);
@@ -833,15 +833,7 @@ namespace ts {
833833
// export * from "mod";
834834
return setTextRange(
835835
createStatement(
836-
createCall(
837-
createIdentifier("__export"),
838-
/*typeArguments*/ undefined,
839-
[
840-
moduleKind !== ModuleKind.AMD
841-
? createRequireCall(node)
842-
: generatedName
843-
]
844-
)
836+
createExportStarHelper(context, moduleKind !== ModuleKind.AMD ? createRequireCall(node) : generatedName)
845837
),
846838
node
847839
);
@@ -1598,9 +1590,17 @@ namespace ts {
15981590
text: `
15991591
function __export(m) {
16001592
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
1601-
}`
1593+
}
1594+
`
16021595
};
16031596

1597+
function createExportStarHelper(context: TransformationContext, module: Expression) {
1598+
const compilerOptions = context.getCompilerOptions();
1599+
return compilerOptions.importHelpers
1600+
? createCall(getHelperName("__exportStar"), /*typeArguments*/ undefined, [module, createIdentifier("exports")])
1601+
: createCall(createIdentifier("__export"), /*typeArguments*/ undefined, [module]);
1602+
}
1603+
16041604
// emit helper for dynamic import
16051605
const dynamicImportUMDHelper: EmitHelper = {
16061606
name: "typescript:dynamicimport-sync-require",

src/compiler/types.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4097,6 +4097,7 @@ namespace ts {
40974097
AsyncGenerator = 1 << 12, // __asyncGenerator (used by ES2017 async generator transformation)
40984098
AsyncDelegator = 1 << 13, // __asyncDelegator (used by ES2017 async generator yield* transformation)
40994099
AsyncValues = 1 << 14, // __asyncValues (used by ES2017 for..await..of transformation)
4100+
ExportStar = 1 << 15, // __exportStar (used by CommonJS/AMD/UMD module transformation)
41004101

41014102
// Helpers included by ES2015 for..of
41024103
ForOfIncludes = Values,
@@ -4114,7 +4115,7 @@ namespace ts {
41144115
SpreadIncludes = Read | Spread,
41154116

41164117
FirstEmitHelper = Extends,
4117-
LastEmitHelper = AsyncValues
4118+
LastEmitHelper = ExportStar
41184119
}
41194120

41204121
export const enum EmitHint {

tests/baselines/reference/importHelpersAmd.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,19 @@ export class A { }
55

66
//// [b.ts]
77
import { A } from "./a";
8+
export * from "./a";
89
export class B extends A { }
910

1011
//// [tslib.d.ts]
1112
export declare function __extends(d: Function, b: Function): void;
1213
export declare function __assign(t: any, ...sources: any[]): any;
14+
export declare function __rest(t: any, propertyNames: string[]): any;
1315
export declare function __decorate(decorators: Function[], target: any, key?: string | symbol, desc?: any): any;
1416
export declare function __param(paramIndex: number, decorator: Function): Function;
1517
export declare function __metadata(metadataKey: any, metadataValue: any): Function;
1618
export declare function __awaiter(thisArg: any, _arguments: any, P: Function, generator: Function): any;
17-
19+
export declare function __generator(thisArg: any, body: Function): any;
20+
export declare function __exportStar(m: any, exports: any): void;
1821

1922
//// [a.js]
2023
define(["require", "exports"], function (require, exports) {
@@ -28,9 +31,10 @@ define(["require", "exports"], function (require, exports) {
2831
exports.A = A;
2932
});
3033
//// [b.js]
31-
define(["require", "exports", "tslib", "./a"], function (require, exports, tslib_1, a_1) {
34+
define(["require", "exports", "tslib", "./a", "./a"], function (require, exports, tslib_1, a_1, a_2) {
3235
"use strict";
3336
Object.defineProperty(exports, "__esModule", { value: true });
37+
tslib_1.__exportStar(a_2, exports);
3438
var B = (function (_super) {
3539
tslib_1.__extends(B, _super);
3640
function B() {

tests/baselines/reference/importHelpersAmd.symbols

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@ export class A { }
66
import { A } from "./a";
77
>A : Symbol(A, Decl(b.ts, 0, 8))
88

9+
export * from "./a";
910
export class B extends A { }
10-
>B : Symbol(B, Decl(b.ts, 0, 24))
11+
>B : Symbol(B, Decl(b.ts, 1, 20))
1112
>A : Symbol(A, Decl(b.ts, 0, 8))
1213

1314
=== tests/cases/compiler/tslib.d.ts ===
@@ -23,6 +24,11 @@ export declare function __assign(t: any, ...sources: any[]): any;
2324
>t : Symbol(t, Decl(tslib.d.ts, --, --))
2425
>sources : Symbol(sources, Decl(tslib.d.ts, --, --))
2526

27+
export declare function __rest(t: any, propertyNames: string[]): any;
28+
>__rest : Symbol(__rest, Decl(tslib.d.ts, --, --))
29+
>t : Symbol(t, Decl(tslib.d.ts, --, --))
30+
>propertyNames : Symbol(propertyNames, Decl(tslib.d.ts, --, --))
31+
2632
export declare function __decorate(decorators: Function[], target: any, key?: string | symbol, desc?: any): any;
2733
>__decorate : Symbol(__decorate, Decl(tslib.d.ts, --, --))
2834
>decorators : Symbol(decorators, Decl(tslib.d.ts, --, --))
@@ -53,3 +59,14 @@ export declare function __awaiter(thisArg: any, _arguments: any, P: Function, ge
5359
>generator : Symbol(generator, Decl(tslib.d.ts, --, --))
5460
>Function : Symbol(Function, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
5561

62+
export declare function __generator(thisArg: any, body: Function): any;
63+
>__generator : Symbol(__generator, Decl(tslib.d.ts, --, --))
64+
>thisArg : Symbol(thisArg, Decl(tslib.d.ts, --, --))
65+
>body : Symbol(body, Decl(tslib.d.ts, --, --))
66+
>Function : Symbol(Function, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
67+
68+
export declare function __exportStar(m: any, exports: any): void;
69+
>__exportStar : Symbol(__exportStar, Decl(tslib.d.ts, --, --))
70+
>m : Symbol(m, Decl(tslib.d.ts, --, --))
71+
>exports : Symbol(exports, Decl(tslib.d.ts, --, --))
72+

tests/baselines/reference/importHelpersAmd.types

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ export class A { }
66
import { A } from "./a";
77
>A : typeof A
88

9+
export * from "./a";
910
export class B extends A { }
1011
>B : B
1112
>A : A
@@ -23,6 +24,11 @@ export declare function __assign(t: any, ...sources: any[]): any;
2324
>t : any
2425
>sources : any[]
2526

27+
export declare function __rest(t: any, propertyNames: string[]): any;
28+
>__rest : (t: any, propertyNames: string[]) => any
29+
>t : any
30+
>propertyNames : string[]
31+
2632
export declare function __decorate(decorators: Function[], target: any, key?: string | symbol, desc?: any): any;
2733
>__decorate : (decorators: Function[], target: any, key?: string | symbol, desc?: any) => any
2834
>decorators : Function[]
@@ -53,3 +59,14 @@ export declare function __awaiter(thisArg: any, _arguments: any, P: Function, ge
5359
>generator : Function
5460
>Function : Function
5561

62+
export declare function __generator(thisArg: any, body: Function): any;
63+
>__generator : (thisArg: any, body: Function) => any
64+
>thisArg : any
65+
>body : Function
66+
>Function : Function
67+
68+
export declare function __exportStar(m: any, exports: any): void;
69+
>__exportStar : (m: any, exports: any) => void
70+
>m : any
71+
>exports : any
72+

tests/baselines/reference/importHelpersInAmbientContext.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,13 @@ declare namespace N {
4848
//// [tslib.d.ts]
4949
export declare function __extends(d: Function, b: Function): void;
5050
export declare function __assign(t: any, ...sources: any[]): any;
51+
export declare function __rest(t: any, propertyNames: string[]): any;
5152
export declare function __decorate(decorators: Function[], target: any, key?: string | symbol, desc?: any): any;
5253
export declare function __param(paramIndex: number, decorator: Function): Function;
5354
export declare function __metadata(metadataKey: any, metadataValue: any): Function;
5455
export declare function __awaiter(thisArg: any, _arguments: any, P: Function, generator: Function): any;
55-
56+
export declare function __generator(thisArg: any, body: Function): any;
57+
export declare function __exportStar(m: any, exports: any): void;
5658

5759
//// [b.js]
5860
"use strict";

tests/baselines/reference/importHelpersInAmbientContext.symbols

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,11 @@ export declare function __assign(t: any, ...sources: any[]): any;
9898
>t : Symbol(t, Decl(tslib.d.ts, --, --))
9999
>sources : Symbol(sources, Decl(tslib.d.ts, --, --))
100100

101+
export declare function __rest(t: any, propertyNames: string[]): any;
102+
>__rest : Symbol(__rest, Decl(tslib.d.ts, --, --))
103+
>t : Symbol(t, Decl(tslib.d.ts, --, --))
104+
>propertyNames : Symbol(propertyNames, Decl(tslib.d.ts, --, --))
105+
101106
export declare function __decorate(decorators: Function[], target: any, key?: string | symbol, desc?: any): any;
102107
>__decorate : Symbol(__decorate, Decl(tslib.d.ts, --, --))
103108
>decorators : Symbol(decorators, Decl(tslib.d.ts, --, --))
@@ -128,3 +133,14 @@ export declare function __awaiter(thisArg: any, _arguments: any, P: Function, ge
128133
>generator : Symbol(generator, Decl(tslib.d.ts, --, --))
129134
>Function : Symbol(Function, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
130135

136+
export declare function __generator(thisArg: any, body: Function): any;
137+
>__generator : Symbol(__generator, Decl(tslib.d.ts, --, --))
138+
>thisArg : Symbol(thisArg, Decl(tslib.d.ts, --, --))
139+
>body : Symbol(body, Decl(tslib.d.ts, --, --))
140+
>Function : Symbol(Function, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
141+
142+
export declare function __exportStar(m: any, exports: any): void;
143+
>__exportStar : Symbol(__exportStar, Decl(tslib.d.ts, --, --))
144+
>m : Symbol(m, Decl(tslib.d.ts, --, --))
145+
>exports : Symbol(exports, Decl(tslib.d.ts, --, --))
146+

tests/baselines/reference/importHelpersInAmbientContext.types

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,11 @@ export declare function __assign(t: any, ...sources: any[]): any;
9898
>t : any
9999
>sources : any[]
100100

101+
export declare function __rest(t: any, propertyNames: string[]): any;
102+
>__rest : (t: any, propertyNames: string[]) => any
103+
>t : any
104+
>propertyNames : string[]
105+
101106
export declare function __decorate(decorators: Function[], target: any, key?: string | symbol, desc?: any): any;
102107
>__decorate : (decorators: Function[], target: any, key?: string | symbol, desc?: any) => any
103108
>decorators : Function[]
@@ -128,3 +133,14 @@ export declare function __awaiter(thisArg: any, _arguments: any, P: Function, ge
128133
>generator : Function
129134
>Function : Function
130135

136+
export declare function __generator(thisArg: any, body: Function): any;
137+
>__generator : (thisArg: any, body: Function) => any
138+
>thisArg : any
139+
>body : Function
140+
>Function : Function
141+
142+
export declare function __exportStar(m: any, exports: any): void;
143+
>__exportStar : (m: any, exports: any) => void
144+
>m : any
145+
>exports : any
146+

tests/baselines/reference/importHelpersNoHelpers.errors.txt

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
1-
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'.
2-
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'.
3-
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'.
4-
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'.
5-
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'.
6-
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'.
1+
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'.
2+
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'.
3+
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'.
4+
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'.
5+
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'.
6+
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'.
7+
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'.
78

89

9-
==== tests/cases/compiler/external.ts (6 errors) ====
10+
==== tests/cases/compiler/external.ts (7 errors) ====
11+
export * from "./other";
12+
~~~~~~~~~~~~~~~~~~~~~~~~
13+
!!! error TS2343: This syntax requires an imported helper named '__exportStar', but module 'tslib' has no exported member '__exportStar'.
1014
export class A { }
1115
export class B extends A { }
1216
~~~~~~~~~
@@ -34,6 +38,9 @@ tests/cases/compiler/external.ts(14,12): error TS2343: This syntax requires an i
3438
~
3539
!!! error TS2343: This syntax requires an imported helper named '__rest', but module 'tslib' has no exported member '__rest'.
3640

41+
==== tests/cases/compiler/other.ts (0 errors) ====
42+
export const x = 1;
43+
3744
==== tests/cases/compiler/script.ts (0 errors) ====
3845
class A { }
3946
class B extends A { }

0 commit comments

Comments
 (0)