Bug 1843797 - Add ESLint rule to reject ChromeUtils.import. r=Standard8

Differential Revision: https://phabricator.services.mozilla.com/D183696
This commit is contained in:
Tooru Fujisawa 2023-07-31 21:03:44 +00:00
Родитель 2933a357f7
Коммит aa900309a0
6 изменённых файлов: 210 добавлений и 0 удалений

Просмотреть файл

@ -2079,5 +2079,22 @@ module.exports = {
"@microsoft/sdl/no-insecure-url": "off",
},
},
{
files: ["*.html", "*.xhtml", "*.xml"],
excludedFiles: [
// Tests specific to JSM
"dom/encoding/test/test_stringencoding.xhtml",
"dom/url/tests/test_bug883784.xhtml",
"dom/url/tests/test_url.xhtml",
"dom/url/tests/test_worker_url.xhtml",
"dom/workers/test/test_chromeWorkerJSM.xhtml",
"js/xpconnect/tests/chrome/test_chrometoSource.xhtml",
"js/xpconnect/tests/chrome/test_expandosharing.xhtml",
"js/xpconnect/tests/chrome/test_xrayic.xhtml",
],
rules: {
"mozilla/reject-chromeutils-import": "error",
},
},
],
};

Просмотреть файл

@ -50,6 +50,7 @@ The plugin implements the following rules:
eslint-plugin-mozilla/prefer-boolean-length-check
eslint-plugin-mozilla/prefer-formatValues
eslint-plugin-mozilla/reject-addtask-only
eslint-plugin-mozilla/reject-chromeutils-import
eslint-plugin-mozilla/reject-chromeutils-import-params
eslint-plugin-mozilla/reject-eager-module-in-lazy-getter
eslint-plugin-mozilla/reject-global-this

Просмотреть файл

@ -0,0 +1,31 @@
reject-chromeutils-import
================================
While ``ChromeUtils.import`` supports the fallback to ESMified module,
in-tree files should use ``ChromeUtils.importESModule`` for ESMified modules.
Examples of incorrect code for this rule:
-----------------------------------------
.. code-block:: js
Components.utils.import("resource://gre/modules/AppConstants.jsm");
Cu.import("resource://gre/modules/AppConstants.jsm");
ChromeUtils.import("resource://gre/modules/AppConstants.jsm");
ChromeUtils.defineModuleGetter(
obj, "AppConstants", "resource://gre/modules/AppConstants.jsm");
XPCOMUtils.defineLazyModuleGetter(
obj, "AppConstants", "resource://gre/modules/AppConstants.jsm");
XPCOMUtils.defineLazyModuleGetters(
obj, { AppConstants: "resource://gre/modules/AppConstants.jsm" });
Examples of correct code for this rule:
---------------------------------------
.. code-block:: js
ChromeUtils.importESModule("resource://gre/modules/AppConstants.sys.mjs");
ChromeUtils.defineESModuleGetters(
obj, { AppConstants: "resource://gre/modules/AppConstants.sys.mjs" });

Просмотреть файл

