Call dynamic import transform on expression used by export equal statement (#18028)

* Call dynamic import transform on expression used by export equal statement

* Use Debug.fail
This commit is contained in:
Wesley Wigham
2017-08-24 17:08:57 -07:00
committed by GitHub
parent 05402b8596
commit 643a7e7e33
13 changed files with 204 additions and 20 deletions

View File

@@ -430,26 +430,32 @@ namespace ts {
*/
function addExportEqualsIfNeeded(statements: Statement[], emitAsReturn: boolean) {
if (currentModuleInfo.exportEquals) {
if (emitAsReturn) {
const statement = createReturn(currentModuleInfo.exportEquals.expression);
setTextRange(statement, currentModuleInfo.exportEquals);
setEmitFlags(statement, EmitFlags.NoTokenSourceMaps | EmitFlags.NoComments);
statements.push(statement);
}
else {
const statement = createStatement(
createAssignment(
createPropertyAccess(
createIdentifier("module"),
"exports"
),
currentModuleInfo.exportEquals.expression
)
);
const expressionResult = importCallExpressionVisitor(currentModuleInfo.exportEquals.expression);
if (expressionResult) {
if (expressionResult instanceof Array) {
return Debug.fail("export= expression should never be replaced with multiple expressions!");
}
if (emitAsReturn) {
const statement = createReturn(expressionResult);
setTextRange(statement, currentModuleInfo.exportEquals);
setEmitFlags(statement, EmitFlags.NoTokenSourceMaps | EmitFlags.NoComments);
statements.push(statement);
}
else {
const statement = createStatement(
createAssignment(
createPropertyAccess(
createIdentifier("module"),
"exports"
),
expressionResult
)
);
setTextRange(statement, currentModuleInfo.exportEquals);
setEmitFlags(statement, EmitFlags.NoComments);
statements.push(statement);
setTextRange(statement, currentModuleInfo.exportEquals);
setEmitFlags(statement, EmitFlags.NoComments);
statements.push(statement);
}
}
}
}
@@ -497,7 +503,7 @@ namespace ts {
}
}
function importCallExpressionVisitor(node: Node): VisitResult<Node> {
function importCallExpressionVisitor(node: Expression): VisitResult<Expression> {
// This visitor does not need to descend into the tree if there is no dynamic import,
// as export/import statements are only transformed at the top level of a file.
if (!(node.transformFlags & TransformFlags.ContainsDynamicImport)) {

View File

@@ -0,0 +1,22 @@
//// [tests/cases/conformance/dynamicImport/importCallExpressionInExportEqualsAMD.ts] ////
//// [something.ts]
export = 42;
//// [index.ts]
export = async function() {
const something = await import("./something");
};
//// [something.js]
define(["require", "exports"], function (require, exports) {
"use strict";
return 42;
});
//// [index.js]
define(["require", "exports"], function (require, exports) {
"use strict";
return async function () {
const something = await new Promise(function (resolve_1, reject_1) { require(["./something"], resolve_1, reject_1); });
};
});

View File

@@ -0,0 +1,10 @@
=== tests/cases/conformance/dynamicImport/something.ts ===
export = 42;
No type information for this code.
No type information for this code.=== tests/cases/conformance/dynamicImport/index.ts ===
export = async function() {
const something = await import("./something");
>something : Symbol(something, Decl(index.ts, 1, 9))
>"./something" : Symbol("tests/cases/conformance/dynamicImport/something", Decl(something.ts, 0, 0))
};

View File

@@ -0,0 +1,14 @@
=== tests/cases/conformance/dynamicImport/something.ts ===
export = 42;
No type information for this code.
No type information for this code.=== tests/cases/conformance/dynamicImport/index.ts ===
export = async function() {
>async function() { const something = await import("./something");} : () => Promise<void>
const something = await import("./something");
>something : 42
>await import("./something") : 42
>import("./something") : Promise<42>
>"./something" : "./something"
};

View File

@@ -0,0 +1,18 @@
//// [tests/cases/conformance/dynamicImport/importCallExpressionInExportEqualsCJS.ts] ////
//// [something.ts]
export = 42;
//// [index.ts]
export = async function() {
const something = await import("./something");
};
//// [something.js]
"use strict";
module.exports = 42;
//// [index.js]
"use strict";
module.exports = async function () {
const something = await Promise.resolve().then(function () { return require("./something"); });
};

View File

@@ -0,0 +1,10 @@
=== tests/cases/conformance/dynamicImport/something.ts ===
export = 42;
No type information for this code.
No type information for this code.=== tests/cases/conformance/dynamicImport/index.ts ===
export = async function() {
const something = await import("./something");
>something : Symbol(something, Decl(index.ts, 1, 9))
>"./something" : Symbol("tests/cases/conformance/dynamicImport/something", Decl(something.ts, 0, 0))
};

View File

@@ -0,0 +1,14 @@
=== tests/cases/conformance/dynamicImport/something.ts ===
export = 42;
No type information for this code.
No type information for this code.=== tests/cases/conformance/dynamicImport/index.ts ===
export = async function() {
>async function() { const something = await import("./something");} : () => Promise<void>
const something = await import("./something");
>something : 42
>await import("./something") : 42
>import("./something") : Promise<42>
>"./something" : "./something"
};

View File

@@ -0,0 +1,39 @@
//// [tests/cases/conformance/dynamicImport/importCallExpressionInExportEqualsUMD.ts] ////
//// [something.ts]
export = 42;
//// [index.ts]
export = async function() {
const something = await import("./something");
};
//// [something.js]
(function (factory) {
if (typeof module === "object" && typeof module.exports === "object") {
var v = factory(require, exports);
if (v !== undefined) module.exports = v;
}
else if (typeof define === "function" && define.amd) {
define(["require", "exports"], factory);
}
})(function (require, exports) {
"use strict";
return 42;
});
//// [index.js]
(function (factory) {
if (typeof module === "object" && typeof module.exports === "object") {
var v = factory(require, exports);
if (v !== undefined) module.exports = v;
}
else if (typeof define === "function" && define.amd) {
define(["require", "exports"], factory);
}
})(function (require, exports) {
"use strict";
var __syncRequire = typeof module === "object" && typeof module.exports === "object";
return async function () {
const something = await (__syncRequire ? Promise.resolve().then(function () { return require("./something"); }) : new Promise(function (resolve_1, reject_1) { require(["./something"], resolve_1, reject_1); }));
};
});

View File

@@ -0,0 +1,10 @@
=== tests/cases/conformance/dynamicImport/something.ts ===
export = 42;
No type information for this code.
No type information for this code.=== tests/cases/conformance/dynamicImport/index.ts ===
export = async function() {
const something = await import("./something");
>something : Symbol(something, Decl(index.ts, 1, 9))
>"./something" : Symbol("tests/cases/conformance/dynamicImport/something", Decl(something.ts, 0, 0))
};

View File

@@ -0,0 +1,14 @@
=== tests/cases/conformance/dynamicImport/something.ts ===
export = 42;
No type information for this code.
No type information for this code.=== tests/cases/conformance/dynamicImport/index.ts ===
export = async function() {
>async function() { const something = await import("./something");} : () => Promise<void>
const something = await import("./something");
>something : 42
>await import("./something") : 42
>import("./something") : Promise<42>
>"./something" : "./something"
};

View File

@@ -0,0 +1,9 @@
// @module: amd
// @target: esnext
// @filename: something.ts
export = 42;
// @filename: index.ts
export = async function() {
const something = await import("./something");
};

View File

@@ -0,0 +1,9 @@
// @module: commonjs
// @target: esnext
// @filename: something.ts
export = 42;
// @filename: index.ts
export = async function() {
const something = await import("./something");
};

View File

@@ -0,0 +1,9 @@
// @module: umd
// @target: esnext
// @filename: something.ts
export = 42;
// @filename: index.ts
export = async function() {
const something = await import("./something");
};