mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-03-02 23:26:03 -06:00
Avoid emitting temp variable in downleveled import() (#51562)
This commit is contained in:
parent
fa15877d63
commit
df7f5fc94e
@ -958,32 +958,57 @@ export function transformModule(context: TransformationContext): (x: SourceFile
|
||||
function createImportCallExpressionCommonJS(arg: Expression | undefined, isInlineable?: boolean): Expression {
|
||||
// import(x)
|
||||
// emit as
|
||||
// var _a;
|
||||
// (_a = x, Promise.resolve().then(() => require(_a)) /*CommonJs Require*/
|
||||
// Promise.resolve(`${x}`).then((s) => require(s)) /*CommonJs Require*/
|
||||
// We have to wrap require in then callback so that require is done in asynchronously
|
||||
// if we simply do require in resolve callback in Promise constructor. We will execute the loading immediately
|
||||
// If the arg is not inlineable, we have to evaluate it in the current scope with a temp var
|
||||
const temp = arg && !isSimpleInlineableExpression(arg) && !isInlineable ? factory.createTempVariable(hoistVariableDeclaration) : undefined;
|
||||
// If the arg is not inlineable, we have to evaluate and ToString() it in the current scope
|
||||
// Otherwise, we inline it in require() so that it's statically analyzable
|
||||
const needSyncEval = arg && !isSimpleInlineableExpression(arg) && !isInlineable;
|
||||
|
||||
const promiseResolveCall = factory.createCallExpression(
|
||||
factory.createPropertyAccessExpression(factory.createIdentifier("Promise"), "resolve"),
|
||||
/*typeArguments*/ undefined,
|
||||
/*argumentsArray*/ [],
|
||||
/*argumentsArray*/ needSyncEval
|
||||
? languageVersion >= ScriptTarget.ES2015
|
||||
? [
|
||||
factory.createTemplateExpression(factory.createTemplateHead(""), [
|
||||
factory.createTemplateSpan(arg, factory.createTemplateTail("")),
|
||||
]),
|
||||
]
|
||||
: [
|
||||
factory.createCallExpression(
|
||||
factory.createPropertyAccessExpression(factory.createStringLiteral(""), "concat"),
|
||||
/*typeArguments*/ undefined,
|
||||
[arg]
|
||||
),
|
||||
]
|
||||
: []
|
||||
);
|
||||
|
||||
let requireCall: Expression = factory.createCallExpression(
|
||||
factory.createIdentifier("require"),
|
||||
/*typeArguments*/ undefined,
|
||||
temp ? [temp] : arg ? [arg] : [],
|
||||
needSyncEval ? [factory.createIdentifier("s")] : arg ? [arg] : [],
|
||||
);
|
||||
if (getESModuleInterop(compilerOptions)) {
|
||||
requireCall = emitHelpers().createImportStarHelper(requireCall);
|
||||
}
|
||||
|
||||
const parameters = needSyncEval
|
||||
? [
|
||||
factory.createParameterDeclaration(
|
||||
/*modifiers*/ undefined,
|
||||
/*dotDotDotToken*/ undefined,
|
||||
/*name*/ "s"),
|
||||
]
|
||||
: [];
|
||||
|
||||
let func: FunctionExpression | ArrowFunction;
|
||||
if (languageVersion >= ScriptTarget.ES2015) {
|
||||
func = factory.createArrowFunction(
|
||||
/*modifiers*/ undefined,
|
||||
/*typeParameters*/ undefined,
|
||||
/*parameters*/ [],
|
||||
/*parameters*/ parameters,
|
||||
/*type*/ undefined,
|
||||
/*equalsGreaterThanToken*/ undefined,
|
||||
requireCall);
|
||||
@ -994,14 +1019,14 @@ export function transformModule(context: TransformationContext): (x: SourceFile
|
||||
/*asteriskToken*/ undefined,
|
||||
/*name*/ undefined,
|
||||
/*typeParameters*/ undefined,
|
||||
/*parameters*/ [],
|
||||
/*parameters*/ parameters,
|
||||
/*type*/ undefined,
|
||||
factory.createBlock([factory.createReturnStatement(requireCall)]));
|
||||
}
|
||||
|
||||
const downleveledImport = factory.createCallExpression(factory.createPropertyAccessExpression(promiseResolveCall, "then"), /*typeArguments*/ undefined, [func]);
|
||||
|
||||
return temp === undefined ? downleveledImport : factory.createCommaListExpression([factory.createAssignment(temp, arg!), downleveledImport]);
|
||||
return downleveledImport;
|
||||
}
|
||||
|
||||
function getHelperExpressionForExport(node: ExportDeclaration, innerExpr: Expression) {
|
||||
|
||||
@ -46,13 +46,12 @@ var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _ar
|
||||
function foo() {
|
||||
return __asyncGenerator(this, arguments, function foo_1() {
|
||||
return __generator(this, function (_a) {
|
||||
var _b, _c;
|
||||
switch (_a.label) {
|
||||
case 0: return [4 /*yield*/, __await("foo")];
|
||||
case 1: return [4 /*yield*/, _a.sent()];
|
||||
case 2: return [4 /*yield*/, __await.apply(void 0, [(_b = _a.sent(), Promise.resolve().then(function () { return require(_b); }))])];
|
||||
case 2: return [4 /*yield*/, __await.apply(void 0, [Promise.resolve("".concat(_a.sent())).then(function (s) { return require(s); })])];
|
||||
case 3:
|
||||
_c = (_a.sent())["default"], Promise.resolve().then(function () { return require(_c); });
|
||||
Promise.resolve("".concat((_a.sent())["default"])).then(function (s) { return require(s); });
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
|
||||
@ -16,16 +16,14 @@ const someFunction = async () => {
|
||||
|
||||
|
||||
//// [dynamicImportEvaluateSpecifier.js]
|
||||
var _a, _b;
|
||||
// https://github.com/microsoft/TypeScript/issues/48285
|
||||
let i = 0;
|
||||
_a = String(i++), Promise.resolve().then(() => require(_a));
|
||||
_b = String(i++), Promise.resolve().then(() => require(_b));
|
||||
Promise.resolve(`${String(i++)}`).then(s => require(s));
|
||||
Promise.resolve(`${String(i++)}`).then(s => require(s));
|
||||
const getPath = async () => {
|
||||
/* in reality this would do some async FS operation, or a web request */
|
||||
return "/root/my/cool/path";
|
||||
};
|
||||
const someFunction = async () => {
|
||||
var _a;
|
||||
const result = await (_a = await getPath(), Promise.resolve().then(() => require(_a)));
|
||||
const result = await Promise.resolve(`${await getPath()}`).then(s => require(s));
|
||||
};
|
||||
|
||||
@ -3,6 +3,5 @@ const path = './foo';
|
||||
import(path,);
|
||||
|
||||
//// [dynamicImportTrailingComma.js]
|
||||
var _a;
|
||||
var path = './foo';
|
||||
_a = path, Promise.resolve().then(function () { return require(_a); });
|
||||
Promise.resolve("".concat(path)).then(function (s) { return require(s); });
|
||||
|
||||
@ -15,14 +15,12 @@ function returnDynamicLoad(path: string) {
|
||||
}
|
||||
|
||||
//// [importCallExpressionDeclarationEmit1.js]
|
||||
var _a, _b, _c, _d;
|
||||
_a = getSpecifier(), Promise.resolve().then(() => require(_a));
|
||||
var p0 = (_b = `${directory}\\${moduleFile}`, Promise.resolve().then(() => require(_b)));
|
||||
var p1 = (_c = getSpecifier(), Promise.resolve().then(() => require(_c)));
|
||||
const p2 = (_d = whatToLoad ? getSpecifier() : "defaulPath", Promise.resolve().then(() => require(_d)));
|
||||
Promise.resolve(`${getSpecifier()}`).then(s => require(s));
|
||||
var p0 = Promise.resolve(`${`${directory}\\${moduleFile}`}`).then(s => require(s));
|
||||
var p1 = Promise.resolve(`${getSpecifier()}`).then(s => require(s));
|
||||
const p2 = Promise.resolve(`${whatToLoad ? getSpecifier() : "defaulPath"}`).then(s => require(s));
|
||||
function returnDynamicLoad(path) {
|
||||
var _a;
|
||||
return _a = path, Promise.resolve().then(() => require(_a));
|
||||
return Promise.resolve(`${path}`).then(s => require(s));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -10,9 +10,8 @@ const p2 = import();
|
||||
const p4 = import("pathToModule", "secondModule");
|
||||
|
||||
//// [importCallExpressionGrammarError.js]
|
||||
var _a, _b;
|
||||
var a = ["./0"];
|
||||
_a = (...["PathModule"]), Promise.resolve().then(() => require(_a));
|
||||
var p1 = (_b = (...a), Promise.resolve().then(() => require(_b)));
|
||||
Promise.resolve(`${...["PathModule"]}`).then(s => require(s));
|
||||
var p1 = Promise.resolve(`${...a}`).then(s => require(s));
|
||||
const p2 = Promise.resolve().then(() => require());
|
||||
const p4 = Promise.resolve().then(() => require("pathToModule"));
|
||||
|
||||
@ -24,7 +24,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
||||
};
|
||||
function foo() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
var _a;
|
||||
return yield (_a = (yield Promise.resolve().then(() => require("./foo"))).default, Promise.resolve().then(() => require(_a)));
|
||||
return yield Promise.resolve(`${(yield Promise.resolve().then(() => require("./foo"))).default}`).then(s => require(s));
|
||||
});
|
||||
}
|
||||
|
||||
@ -52,10 +52,9 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
|
||||
function foo() {
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
return __generator(this, function (_a) {
|
||||
var _b;
|
||||
switch (_a.label) {
|
||||
case 0: return [4 /*yield*/, Promise.resolve().then(function () { return require("./foo"); })];
|
||||
case 1: return [4 /*yield*/, (_b = (_a.sent()).default, Promise.resolve().then(function () { return require(_b); }))];
|
||||
case 1: return [4 /*yield*/, Promise.resolve("".concat((_a.sent()).default)).then(function (s) { return require(s); })];
|
||||
case 2: return [2 /*return*/, _a.sent()];
|
||||
}
|
||||
});
|
||||
|
||||
@ -42,23 +42,21 @@ class C {
|
||||
exports.C = C;
|
||||
//// [1.js]
|
||||
"use strict";
|
||||
var _a, _b, _c, _d, _e, _f, _g;
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
_a = `${directory}\\${moduleFile}`, Promise.resolve().then(() => require(_a));
|
||||
_b = getSpecifier(), Promise.resolve().then(() => require(_b));
|
||||
var p1 = (_c = ValidSomeCondition() ? "./0" : "externalModule", Promise.resolve().then(() => require(_c)));
|
||||
var p1 = (_d = getSpecifier(), Promise.resolve().then(() => require(_d)));
|
||||
var p11 = (_e = getSpecifier(), Promise.resolve().then(() => require(_e)));
|
||||
const p2 = (_f = whatToLoad ? getSpecifier() : "defaulPath", Promise.resolve().then(() => require(_f)));
|
||||
Promise.resolve(`${`${directory}\\${moduleFile}`}`).then(s => require(s));
|
||||
Promise.resolve(`${getSpecifier()}`).then(s => require(s));
|
||||
var p1 = Promise.resolve(`${ValidSomeCondition() ? "./0" : "externalModule"}`).then(s => require(s));
|
||||
var p1 = Promise.resolve(`${getSpecifier()}`).then(s => require(s));
|
||||
var p11 = Promise.resolve(`${getSpecifier()}`).then(s => require(s));
|
||||
const p2 = Promise.resolve(`${whatToLoad ? getSpecifier() : "defaulPath"}`).then(s => require(s));
|
||||
p1.then(zero => {
|
||||
return zero.foo(); // ok, zero is any
|
||||
});
|
||||
let j;
|
||||
var p3 = (_g = j = getSpecifier(), Promise.resolve().then(() => require(_g)));
|
||||
var p3 = Promise.resolve(`${j = getSpecifier()}`).then(s => require(s));
|
||||
function* loadModule(directories) {
|
||||
var _a;
|
||||
for (const directory of directories) {
|
||||
const path = `${directory}\\moduleFile`;
|
||||
_a = yield path, Promise.resolve().then(() => require(_a));
|
||||
Promise.resolve(`${yield path}`).then(s => require(s));
|
||||
}
|
||||
}
|
||||
|
||||
@ -14,13 +14,12 @@ var p3 = import(["path1", "path2"]);
|
||||
var p4 = import(()=>"PathToModule");
|
||||
|
||||
//// [importCallExpressionSpecifierNotStringTypeError.js]
|
||||
var _a, _b, _c, _d, _e;
|
||||
// Error specifier is not assignable to string
|
||||
_a = getSpecifier(), Promise.resolve().then(() => require(_a));
|
||||
var p1 = (_b = getSpecifier(), Promise.resolve().then(() => require(_b)));
|
||||
const p2 = (_c = whatToLoad ? getSpecifier() : "defaulPath", Promise.resolve().then(() => require(_c)));
|
||||
Promise.resolve(`${getSpecifier()}`).then(s => require(s));
|
||||
var p1 = Promise.resolve(`${getSpecifier()}`).then(s => require(s));
|
||||
const p2 = Promise.resolve(`${whatToLoad ? getSpecifier() : "defaulPath"}`).then(s => require(s));
|
||||
p1.then(zero => {
|
||||
return zero.foo(); // ok, zero is any
|
||||
});
|
||||
var p3 = (_d = ["path1", "path2"], Promise.resolve().then(() => require(_d)));
|
||||
var p4 = (_e = () => "PathToModule", Promise.resolve().then(() => require(_e)));
|
||||
var p3 = Promise.resolve(`${["path1", "path2"]}`).then(s => require(s));
|
||||
var p4 = Promise.resolve(`${() => "PathToModule"}`).then(s => require(s));
|
||||
|
||||
@ -58,7 +58,6 @@ var v = import(String());
|
||||
|
||||
|
||||
//// [jsdocInTypeScript.js]
|
||||
var _a;
|
||||
var T = /** @class */ (function () {
|
||||
function T() {
|
||||
}
|
||||
@ -93,4 +92,4 @@ var E = {};
|
||||
E[""];
|
||||
// make sure import types in JSDoc are not resolved
|
||||
/** @type {import("should-not-be-resolved").Type} */
|
||||
var v = (_a = String(), Promise.resolve().then(function () { return require(_a); }));
|
||||
var v = Promise.resolve("".concat(String())).then(function (s) { return require(s); });
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user