Skip to content

Commit 350c9f6

Browse files
authored
Call dynamic import transform on expression used by export equal statement (#18028) (#18033)
* Call dynamic import transform on expression used by export equal statement * Use Debug.fail
1 parent 0851f69 commit 350c9f6

13 files changed

+204
-20
lines changed

src/compiler/transformers/module/module.ts

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -430,26 +430,32 @@ namespace ts {
430430
*/
431431
function addExportEqualsIfNeeded(statements: Statement[], emitAsReturn: boolean) {
432432
if (currentModuleInfo.exportEquals) {
433-
if (emitAsReturn) {
434-
const statement = createReturn(currentModuleInfo.exportEquals.expression);
435-
setTextRange(statement, currentModuleInfo.exportEquals);
436-
setEmitFlags(statement, EmitFlags.NoTokenSourceMaps | EmitFlags.NoComments);
437-
statements.push(statement);
438-
}
439-
else {
440-
const statement = createStatement(
441-
createAssignment(
442-
createPropertyAccess(
443-
createIdentifier("module"),
444-
"exports"
445-
),
446-
currentModuleInfo.exportEquals.expression
447-
)
448-
);
433+
const expressionResult = importCallExpressionVisitor(currentModuleInfo.exportEquals.expression);
434+
if (expressionResult) {
435+
if (expressionResult instanceof Array) {
436+
return Debug.fail("export= expression should never be replaced with multiple expressions!");
437+
}
438+
if (emitAsReturn) {
439+
const statement = createReturn(expressionResult);
440+
setTextRange(statement, currentModuleInfo.exportEquals);
441+
setEmitFlags(statement, EmitFlags.NoTokenSourceMaps | EmitFlags.NoComments);
442+
statements.push(statement);
443+
}
444+
else {
445+
const statement = createStatement(
446+
createAssignment(
447+
createPropertyAccess(
448+
createIdentifier("module"),
449+
"exports"
450+
),
451+
expressionResult
452+
)
453+
);
449454

450-
setTextRange(statement, currentModuleInfo.exportEquals);
451-
setEmitFlags(statement, EmitFlags.NoComments);
452-
statements.push(statement);
455+
setTextRange(statement, currentModuleInfo.exportEquals);
456+
setEmitFlags(statement, EmitFlags.NoComments);
457+
statements.push(statement);
458+
}
453459
}
454460
}
455461
}
@@ -497,7 +503,7 @@ namespace ts {
497503
}
498504
}
499505

500-
function importCallExpressionVisitor(node: Node): VisitResult<Node> {
506+
function importCallExpressionVisitor(node: Expression): VisitResult<Expression> {
501507
// This visitor does not need to descend into the tree if there is no dynamic import,
502508
// as export/import statements are only transformed at the top level of a file.
503509
if (!(node.transformFlags & TransformFlags.ContainsDynamicImport)) {
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
//// [tests/cases/conformance/dynamicImport/importCallExpressionInExportEqualsAMD.ts] ////
2+
3+
//// [something.ts]
4+
export = 42;
5+
6+
//// [index.ts]
7+
export = async function() {
8+
const something = await import("./something");
9+
};
10+
11+
//// [something.js]
12+
define(["require", "exports"], function (require, exports) {
13+
"use strict";
14+
return 42;
15+
});
16+
//// [index.js]
17+
define(["require", "exports"], function (require, exports) {
18+
"use strict";
19+
return async function () {
20+
const something = await new Promise(function (resolve_1, reject_1) { require(["./something"], resolve_1, reject_1); });
21+
};
22+
});
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
=== tests/cases/conformance/dynamicImport/something.ts ===
2+
export = 42;
3+
No type information for this code.
4+
No type information for this code.=== tests/cases/conformance/dynamicImport/index.ts ===
5+
export = async function() {
6+
const something = await import("./something");
7+
>something : Symbol(something, Decl(index.ts, 1, 9))
8+
>"./something" : Symbol("tests/cases/conformance/dynamicImport/something", Decl(something.ts, 0, 0))
9+
10+
};
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
=== tests/cases/conformance/dynamicImport/something.ts ===
2+
export = 42;
3+
No type information for this code.
4+
No type information for this code.=== tests/cases/conformance/dynamicImport/index.ts ===
5+
export = async function() {
6+
>async function() { const something = await import("./something");} : () => Promise<void>
7+
8+
const something = await import("./something");
9+
>something : 42
10+
>await import("./something") : 42
11+
>import("./something") : Promise<42>
12+
>"./something" : "./something"
13+
14+
};
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//// [tests/cases/conformance/dynamicImport/importCallExpressionInExportEqualsCJS.ts] ////
2+
3+
//// [something.ts]
4+
export = 42;
5+
6+
//// [index.ts]
7+
export = async function() {
8+
const something = await import("./something");
9+
};
10+
11+
//// [something.js]
12+
"use strict";
13+
module.exports = 42;
14+
//// [index.js]
15+
"use strict";
16+
module.exports = async function () {
17+
const something = await Promise.resolve().then(function () { return require("./something"); });
18+
};
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
=== tests/cases/conformance/dynamicImport/something.ts ===
2+
export = 42;
3+
No type information for this code.
4+
No type information for this code.=== tests/cases/conformance/dynamicImport/index.ts ===
5+
export = async function() {
6+
const something = await import("./something");
7+
>something : Symbol(something, Decl(index.ts, 1, 9))
8+
>"./something" : Symbol("tests/cases/conformance/dynamicImport/something", Decl(something.ts, 0, 0))
9+
10+
};
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
=== tests/cases/conformance/dynamicImport/something.ts ===
2+
export = 42;
3+
No type information for this code.
4+
No type information for this code.=== tests/cases/conformance/dynamicImport/index.ts ===
5+
export = async function() {
6+
>async function() { const something = await import("./something");} : () => Promise<void>
7+
8+
const something = await import("./something");
9+
>something : 42
10+
>await import("./something") : 42
11+
>import("./something") : Promise<42>
12+
>"./something" : "./something"
13+
14+
};
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
//// [tests/cases/conformance/dynamicImport/importCallExpressionInExportEqualsUMD.ts] ////
2+
3+
//// [something.ts]
4+
export = 42;
5+
6+
//// [index.ts]
7+
export = async function() {
8+
const something = await import("./something");
9+
};
10+
11+
//// [something.js]
12+
(function (factory) {
13+
if (typeof module === "object" && typeof module.exports === "object") {
14+
var v = factory(require, exports);
15+
if (v !== undefined) module.exports = v;
16+
}
17+
else if (typeof define === "function" && define.amd) {
18+
define(["require", "exports"], factory);
19+
}
20+
})(function (require, exports) {
21+
"use strict";
22+
return 42;
23+
});
24+
//// [index.js]
25+
(function (factory) {
26+
if (typeof module === "object" && typeof module.exports === "object") {
27+
var v = factory(require, exports);
28+
if (v !== undefined) module.exports = v;
29+
}
30+
else if (typeof define === "function" && define.amd) {
31+
define(["require", "exports"], factory);
32+
}
33+
})(function (require, exports) {
34+
"use strict";
35+
var __syncRequire = typeof module === "object" && typeof module.exports === "object";
36+
return async function () {
37+
const something = await (__syncRequire ? Promise.resolve().then(function () { return require("./something"); }) : new Promise(function (resolve_1, reject_1) { require(["./something"], resolve_1, reject_1); }));
38+
};
39+
});
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
=== tests/cases/conformance/dynamicImport/something.ts ===
2+
export = 42;
3+
No type information for this code.
4+
No type information for this code.=== tests/cases/conformance/dynamicImport/index.ts ===
5+
export = async function() {
6+
const something = await import("./something");
7+
>something : Symbol(something, Decl(index.ts, 1, 9))
8+
>"./something" : Symbol("tests/cases/conformance/dynamicImport/something", Decl(something.ts, 0, 0))
9+
10+
};
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
=== tests/cases/conformance/dynamicImport/something.ts ===
2+
export = 42;
3+
No type information for this code.
4+
No type information for this code.=== tests/cases/conformance/dynamicImport/index.ts ===
5+
export = async function() {
6+
>async function() { const something = await import("./something");} : () => Promise<void>
7+
8+
const something = await import("./something");
9+
>something : 42
10+
>await import("./something") : 42
11+
>import("./something") : Promise<42>
12+
>"./something" : "./something"
13+
14+
};
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// @module: amd
2+
// @target: esnext
3+
// @filename: something.ts
4+
export = 42;
5+
6+
// @filename: index.ts
7+
export = async function() {
8+
const something = await import("./something");
9+
};
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// @module: commonjs
2+
// @target: esnext
3+
// @filename: something.ts
4+
export = 42;
5+
6+
// @filename: index.ts
7+
export = async function() {
8+
const something = await import("./something");
9+
};
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// @module: umd
2+
// @target: esnext
3+
// @filename: something.ts
4+
export = 42;
5+
6+
// @filename: index.ts
7+
export = async function() {
8+
const something = await import("./something");
9+
};

0 commit comments

Comments
 (0)