summaryrefslogtreecommitdiffstats
path: root/tools/lint/eslint/eslint-plugin-mozilla/lib/rules
diff options
context:
space:
mode:
Diffstat (limited to 'tools/lint/eslint/eslint-plugin-mozilla/lib/rules')
-rw-r--r--tools/lint/eslint/eslint-plugin-mozilla/lib/rules/.eslintrc.js51
-rw-r--r--tools/lint/eslint/eslint-plugin-mozilla/lib/rules/balanced-listeners.js113
-rw-r--r--tools/lint/eslint/eslint-plugin-mozilla/lib/rules/import-browserjs-globals.js83
-rw-r--r--tools/lint/eslint/eslint-plugin-mozilla/lib/rules/import-globals.js15
-rw-r--r--tools/lint/eslint/eslint-plugin-mozilla/lib/rules/import-headjs-globals.js49
-rw-r--r--tools/lint/eslint/eslint-plugin-mozilla/lib/rules/mark-test-function-used.js37
-rw-r--r--tools/lint/eslint/eslint-plugin-mozilla/lib/rules/no-aArgs.js55
-rw-r--r--tools/lint/eslint/eslint-plugin-mozilla/lib/rules/no-cpows-in-tests.js112
-rw-r--r--tools/lint/eslint/eslint-plugin-mozilla/lib/rules/no-single-arg-cu-import.js39
-rw-r--r--tools/lint/eslint/eslint-plugin-mozilla/lib/rules/reject-importGlobalProperties.js37
-rw-r--r--tools/lint/eslint/eslint-plugin-mozilla/lib/rules/reject-some-requires.js48
-rw-r--r--tools/lint/eslint/eslint-plugin-mozilla/lib/rules/var-only-at-top-level.js34
12 files changed, 673 insertions, 0 deletions
diff --git a/tools/lint/eslint/eslint-plugin-mozilla/lib/rules/.eslintrc.js b/tools/lint/eslint/eslint-plugin-mozilla/lib/rules/.eslintrc.js
new file mode 100644
index 000000000..505a3ea82
--- /dev/null
+++ b/tools/lint/eslint/eslint-plugin-mozilla/lib/rules/.eslintrc.js
@@ -0,0 +1,51 @@
+"use strict";
+
+/**
+ * Based on npm coding standards at https://docs.npmjs.com/misc/coding-style.
+ *
+ * The places we differ from the npm coding style:
+ * - Commas should be at the end of a line.
+ * - Always use semicolons.
+ * - Functions should not have whitespace before params.
+ */
+
+module.exports = {
+ "env": {
+ "node": true
+ },
+
+ "rules": {
+ "brace-style": ["error", "1tbs"],
+ "camelcase": "error",
+ "comma-dangle": ["error", "never"],
+ "comma-spacing": "error",
+ "comma-style": ["error", "last"],
+ "curly": ["error", "multi-line"],
+ "handle-callback-err": ["error", "er"],
+ "indent": ["error", 2, {"SwitchCase": 1}],
+ "max-len": ["error", 80, "error"],
+ "no-multiple-empty-lines": ["error", {"max": 1}],
+ "no-undef": "error",
+ "no-undef-init": "error",
+ "no-unexpected-multiline": "error",
+ "object-curly-spacing": "off",
+ "one-var": ["error", "never"],
+ "operator-linebreak": ["error", "after"],
+ "semi": ["error", "always"],
+ "space-before-blocks": "error",
+ "space-before-function-paren": ["error", "never"],
+ "keyword-spacing": "error",
+ "strict": ["error", "global"],
+ },
+
+ // Globals accessible within node modules.
+ "globals": {
+ "DTRACE_HTTP_CLIENT_REQUEST": true,
+ "DTRACE_HTTP_CLIENT_RESPONSE": true,
+ "DTRACE_HTTP_SERVER_REQUEST": true,
+ "DTRACE_HTTP_SERVER_RESPONSE": true,
+ "DTRACE_NET_SERVER_CONNECTION": true,
+ "DTRACE_NET_STREAM_END": true,
+ "Intl": true,
+ },
+};
diff --git a/tools/lint/eslint/eslint-plugin-mozilla/lib/rules/balanced-listeners.js b/tools/lint/eslint/eslint-plugin-mozilla/lib/rules/balanced-listeners.js
new file mode 100644
index 000000000..c658a6b44
--- /dev/null
+++ b/tools/lint/eslint/eslint-plugin-mozilla/lib/rules/balanced-listeners.js
@@ -0,0 +1,113 @@
+/**
+ * @fileoverview Check that there's a removeEventListener for each
+ * addEventListener and an off for each on.
+ * Note that for now, this rule is rather simple in that it only checks that
+ * for each event name there is both an add and remove listener. It doesn't
+ * check that these are called on the right objects or with the same callback.
+ *
+ * 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";
+
+// -----------------------------------------------------------------------------
+// Rule Definition
+// -----------------------------------------------------------------------------
+
+module.exports = function(context) {
+ // ---------------------------------------------------------------------------
+ // Helpers
+ // ---------------------------------------------------------------------------
+
+ var DICTIONARY = {
+ "addEventListener": "removeEventListener",
+ "on": "off"
+ };
+ // Invert this dictionary to make it easy later.
+ var INVERTED_DICTIONARY = {};
+ for (var i in DICTIONARY) {
+ INVERTED_DICTIONARY[DICTIONARY[i]] = i;
+ }
+
+ // Collect the add/remove listeners in these 2 arrays.
+ var addedListeners = [];
+ var removedListeners = [];
+
+ function addAddedListener(node) {
+ addedListeners.push({
+ functionName: node.callee.property.name,
+ type: node.arguments[0].value,
+ node: node.callee.property,
+ useCapture: node.arguments[2] ? node.arguments[2].value : null
+ });
+ }
+
+ function addRemovedListener(node) {
+ removedListeners.push({
+ functionName: node.callee.property.name,
+ type: node.arguments[0].value,
+ useCapture: node.arguments[2] ? node.arguments[2].value : null
+ });
+ }
+
+ function getUnbalancedListeners() {
+ var unbalanced = [];
+
+ for (var j = 0; j < addedListeners.length; j++) {
+ if (!hasRemovedListener(addedListeners[j])) {
+ unbalanced.push(addedListeners[j]);
+ }
+ }
+ addedListeners = removedListeners = [];
+
+ return unbalanced;
+ }
+
+ function hasRemovedListener(addedListener) {
+ for (var k = 0; k < removedListeners.length; k++) {
+ var listener = removedListeners[k];
+ if (DICTIONARY[addedListener.functionName] === listener.functionName &&
+ addedListener.type === listener.type &&
+ addedListener.useCapture === listener.useCapture) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ // ---------------------------------------------------------------------------
+ // Public
+ // ---------------------------------------------------------------------------
+
+ return {
+ CallExpression: function(node) {
+ if (node.arguments.length === 0) {
+ return;
+ }
+
+ if (node.callee.type === "MemberExpression") {
+ var listenerMethodName = node.callee.property.name;
+
+ if (DICTIONARY.hasOwnProperty(listenerMethodName)) {
+ addAddedListener(node);
+ } else if (INVERTED_DICTIONARY.hasOwnProperty(listenerMethodName)) {
+ addRemovedListener(node);
+ }
+ }
+ },
+
+ "Program:exit": function() {
+ getUnbalancedListeners().forEach(function(listener) {
+ context.report(listener.node,
+ "No corresponding '{{functionName}}({{type}})' was found.",
+ {
+ functionName: DICTIONARY[listener.functionName],
+ type: listener.type
+ });
+ });
+ }
+ };
+};
diff --git a/tools/lint/eslint/eslint-plugin-mozilla/lib/rules/import-browserjs-globals.js b/tools/lint/eslint/eslint-plugin-mozilla/lib/rules/import-browserjs-globals.js
new file mode 100644
index 000000000..313af2d71
--- /dev/null
+++ b/tools/lint/eslint/eslint-plugin-mozilla/lib/rules/import-browserjs-globals.js
@@ -0,0 +1,83 @@
+/**
+ * @fileoverview Import globals from browser.js.
+ *
+ * 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";
+
+// -----------------------------------------------------------------------------
+// Rule Definition
+// -----------------------------------------------------------------------------
+
+var fs = require("fs");
+var path = require("path");
+var helpers = require("../helpers");
+var globals = require("../globals");
+
+const SCRIPTS = [
+ //"browser/base/content/nsContextMenu.js",
+ "toolkit/content/contentAreaUtils.js",
+ "browser/components/places/content/editBookmarkOverlay.js",
+ "toolkit/components/printing/content/printUtils.js",
+ "toolkit/content/viewZoomOverlay.js",
+ "browser/components/places/content/browserPlacesViews.js",
+ "browser/base/content/browser.js",
+ "browser/components/downloads/content/downloads.js",
+ "browser/components/downloads/content/indicator.js",
+ "browser/components/customizableui/content/panelUI.js",
+ "toolkit/components/viewsource/content/viewSourceUtils.js",
+ "browser/base/content/browser-addons.js",
+ "browser/base/content/browser-ctrlTab.js",
+ "browser/base/content/browser-customization.js",
+ "browser/base/content/browser-devedition.js",
+ "browser/base/content/browser-feeds.js",
+ "browser/base/content/browser-fullScreenAndPointerLock.js",
+ "browser/base/content/browser-fullZoom.js",
+ "browser/base/content/browser-gestureSupport.js",
+ "browser/base/content/browser-media.js",
+ "browser/base/content/browser-places.js",
+ "browser/base/content/browser-plugins.js",
+ "browser/base/content/browser-refreshblocker.js",
+ "browser/base/content/browser-safebrowsing.js",
+ "browser/base/content/browser-sidebar.js",
+ "browser/base/content/browser-social.js",
+ "browser/base/content/browser-syncui.js",
+ "browser/base/content/browser-tabsintitlebar.js",
+ "browser/base/content/browser-thumbnails.js",
+ "browser/base/content/browser-trackingprotection.js",
+ "browser/base/content/browser-data-submission-info-bar.js",
+ "browser/base/content/browser-fxaccounts.js"
+];
+
+module.exports = function(context) {
+ return {
+ Program: function(node) {
+ if (helpers.getTestType(this) != "browser" &&
+ !helpers.getIsHeadFile(this)) {
+ return;
+ }
+
+ let filepath = helpers.getAbsoluteFilePath(context);
+ let root = helpers.getRootDir(filepath);
+ for (let script of SCRIPTS) {
+ let fileName = path.join(root, script);
+ try {
+ let newGlobals = globals.getGlobalsForFile(fileName);
+ helpers.addGlobals(newGlobals, context.getScope());
+ } catch (e) {
+ context.report(
+ node,
+ "Could not load globals from file {{filePath}}: {{error}}",
+ {
+ filePath: path.relative(root, fileName),
+ error: e
+ }
+ );
+ }
+ }
+ }
+ };
+};
diff --git a/tools/lint/eslint/eslint-plugin-mozilla/lib/rules/import-globals.js b/tools/lint/eslint/eslint-plugin-mozilla/lib/rules/import-globals.js
new file mode 100644
index 000000000..053a9e702
--- /dev/null
+++ b/tools/lint/eslint/eslint-plugin-mozilla/lib/rules/import-globals.js
@@ -0,0 +1,15 @@
+/**
+ * @fileoverview Discovers all globals for the current file.
+ *
+ * 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";
+
+// -----------------------------------------------------------------------------
+// Rule Definition
+// -----------------------------------------------------------------------------
+
+module.exports = require("../globals").getESLintGlobalParser;
diff --git a/tools/lint/eslint/eslint-plugin-mozilla/lib/rules/import-headjs-globals.js b/tools/lint/eslint/eslint-plugin-mozilla/lib/rules/import-headjs-globals.js
new file mode 100644
index 000000000..783642f58
--- /dev/null
+++ b/tools/lint/eslint/eslint-plugin-mozilla/lib/rules/import-headjs-globals.js
@@ -0,0 +1,49 @@
+/**
+ * @fileoverview Import globals from head.js and from any files that were
+ * imported by head.js (as far as we can correctly resolve the path).
+ *
+ * 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";
+
+// -----------------------------------------------------------------------------
+// Rule Definition
+// -----------------------------------------------------------------------------
+
+var fs = require("fs");
+var path = require("path");
+var helpers = require("../helpers");
+var globals = require("../globals");
+
+module.exports = function(context) {
+
+ function importHead(path, node) {
+ try {
+ let stats = fs.statSync(path);
+ if (!stats.isFile()) {
+ return;
+ }
+ } catch (e) {
+ return;
+ }
+
+ let newGlobals = globals.getGlobalsForFile(path);
+ helpers.addGlobals(newGlobals, context.getScope());
+ }
+
+ // ---------------------------------------------------------------------------
+ // Public
+ // ---------------------------------------------------------------------------
+
+ return {
+ Program: function(node) {
+ let heads = helpers.getTestHeadFiles(this);
+ for (let head of heads) {
+ importHead(head, node);
+ }
+ }
+ };
+};
diff --git a/tools/lint/eslint/eslint-plugin-mozilla/lib/rules/mark-test-function-used.js b/tools/lint/eslint/eslint-plugin-mozilla/lib/rules/mark-test-function-used.js
new file mode 100644
index 000000000..b2e8ec294
--- /dev/null
+++ b/tools/lint/eslint/eslint-plugin-mozilla/lib/rules/mark-test-function-used.js
@@ -0,0 +1,37 @@
+/**
+ * @fileoverview Simply marks `test` (the test method) or `run_test` as used when
+ * in mochitests or xpcshell tests respectively. This avoids ESLint telling us
+ * that the function is never called.
+ *
+ * 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";
+
+// -----------------------------------------------------------------------------
+// Rule Definition
+// -----------------------------------------------------------------------------
+
+var helpers = require("../helpers");
+
+module.exports = function(context) {
+ // ---------------------------------------------------------------------------
+ // Public
+ // ---------------------------------------------------------------------------
+
+ return {
+ Program: function() {
+ if (helpers.getTestType(this) == "browser") {
+ context.markVariableAsUsed("test");
+ return;
+ }
+
+ if (helpers.getTestType(this) == "xpcshell") {
+ context.markVariableAsUsed("run_test");
+ return;
+ }
+ }
+ };
+};
diff --git a/tools/lint/eslint/eslint-plugin-mozilla/lib/rules/no-aArgs.js b/tools/lint/eslint/eslint-plugin-mozilla/lib/rules/no-aArgs.js
new file mode 100644
index 000000000..267f6836f
--- /dev/null
+++ b/tools/lint/eslint/eslint-plugin-mozilla/lib/rules/no-aArgs.js
@@ -0,0 +1,55 @@
+/**
+ * @fileoverview warns against using hungarian notation in function arguments
+ * (i.e. aArg).
+ *
+ * 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";
+
+// -----------------------------------------------------------------------------
+// Rule Definition
+// -----------------------------------------------------------------------------
+
+module.exports = function(context) {
+ // ---------------------------------------------------------------------------
+ // Helpers
+ // ---------------------------------------------------------------------------
+
+ function isPrefixed(name) {
+ return name.length >= 2 && /^a[A-Z]/.test(name);
+ }
+
+ function deHungarianize(name) {
+ return name.substring(1, 2).toLowerCase() +
+ name.substring(2, name.length);
+ }
+
+ function checkFunction(node) {
+ for (var i = 0; i < node.params.length; i++) {
+ var param = node.params[i];
+ if (param.name && isPrefixed(param.name)) {
+ var errorObj = {
+ name: param.name,
+ suggestion: deHungarianize(param.name)
+ };
+ context.report(param,
+ "Parameter '{{name}}' uses Hungarian Notation, " +
+ "consider using '{{suggestion}}' instead.",
+ errorObj);
+ }
+ }
+ }
+
+ // ---------------------------------------------------------------------------
+ // Public
+ // ---------------------------------------------------------------------------
+
+ return {
+ "FunctionDeclaration": checkFunction,
+ "ArrowFunctionExpression": checkFunction,
+ "FunctionExpression": checkFunction
+ };
+};
diff --git a/tools/lint/eslint/eslint-plugin-mozilla/lib/rules/no-cpows-in-tests.js b/tools/lint/eslint/eslint-plugin-mozilla/lib/rules/no-cpows-in-tests.js
new file mode 100644
index 000000000..415cb2fc9
--- /dev/null
+++ b/tools/lint/eslint/eslint-plugin-mozilla/lib/rules/no-cpows-in-tests.js
@@ -0,0 +1,112 @@
+/**
+ * @fileoverview Prevent access to CPOWs in browser mochitests.
+ *
+ * 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";
+
+// -----------------------------------------------------------------------------
+// Rule Definition
+// -----------------------------------------------------------------------------
+
+var helpers = require("../helpers");
+
+var cpows = [
+ /^gBrowser\.contentWindow/,
+ /^gBrowser\.contentDocument/,
+ /^gBrowser\.selectedBrowser.contentWindow/,
+ /^browser\.contentDocument/,
+ /^window\.content/
+];
+
+var isInContentTask = false;
+
+module.exports = function(context) {
+ // ---------------------------------------------------------------------------
+ // Helpers
+ // ---------------------------------------------------------------------------
+
+ function showError(node, identifier) {
+ if (isInContentTask) {
+ return;
+ }
+
+ context.report({
+ node: node,
+ message: identifier +
+ " is a possible Cross Process Object Wrapper (CPOW)."
+ });
+ }
+
+ function isContentTask(node) {
+ return node &&
+ node.type === "MemberExpression" &&
+ node.property.type === "Identifier" &&
+ node.property.name === "spawn" &&
+ node.object.type === "Identifier" &&
+ node.object.name === "ContentTask";
+ }
+
+ // ---------------------------------------------------------------------------
+ // Public
+ // ---------------------------------------------------------------------------
+
+ return {
+ CallExpression: function(node) {
+ if (isContentTask(node.callee)) {
+ isInContentTask = true;
+ }
+ },
+
+ "CallExpression:exit": function(node) {
+ if (isContentTask(node.callee)) {
+ isInContentTask = false;
+ }
+ },
+
+ MemberExpression: function(node) {
+ if (helpers.getTestType(this) != "browser") {
+ return;
+ }
+
+ var expression = context.getSource(node);
+
+ // Only report a single CPOW error per node -- so if checking
+ // |cpows| reports one, don't report another below.
+ var someCpowFound = cpows.some(function(cpow) {
+ if (cpow.test(expression)) {
+ showError(node, expression);
+ return true;
+ }
+ return false;
+ });
+ if (!someCpowFound && helpers.getIsGlobalScope(context.getAncestors())) {
+ if (/^content\./.test(expression)) {
+ showError(node, expression);
+ return;
+ }
+ }
+ },
+
+ Identifier: function(node) {
+ if (helpers.getTestType(this) != "browser") {
+ return;
+ }
+
+ var expression = context.getSource(node);
+ if (expression == "content" || /^content\./.test(expression)) {
+ if (node.parent.type === "MemberExpression" &&
+ node.parent.object &&
+ node.parent.object.type === "Identifier" &&
+ node.parent.object.name != "content") {
+ return;
+ }
+ showError(node, expression);
+ return;
+ }
+ }
+ };
+};
diff --git a/tools/lint/eslint/eslint-plugin-mozilla/lib/rules/no-single-arg-cu-import.js b/tools/lint/eslint/eslint-plugin-mozilla/lib/rules/no-single-arg-cu-import.js
new file mode 100644
index 000000000..b295f3555
--- /dev/null
+++ b/tools/lint/eslint/eslint-plugin-mozilla/lib/rules/no-single-arg-cu-import.js
@@ -0,0 +1,39 @@
+/**
+ * @fileoverview Reject use of single argument Cu.import
+ *
+ * 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";
+
+// -----------------------------------------------------------------------------
+// Rule Definition
+// -----------------------------------------------------------------------------
+
+var helpers = require("../helpers");
+
+module.exports = function(context) {
+
+ // ---------------------------------------------------------------------------
+ // Public
+ // --------------------------------------------------------------------------
+
+ return {
+ "CallExpression": function(node) {
+ if (node.callee.type === "MemberExpression") {
+ let memexp = node.callee;
+ if (memexp.object.type === "Identifier" &&
+ // Only Cu, not Components.utils; see bug 1230369.
+ memexp.object.name === "Cu" &&
+ memexp.property.type === "Identifier" &&
+ memexp.property.name === "import" &&
+ node.arguments.length === 1) {
+ context.report(node, "Single argument Cu.import exposes new " +
+ "globals to all modules");
+ }
+ }
+ }
+ };
+};
diff --git a/tools/lint/eslint/eslint-plugin-mozilla/lib/rules/reject-importGlobalProperties.js b/tools/lint/eslint/eslint-plugin-mozilla/lib/rules/reject-importGlobalProperties.js
new file mode 100644
index 000000000..0661c91d4
--- /dev/null
+++ b/tools/lint/eslint/eslint-plugin-mozilla/lib/rules/reject-importGlobalProperties.js
@@ -0,0 +1,37 @@
+/**
+ * @fileoverview Reject use of Cu.importGlobalProperties
+ *
+ * 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";
+
+// -----------------------------------------------------------------------------
+// Rule Definition
+// -----------------------------------------------------------------------------
+
+var helpers = require("../helpers");
+
+module.exports = function(context) {
+
+ // ---------------------------------------------------------------------------
+ // Public
+ // --------------------------------------------------------------------------
+
+ return {
+ "CallExpression": function(node) {
+ if (node.callee.type === "MemberExpression") {
+ let memexp = node.callee;
+ if (memexp.object.type === "Identifier" &&
+ // Only Cu, not Components.utils; see bug 1230369.
+ memexp.object.name === "Cu" &&
+ memexp.property.type === "Identifier" &&
+ memexp.property.name === "importGlobalProperties") {
+ context.report(node, "Unexpected call to Cu.importGlobalProperties");
+ }
+ }
+ }
+ };
+};
diff --git a/tools/lint/eslint/eslint-plugin-mozilla/lib/rules/reject-some-requires.js b/tools/lint/eslint/eslint-plugin-mozilla/lib/rules/reject-some-requires.js
new file mode 100644
index 000000000..746f98a1f
--- /dev/null
+++ b/tools/lint/eslint/eslint-plugin-mozilla/lib/rules/reject-some-requires.js
@@ -0,0 +1,48 @@
+/**
+ * @fileoverview Reject some uses of require.
+ *
+ * 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";
+
+// -----------------------------------------------------------------------------
+// Rule Definition
+// -----------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+ // ---------------------------------------------------------------------------
+ // Public
+ // --------------------------------------------------------------------------
+
+ if (typeof(context.options[0]) !== "string") {
+ throw new Error("reject-some-requires expects a regexp");
+ }
+ const RX = new RegExp(context.options[0]);
+
+ const checkPath = function(node, path) {
+ if (RX.test(path)) {
+ context.report(node, `require(${path}) is not allowed`);
+ }
+ };
+
+ return {
+ "CallExpression": function(node) {
+ if (node.callee.type == "Identifier" &&
+ node.callee.name == "require" &&
+ node.arguments.length == 1 &&
+ node.arguments[0].type == "Literal") {
+ checkPath(node, node.arguments[0].value);
+ } else if (node.callee.type == "MemberExpression" &&
+ node.callee.property.type == "Identifier" &&
+ node.callee.property.name == "lazyRequireGetter" &&
+ node.arguments.length >= 3 &&
+ node.arguments[2].type == "Literal") {
+ checkPath(node, node.arguments[2].value);
+ }
+ }
+ };
+};
diff --git a/tools/lint/eslint/eslint-plugin-mozilla/lib/rules/var-only-at-top-level.js b/tools/lint/eslint/eslint-plugin-mozilla/lib/rules/var-only-at-top-level.js
new file mode 100644
index 000000000..a1e14e166
--- /dev/null
+++ b/tools/lint/eslint/eslint-plugin-mozilla/lib/rules/var-only-at-top-level.js
@@ -0,0 +1,34 @@
+/**
+ * @fileoverview Marks all var declarations that are not at the top level
+ * invalid.
+ *
+ * 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";
+
+// -----------------------------------------------------------------------------
+// Rule Definition
+// -----------------------------------------------------------------------------
+
+var helpers = require("../helpers");
+
+module.exports = function(context) {
+ // ---------------------------------------------------------------------------
+ // Public
+ // --------------------------------------------------------------------------
+
+ return {
+ "VariableDeclaration": function(node) {
+ if (node.kind === "var") {
+ if (helpers.getIsGlobalScope(context.getAncestors())) {
+ return;
+ }
+
+ context.report(node, "Unexpected var, use let or const instead.");
+ }
+ }
+ };
+};