diff --git a/lib/rules/id-match.js b/lib/rules/id-match.js index ed3cdfdd692..dd8dbae5547 100644 --- a/lib/rules/id-match.js +++ b/lib/rules/id-match.js @@ -5,13 +5,6 @@ "use strict"; -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - -const astUtils = require("./utils/ast-utils"); -const globals = require("globals"); - //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ @@ -83,23 +76,28 @@ module.exports = { const ALLOWED_PARENT_TYPES = new Set(["CallExpression", "NewExpression"]); const DECLARATION_TYPES = new Set(["FunctionDeclaration", "VariableDeclarator"]); const IMPORT_TYPES = new Set(["ImportSpecifier", "ImportNamespaceSpecifier", "ImportDefaultSpecifier"]); - const BUILT_IN_REFERENCES = new Set(Object.keys(globals.builtin)); /** - * Checks if a string matches the provided pattern and is not a global built-in reference + * Checks whether the given node represents a reference to a global variable that is not declared in the source code. + * These identifiers will be allowed, as it is assumed that user has no control over the names of external global variables. + * @param {ASTNode} node `Identifier` node to check. + * @returns {boolean} `true` if the node is a reference to a global variable. + */ + function isReferenceToGlobalVariable(node) { + const scope = context.getScope(); + const variable = scope.set.get(node.name); + + return variable && variable.defs.length === 0 && + variable.references.some(ref => ref.identifier === node); + } + + /** + * Checks if a string matches the provided pattern and is not a global reference * @param {string} name The string to check. * @returns {boolean} if the string is a match * @private */ function isInvalid(name) { - const scope = context.getScope(); - const variable = astUtils.getVariableByName(scope, name); - - // Do not report global built-in references - if (variable && variable.scope.type === "global" && BUILT_IN_REFERENCES.has(name)) { - return false; - } - return !regexp.test(name); } @@ -176,6 +174,10 @@ module.exports = { parent = node.parent, effectiveParent = (parent.type === "MemberExpression") ? parent.parent : parent; + if (isReferenceToGlobalVariable(node)) { + return; + } + if (parent.type === "MemberExpression") { if (!checkProperties) { @@ -265,6 +267,10 @@ module.exports = { const isClassField = node.parent.type === "PropertyDefinition"; + if (isReferenceToGlobalVariable(node)) { + return; + } + if (isClassField && !checkClassFields) { return; } diff --git a/tests/lib/rules/id-match.js b/tests/lib/rules/id-match.js index 1f812fbe666..7afcd4c2e46 100644 --- a/tests/lib/rules/id-match.js +++ b/tests/lib/rules/id-match.js @@ -185,7 +185,7 @@ ruleTester.run("id-match", rule, { }] }, - // Should not report for global references that are native objects - https://github.com/eslint/eslint/issues/15395 + // Should not report for global references - https://github.com/eslint/eslint/issues/15395 { code: ` var foo = Object.keys(bar); @@ -664,6 +664,7 @@ ruleTester.run("id-match", rule, { let d = Array.from(b); let e = (Object) => Object.keys(obj, prop); // not global Object let f = (Array) => Array.from(obj, prop); // not global Array + foo.Array = 5; // not global Array `, options: ["^\\$?[a-z]+([A-Z0-9][a-z0-9]+)*$", { properties: true @@ -682,6 +683,8 @@ ruleTester.run("id-match", rule, { line: 3, column: 19 }, + + // let e = (Object) => Object.keys(obj, prop) { message: "Identifier 'Object' does not match the pattern '^\\$?[a-z]+([A-Z0-9][a-z0-9]+)*$'.", type: "Identifier", @@ -694,6 +697,8 @@ ruleTester.run("id-match", rule, { line: 9, column: 33 }, + + // let f =(Array) => Array.from(obj, prop); { message: "Identifier 'Array' does not match the pattern '^\\$?[a-z]+([A-Z0-9][a-z0-9]+)*$'.", type: "Identifier", @@ -705,6 +710,14 @@ ruleTester.run("id-match", rule, { type: "Identifier", line: 10, column: 32 + }, + + // foo.Array = 5; + { + message: "Identifier 'Array' does not match the pattern '^\\$?[a-z]+([A-Z0-9][a-z0-9]+)*$'.", + type: "Identifier", + line: 11, + column: 17 } ] },