Bug 1430923 - Handle EXPORTED_SYMBOLS in ESLint to help define globals in jsm files, and disallow 'let EXPORTED_SYMBOLS = '. r=mossop

MozReview-Commit-ID: 5abfpM8EAEL

--HG--
extra : rebase_source : b266018a3754459aa8628217232f86e1a56c00b7
This commit is contained in:
Mark Banner 2018-01-16 23:07:25 +00:00
Родитель db162e24be
Коммит bc030d501e
6 изменённых файлов: 124 добавлений и 3 удалений

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

@ -68,7 +68,15 @@ module.exports = {
"browser": false,
"mozilla/jsm": true
},
"files": "**/*.jsm"
"files": "**/*.jsm",
"rules": {
"mozilla/mark-exported-symbols-as-used": "error"
// "no-unused-vars": ["error", {
// "args": "none",
// "vars": "all",
// "varsIgnorePattern": "^Cc|Ci|Cu|Cr|EXPORTED_SYMBOLS"
// }]
}
}],
"parserOptions": {

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

@ -40,6 +40,7 @@ module.exports = {
require("../lib/rules/import-content-task-globals"),
"import-globals": require("../lib/rules/import-globals"),
"import-headjs-globals": require("../lib/rules/import-headjs-globals"),
"mark-exported-symbols-as-used": require("../lib/rules/mark-exported-symbols-as-used"),
"mark-test-function-used": require("../lib/rules/mark-test-function-used"),
"no-aArgs": require("../lib/rules/no-aArgs"),
"no-arbitrary-setTimeout": require("../lib/rules/no-arbitrary-setTimeout"),

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

@ -0,0 +1,76 @@
/**
* @fileoverview Simply marks exported symbols as used. Designed for use in
* .jsm files only.
*
* 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 markArrayElementsAsUsed(context, node, expression) {
if (expression.type != "ArrayExpression") {
context.report({
node,
message: "Unexpected assignment of non-Array to EXPORTED_SYMBOLS"
});
return;
}
for (let element of expression.elements) {
context.markVariableAsUsed(element.value);
}
}
// -----------------------------------------------------------------------------
// Rule Definition
// -----------------------------------------------------------------------------
module.exports = function(context) {
// Ignore assignments not in the global scope, e.g. where special module
// definitions are required due to having different ways of importing files,
// e.g. osfile.
function isGlobalScope() {
return !context.getScope().upper;
}
// ---------------------------------------------------------------------------
// Public
// ---------------------------------------------------------------------------
return {
AssignmentExpression(node, parents) {
if (node.operator === "=" &&
node.left.type === "MemberExpression" &&
node.left.object.type === "ThisExpression" &&
node.left.property.name === "EXPORTED_SYMBOLS" &&
isGlobalScope()) {
markArrayElementsAsUsed(context, node, node.right);
}
},
VariableDeclaration(node, parents) {
if (!isGlobalScope()) {
return;
}
for (let item of node.declarations) {
if (item.id &&
item.id.type == "Identifier" &&
item.id.name === "EXPORTED_SYMBOLS") {
if (node.kind === "let") {
// The use of 'let' isn't allowed as the lexical scope may die after
// the script executes.
context.report({
node,
message: "EXPORTED_SYMBOLS cannot be declared via `let`. Use `var` or `this.EXPORTED_SYMBOLS =`"
});
}
markArrayElementsAsUsed(context, node, item.init);
}
}
}
};
};

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

@ -1,6 +1,6 @@
{
"name": "eslint-plugin-mozilla",
"version": "0.5.0",
"version": "0.6.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {

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

@ -1,6 +1,6 @@
{
"name": "eslint-plugin-mozilla",
"version": "0.5.0",
"version": "0.6.0",
"description": "A collection of rules that help enforce JavaScript coding standard in the Mozilla project.",
"keywords": [
"eslint",

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

@ -0,0 +1,36 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// ------------------------------------------------------------------------------
// Requirements
// ------------------------------------------------------------------------------
var rule = require("../lib/rules/mark-exported-symbols-as-used");
var RuleTester = require("eslint/lib/testers/rule-tester");
const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 6 } });
// ------------------------------------------------------------------------------
// Tests
// ------------------------------------------------------------------------------
function invalidCode(code, type, message) {
return {code, errors: [{message, type}]};
}
ruleTester.run("mark-exported-symbols-as-used", rule, {
valid: [
"var EXPORTED_SYMBOLS = ['foo'];",
"this.EXPORTED_SYMBOLS = ['foo'];"
],
invalid: [
invalidCode("let EXPORTED_SYMBOLS = ['foo'];", "VariableDeclaration",
"EXPORTED_SYMBOLS cannot be declared via `let`. Use `var` or `this.EXPORTED_SYMBOLS =`"),
invalidCode("var EXPORTED_SYMBOLS = 'foo';", "VariableDeclaration",
"Unexpected assignment of non-Array to EXPORTED_SYMBOLS"),
invalidCode("this.EXPORTED_SYMBOLS = 'foo';", "AssignmentExpression",
"Unexpected assignment of non-Array to EXPORTED_SYMBOLS")
]
});