223 lines
8.9 KiB
JavaScript
223 lines
8.9 KiB
JavaScript
/**
|
|
* @fileoverview A collection of rules that help enforce JavaScript coding
|
|
* standard and avoid common errors in the Mozilla project.
|
|
* 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";
|
|
|
|
const path = require("path");
|
|
const globals = require("globals");
|
|
const { allFileExtensions, turnOff } = require("./helpers.js");
|
|
|
|
const { name, version } = require(path.join(__dirname, "..", "package.json"));
|
|
|
|
const plugin = {
|
|
meta: { name, version },
|
|
configs: {
|
|
// Filled in below.
|
|
},
|
|
environments: {
|
|
"browser-window": require("./environments/browser-window.js"),
|
|
"chrome-script": require("./environments/chrome-script.js"),
|
|
"frame-script": require("./environments/frame-script.js"),
|
|
sysmjs: require("./environments/sysmjs.js"),
|
|
privileged: require("./environments/privileged.js"),
|
|
"process-script": require("./environments/process-script.js"),
|
|
"remote-page": require("./environments/remote-page.js"),
|
|
simpletest: require("./environments/simpletest.js"),
|
|
sjs: require("./environments/sjs.js"),
|
|
"special-powers-sandbox": require("./environments/special-powers-sandbox.js"),
|
|
specific: require("./environments/specific"),
|
|
testharness: require("./environments/testharness.js"),
|
|
xpcshell: require("./environments/xpcshell.js"),
|
|
},
|
|
rules: {
|
|
"avoid-Date-timing": require("./rules/avoid-Date-timing"),
|
|
"avoid-removeChild": require("./rules/avoid-removeChild"),
|
|
"balanced-listeners": require("./rules/balanced-listeners"),
|
|
"balanced-observers": require("./rules/balanced-observers"),
|
|
"import-browser-window-globals": require("./rules/import-browser-window-globals"),
|
|
"import-content-task-globals": require("./rules/import-content-task-globals"),
|
|
"import-globals": require("./rules/import-globals"),
|
|
"import-headjs-globals": require("./rules/import-headjs-globals"),
|
|
"lazy-getter-object-name": require("./rules/lazy-getter-object-name"),
|
|
"mark-test-function-used": require("./rules/mark-test-function-used"),
|
|
"no-aArgs": require("./rules/no-aArgs"),
|
|
"no-addtask-setup": require("./rules/no-addtask-setup"),
|
|
"no-arbitrary-setTimeout": require("./rules/no-arbitrary-setTimeout"),
|
|
"no-browser-refs-in-toolkit": require("./rules/no-browser-refs-in-toolkit"),
|
|
"no-compare-against-boolean-literals": require("./rules/no-compare-against-boolean-literals"),
|
|
"no-comparison-or-assignment-inside-ok": require("./rules/no-comparison-or-assignment-inside-ok"),
|
|
"no-cu-reportError": require("./rules/no-cu-reportError"),
|
|
"no-define-cc-etc": require("./rules/no-define-cc-etc"),
|
|
"no-more-globals": require("./rules/no-more-globals"),
|
|
"no-redeclare-with-import-autofix": require("./rules/no-redeclare-with-import-autofix"),
|
|
"no-throw-cr-literal": require("./rules/no-throw-cr-literal"),
|
|
"no-useless-parameters": require("./rules/no-useless-parameters"),
|
|
"no-useless-removeEventListener": require("./rules/no-useless-removeEventListener"),
|
|
"no-useless-run-test": require("./rules/no-useless-run-test"),
|
|
"prefer-boolean-length-check": require("./rules/prefer-boolean-length-check"),
|
|
"prefer-formatValues": require("./rules/prefer-formatValues"),
|
|
"reject-addtask-only": require("./rules/reject-addtask-only"),
|
|
"reject-eager-module-in-lazy-getter": require("./rules/reject-eager-module-in-lazy-getter"),
|
|
"reject-globalThis-modification": require("./rules/reject-globalThis-modification"),
|
|
"reject-import-system-module-from-non-system": require("./rules/reject-import-system-module-from-non-system"),
|
|
"reject-importGlobalProperties": require("./rules/reject-importGlobalProperties"),
|
|
"reject-lazy-imports-into-globals": require("./rules/reject-lazy-imports-into-globals"),
|
|
"reject-mixing-eager-and-lazy": require("./rules/reject-mixing-eager-and-lazy"),
|
|
"reject-multiple-await": require("./rules/reject-multiple-await.js"),
|
|
"reject-multiple-getters-calls": require("./rules/reject-multiple-getters-calls"),
|
|
"reject-scriptableunicodeconverter": require("./rules/reject-scriptableunicodeconverter"),
|
|
"reject-relative-requires": require("./rules/reject-relative-requires"),
|
|
"reject-some-requires": require("./rules/reject-some-requires"),
|
|
"reject-top-level-await": require("./rules/reject-top-level-await"),
|
|
"rejects-requires-await": require("./rules/rejects-requires-await"),
|
|
"use-cc-etc": require("./rules/use-cc-etc"),
|
|
"use-chromeutils-generateqi": require("./rules/use-chromeutils-generateqi"),
|
|
"use-console-createInstance": require("./rules/use-console-createInstance"),
|
|
"use-default-preference-values": require("./rules/use-default-preference-values"),
|
|
"use-ownerGlobal": require("./rules/use-ownerGlobal"),
|
|
"use-includes-instead-of-indexOf": require("./rules/use-includes-instead-of-indexOf"),
|
|
"use-isInstance": require("./rules/use-isInstance"),
|
|
"use-returnValue": require("./rules/use-returnValue"),
|
|
"use-services": require("./rules/use-services"),
|
|
"use-static-import": require("./rules/use-static-import"),
|
|
"valid-ci-uses": require("./rules/valid-ci-uses"),
|
|
"valid-lazy": require("./rules/valid-lazy"),
|
|
"valid-services": require("./rules/valid-services"),
|
|
"valid-services-property": require("./rules/valid-services-property"),
|
|
"var-only-at-top-level": require("./rules/var-only-at-top-level"),
|
|
},
|
|
allFileExtensions,
|
|
turnOff,
|
|
};
|
|
|
|
const configurations = [
|
|
"browser-test",
|
|
"chrome-test",
|
|
"general-test",
|
|
"mochitest-test",
|
|
"recommended",
|
|
"require-jsdoc",
|
|
"valid-jsdoc",
|
|
"xpcshell-test",
|
|
];
|
|
|
|
/**
|
|
* Clones a legacy configuration section, adjusting fields so that ESLint won't
|
|
* fail.
|
|
*
|
|
* @param {object} section
|
|
* The section to clone.
|
|
* @returns {object}
|
|
* The cloned section.
|
|
*/
|
|
function cloneLegacySection(section) {
|
|
let config = structuredClone(section);
|
|
|
|
// The legacy config doesn't support names, so get rid of those.
|
|
delete config.name;
|
|
|
|
if (config.overrides) {
|
|
for (let overridesSection of config.overrides) {
|
|
// The legacy config doesn't support names in sections, so get rid of those.
|
|
delete overridesSection.name;
|
|
// Also, the legacy config supports "excludedFiles" rather than "ignores".
|
|
if (overridesSection.ignores) {
|
|
overridesSection.excludedFiles = overridesSection.ignores;
|
|
delete overridesSection.ignores;
|
|
}
|
|
}
|
|
}
|
|
|
|
return config;
|
|
}
|
|
|
|
/**
|
|
* Clones a flat configuration section, adjusting fields so that ESLint won't
|
|
* fail.
|
|
*
|
|
* @param {object} section
|
|
* The section to clone.
|
|
* @returns {object}
|
|
* The cloned section.
|
|
*/
|
|
function cloneFlatSection(section) {
|
|
let config = structuredClone(section);
|
|
|
|
// We assume all parts of the flat config need the plugins defined. In
|
|
// practice, they only need to be defined where they are used, but for
|
|
// now this is simpler.
|
|
config.plugins = {
|
|
mozilla: plugin,
|
|
"no-unsanitized": require("eslint-plugin-no-unsanitized"),
|
|
"@microsoft/sdl": require("@microsoft/eslint-plugin-sdl"),
|
|
promise: require("eslint-plugin-promise"),
|
|
jsdoc: require("eslint-plugin-jsdoc"),
|
|
};
|
|
if (!config.languageOptions) {
|
|
config.languageOptions = {};
|
|
}
|
|
|
|
if (config.globals) {
|
|
config.languageOptions.globals = { ...config.globals };
|
|
delete config.globals;
|
|
}
|
|
|
|
// Handle changing the location of the sourceType.
|
|
if (config.parserOptions?.sourceType) {
|
|
config.languageOptions.sourceType = config.parserOptions.sourceType;
|
|
}
|
|
if (config.parserOptions?.ecmaFeatures) {
|
|
config.languageOptions.parserOptions = {
|
|
ecmaFeatures: config.parserOptions.ecmaFeatures,
|
|
};
|
|
}
|
|
delete config.parserOptions;
|
|
|
|
// Convert any environments into a list of globals.
|
|
for (let [key, value] of Object.entries(config.env ?? {})) {
|
|
if (!value) {
|
|
throw new Error(
|
|
"Removing environments is not supported by eslint-plugin-mozilla"
|
|
);
|
|
}
|
|
if (!config.languageOptions.globals) {
|
|
config.languageOptions.globals = {};
|
|
}
|
|
if (key.startsWith("mozilla/")) {
|
|
config.languageOptions.globals = {
|
|
...config.languageOptions.globals,
|
|
...plugin.environments[key.substring("mozilla/".length)].globals,
|
|
};
|
|
} else {
|
|
config.languageOptions.globals = {
|
|
...config.languageOptions.globals,
|
|
...globals[key],
|
|
};
|
|
}
|
|
}
|
|
delete config.env;
|
|
|
|
return config;
|
|
}
|
|
|
|
for (let configName of configurations) {
|
|
let config = require(`./configs/${configName}`);
|
|
|
|
if (configName == "recommended") {
|
|
plugin.configs[configName] = cloneLegacySection(config.getConfig("legacy"));
|
|
plugin.configs[`flat/${configName}`] = config
|
|
.getConfig("flat")
|
|
.map(section => cloneFlatSection(section));
|
|
continue;
|
|
}
|
|
|
|
plugin.configs[configName] = cloneLegacySection(config);
|
|
plugin.configs[`flat/${configName}`] = cloneFlatSection(config);
|
|
}
|
|
|
|
module.exports = plugin;
|