@ -63,6 +63,7 @@ module.exports = {
"prefer-boolean-length-check": require("../lib/rules/prefer-boolean-length-check"),
"prefer-formatValues": require("../lib/rules/prefer-formatValues"),
"reject-addtask-only": require("../lib/rules/reject-addtask-only"),
"reject-chromeutils-import": require("../lib/rules/reject-chromeutils-import"),
"reject-chromeutils-import-params": require("../lib/rules/reject-chromeutils-import-params"),
"reject-eager-module-in-lazy-getter": require("../lib/rules/reject-eager-module-in-lazy-getter"),
"reject-global-this": require("../lib/rules/reject-global-this"),

Просмотреть файл

@ -0,0 +1,84 @@
/**
* @fileoverview Reject use of Cu.import and ChromeUtils.import
* in favor of ChromeUtils.importESModule.
*
* 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/.
*/
"use strict";
function isIdentifier(node, id) {
return node && node.type === "Identifier" && node.name === id;
}
function isMemberExpression(node, object, member) {
return (
node.type === "MemberExpression" &&
isIdentifier(node.object, object) &&
isIdentifier(node.property, member)
);
}
module.exports = {
meta: {
docs: {
url: "https://firefox-source-docs.mozilla.org/code-quality/lint/linters/eslint-plugin-mozilla/reject-chromeutils-import.html",
},
messages: {
useImportESModule:
"Please use ChromeUtils.importESModule instead of " +
"ChromeUtils.import unless the module is not yet ESMified",
useImportESModuleLazy:
"Please use ChromeUtils.defineESModuleGetters instead of " +
"ChromeUtils.defineModuleGetter " +
"unless the module is not yet ESMified",
},
schema: [],
type: "problem",
},
create(context) {
return {
CallExpression(node) {
if (node.callee.type !== "MemberExpression") {
return;
}
let { callee } = node;
if (
(isMemberExpression(callee.object, "Components", "utils") ||
isIdentifier(callee.object, "Cu") ||
isMemberExpression(callee.object, "SpecialPowers", "Cu") ||
isIdentifier(callee.object, "ChromeUtils") ||
isMemberExpression(
callee.object,
"SpecialPowers",
"ChromeUtils"
)) &&
isIdentifier(callee.property, "import")
) {
context.report({
node,
messageId: "useImportESModule",
});
}
if (
(isMemberExpression(callee.object, "SpecialPowers", "ChromeUtils") &&
isIdentifier(callee.property, "defineModuleGetter")) ||
isMemberExpression(callee, "ChromeUtils", "defineModuleGetter") ||
isMemberExpression(callee, "XPCOMUtils", "defineLazyModuleGetter") ||
isMemberExpression(callee, "XPCOMUtils", "defineLazyModuleGetters")
) {
context.report({
node,
messageId: "useImportESModuleLazy",
});
}
},
};
},
};

Просмотреть файл

@ -0,0 +1,76 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// ------------------------------------------------------------------------------
// Requirements
// ------------------------------------------------------------------------------
var rule = require("../lib/rules/reject-chromeutils-import");
var RuleTester = require("eslint").RuleTester;
const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: "latest" } });
// ------------------------------------------------------------------------------
// Tests
// ------------------------------------------------------------------------------
const invalidError = [
{
messageId: "useImportESModule",
type: "CallExpression",
},
];
const invalidErrorLazy = [
{
messageId: "useImportESModuleLazy",
type: "CallExpression",
},
];
ruleTester.run("reject-chromeutils-import", rule, {
valid: [
'ChromeUtils.importESModule("resource://some/path/to/My.sys.mjs")',
'ChromeUtils.defineESModuleGetters(obj, { My: "resource://some/path/to/My.sys.mjs" })',
],
invalid: [
{
code: 'Components.utils.import("resource://some/path/to/My.jsm")',
errors: invalidError,
},
{
code: 'Cu.import("resource://some/path/to/My.jsm")',
errors: invalidError,
},
{
code: 'ChromeUtils.import("resource://some/path/to/My.jsm")',
errors: invalidError,
},
{
code: 'SpecialPowers.Cu.import("resource://some/path/to/My.jsm")',
errors: invalidError,
},
{
code: 'SpecialPowers.ChromeUtils.import("resource://some/path/to/My.jsm")',
errors: invalidError,
},
{
code: 'ChromeUtils.defineModuleGetter(obj, "My", "resource://some/path/to/My.jsm")',
errors: invalidErrorLazy,
},
{
code: 'SpecialPowers.ChromeUtils.defineModuleGetter(obj, "My", "resource://some/path/to/My.jsm")',
errors: invalidErrorLazy,
},
{
code: 'XPCOMUtils.defineLazyModuleGetter(obj, "My", "resource://some/path/to/My.jsm")',
errors: invalidErrorLazy,
},
{
code: 'XPCOMUtils.defineLazyModuleGetters(obj, { My: "resource://some/path/to/My.jsm" })',
errors: invalidErrorLazy,
},
],
});