зеркало из https://github.com/mozilla/gecko-dev.git
148 строки
3.7 KiB
JavaScript
148 строки
3.7 KiB
JavaScript
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
/* eslint-env node */
|
|
|
|
const _path = require("path");
|
|
const { getESMFiles } = require(_path.resolve(__dirname, "./is-esmified.js"));
|
|
const {
|
|
esmifyExtension,
|
|
isString,
|
|
warnForPath,
|
|
isMemberExpressionWithIdentifiers,
|
|
} = require(_path.resolve(__dirname, "./utils.js"));
|
|
|
|
function isTargetESM(resourceURI) {
|
|
if ("ESMIFY_TARGET_PREFIX" in process.env) {
|
|
const files = getESMFiles(resourceURI);
|
|
const targetPrefix = process.env.ESMIFY_TARGET_PREFIX;
|
|
for (const esm of files) {
|
|
if (esm.startsWith(targetPrefix)) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
function isImportESModuleCall(node) {
|
|
return isMemberExpressionWithIdentifiers(node.callee, [
|
|
"ChromeUtils",
|
|
"importESModule",
|
|
]);
|
|
}
|
|
|
|
// Replace `ChromeUtils.import`, `Cu.import`, and `ChromeUtils.importESModule`
|
|
// with static import if it's at the top-level of system ESM file.
|
|
function tryReplacingWithStaticImport(
|
|
jscodeshift,
|
|
inputFile,
|
|
path,
|
|
resourceURINode,
|
|
alwaysReplace
|
|
) {
|
|
if (!alwaysReplace && !inputFile.endsWith(".sys.mjs")) {
|
|
// Static import is available only in system ESM.
|
|
return false;
|
|
}
|
|
|
|
// Check if it's at the top-level.
|
|
if (path.parent.node.type !== "VariableDeclarator") {
|
|
return false;
|
|
}
|
|
|
|
if (path.parent.parent.node.type !== "VariableDeclaration") {
|
|
return false;
|
|
}
|
|
|
|
const decls = path.parent.parent.node;
|
|
if (decls.declarations.length !== 1) {
|
|
return false;
|
|
}
|
|
|
|
if (path.parent.parent.parent.node.type !== "Program") {
|
|
return false;
|
|
}
|
|
|
|
if (path.node.arguments.length !== 1) {
|
|
return false;
|
|
}
|
|
|
|
const resourceURI = resourceURINode.value;
|
|
|
|
// Collect imported symbols.
|
|
const specs = [];
|
|
if (path.parent.node.id.type === "Identifier") {
|
|
specs.push(jscodeshift.importNamespaceSpecifier(path.parent.node.id));
|
|
} else if (path.parent.node.id.type === "ObjectPattern") {
|
|
for (const prop of path.parent.node.id.properties) {
|
|
if (prop.shorthand) {
|
|
specs.push(jscodeshift.importSpecifier(prop.key));
|
|
} else if (prop.value.type === "Identifier") {
|
|
specs.push(jscodeshift.importSpecifier(prop.key, prop.value));
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
} else {
|
|
return false;
|
|
}
|
|
|
|
// If this is `ChromeUtils.import` or `Cu.import`, replace the extension.
|
|
// no-op for `ChromeUtils.importESModule`.
|
|
resourceURINode.value = esmifyExtension(resourceURI);
|
|
|
|
const e = jscodeshift.importDeclaration(specs, resourceURINode);
|
|
e.comments = path.parent.parent.node.comments;
|
|
path.parent.parent.node.comments = [];
|
|
path.parent.parent.replace(e);
|
|
|
|
return true;
|
|
}
|
|
|
|
function replaceImportESModuleCall(
|
|
inputFile,
|
|
jscodeshift,
|
|
path,
|
|
alwaysReplace
|
|
) {
|
|
if (path.node.arguments.length !== 1) {
|
|
warnForPath(
|
|
inputFile,
|
|
path,
|
|
`importESModule call should have only one argument`
|
|
);
|
|
return;
|
|
}
|
|
|
|
const resourceURINode = path.node.arguments[0];
|
|
if (!isString(resourceURINode)) {
|
|
warnForPath(inputFile, path, `resource URI should be a string`);
|
|
return;
|
|
}
|
|
|
|
if (!alwaysReplace) {
|
|
const resourceURI = resourceURINode.value;
|
|
if (!isTargetESM(resourceURI)) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
// If this cannot be replaced with static import, do nothing.
|
|
tryReplacingWithStaticImport(
|
|
jscodeshift,
|
|
inputFile,
|
|
path,
|
|
resourceURINode,
|
|
alwaysReplace
|
|
);
|
|
}
|
|
|
|
exports.isImportESModuleCall = isImportESModuleCall;
|
|
exports.tryReplacingWithStaticImport = tryReplacingWithStaticImport;
|
|
exports.replaceImportESModuleCall = replaceImportESModuleCall;
|