Skip to content

Commit

Permalink
fix: do not report global references in id-match rule (#15420)
Browse files Browse the repository at this point in the history
* fix: do not report global built-in references in `id-match` rule

Fixes #15395

* test: add more cases

* refactor: code

* fix: do not report global references

* fix: use the global scope

* refactor: move scope call to `Program`
  • Loading branch information
snitin315 committed Dec 15, 2021
1 parent 3928175 commit 981fb48
Show file tree
Hide file tree
Showing 2 changed files with 106 additions and 0 deletions.
23 changes: 23 additions & 0 deletions lib/rules/id-match.js
Expand Up @@ -67,6 +67,8 @@ module.exports = {
onlyDeclarations = !!options.onlyDeclarations,
ignoreDestructuring = !!options.ignoreDestructuring;

let globalScope;

//--------------------------------------------------------------------------
// Helpers
//--------------------------------------------------------------------------
Expand All @@ -77,6 +79,19 @@ module.exports = {
const DECLARATION_TYPES = new Set(["FunctionDeclaration", "VariableDeclarator"]);
const IMPORT_TYPES = new Set(["ImportSpecifier", "ImportNamespaceSpecifier", "ImportDefaultSpecifier"]);

/**
* 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 variable = globalScope.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
* @param {string} name The string to check.
Expand Down Expand Up @@ -155,11 +170,19 @@ module.exports = {

return {

Program() {
globalScope = context.getScope();
},

Identifier(node) {
const name = node.name,
parent = node.parent,
effectiveParent = (parent.type === "MemberExpression") ? parent.parent : parent;

if (isReferenceToGlobalVariable(node)) {
return;
}

if (parent.type === "MemberExpression") {

if (!checkProperties) {
Expand Down
83 changes: 83 additions & 0 deletions tests/lib/rules/id-match.js
Expand Up @@ -185,6 +185,19 @@ ruleTester.run("id-match", rule, {
}]
},

// Should not report for global references - https://github.com/eslint/eslint/issues/15395
{
code: `
const foo = Object.keys(bar);
const a = Array.from(b);
const bar = () => Array;
`,
options: ["^\\$?[a-z]+([A-Z0-9][a-z0-9]+)*$", {
properties: true
}],
parserOptions: { ecmaVersion: 2022 }
},

// Class Methods
{
code: "class x { foo() {} }",
Expand Down Expand Up @@ -641,6 +654,76 @@ ruleTester.run("id-match", rule, {
]
},

// https://github.com/eslint/eslint/issues/15395
{
code: `
const foo_variable = 1;
class MyClass {
}
let a = new MyClass();
let b = {id: 1};
let c = Object.keys(b);
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
}],
parserOptions: { ecmaVersion: 6 },
errors: [
{
message: "Identifier 'foo_variable' does not match the pattern '^\\$?[a-z]+([A-Z0-9][a-z0-9]+)*$'.",
type: "Identifier",
line: 2,
column: 19
},
{
message: "Identifier 'MyClass' does not match the pattern '^\\$?[a-z]+([A-Z0-9][a-z0-9]+)*$'.",
type: "Identifier",
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",
line: 9,
column: 22
},
{
message: "Identifier 'Object' does not match the pattern '^\\$?[a-z]+([A-Z0-9][a-z0-9]+)*$'.",
type: "Identifier",
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",
line: 10,
column: 22
},
{
message: "Identifier 'Array' does not match the pattern '^\\$?[a-z]+([A-Z0-9][a-z0-9]+)*$'.",
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
}
]
},

// Class Methods
{
code: "class x { _foo() {} }",
Expand Down

0 comments on commit 981fb48

Please sign in to comment.