Skip to content

Commit

Permalink
feat: check imports and class names in no-shadow-restricted-names (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
mdjermanovic authored Dec 27, 2024
1 parent 5db226f commit 87a9352
Show file tree
Hide file tree
Showing 3 changed files with 147 additions and 48 deletions.
24 changes: 24 additions & 0 deletions docs/src/rules/no-shadow-restricted-names.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,20 @@ try {} catch(eval){}

:::

::: incorrect

```js
/*eslint no-shadow-restricted-names: "error"*/

import NaN from "foo";

import { undefined } from "bar";

class Infinity {}
```

:::

Examples of **correct** code for this rule:

::: correct { "sourceType": "script" }
Expand All @@ -54,3 +68,13 @@ var undefined;
```

:::

::: correct

```js
/*eslint no-shadow-restricted-names: "error"*/

import { undefined as undef } from "bar";
```

:::
24 changes: 17 additions & 7 deletions lib/rules/no-shadow-restricted-names.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,17 +45,27 @@ module.exports = {
const RESTRICTED = new Set(["undefined", "NaN", "Infinity", "arguments", "eval"]);
const sourceCode = context.sourceCode;

// Track reported nodes to avoid duplicate reports. For example, on class declarations.
const reportedNodes = new Set();

return {
"VariableDeclaration, :function, CatchClause"(node) {
"VariableDeclaration, :function, CatchClause, ImportDeclaration, ClassDeclaration, ClassExpression"(node) {
for (const variable of sourceCode.getDeclaredVariables(node)) {
if (variable.defs.length > 0 && RESTRICTED.has(variable.name) && !safelyShadowsUndefined(variable)) {
context.report({
node: variable.defs[0].name,
messageId: "shadowingRestrictedName",
data: {
name: variable.name
for (const def of variable.defs) {
const nodeToReport = def.name;

if (!reportedNodes.has(nodeToReport)) {
reportedNodes.add(nodeToReport);
context.report({
node: nodeToReport,
messageId: "shadowingRestrictedName",
data: {
name: variable.name
}
});
}
});
}
}
}
}
Expand Down
147 changes: 106 additions & 41 deletions tests/lib/rules/no-shadow-restricted-names.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,96 +40,161 @@ ruleTester.run("no-shadow-restricted-names", rule, {
{
code: "let undefined",
languageOptions: { ecmaVersion: 2015 }
},
{
code: "import { undefined as undef } from 'foo';",
languageOptions: {
sourceType: "module",
ecmaVersion: 2015
}
}
],
invalid: [
{
code: "function NaN(NaN) { var NaN; !function NaN(NaN) { try {} catch(NaN) {} }; }",
errors: [
{ messageId: "shadowingRestrictedName", data: { name: "NaN" }, type: "Identifier" },
{ messageId: "shadowingRestrictedName", data: { name: "NaN" }, type: "Identifier" },
{ messageId: "shadowingRestrictedName", data: { name: "NaN" }, type: "Identifier" },
{ messageId: "shadowingRestrictedName", data: { name: "NaN" }, type: "Identifier" },
{ messageId: "shadowingRestrictedName", data: { name: "NaN" }, type: "Identifier" },
{ messageId: "shadowingRestrictedName", data: { name: "NaN" }, type: "Identifier" }
{ messageId: "shadowingRestrictedName", data: { name: "NaN" }, type: "Identifier", column: 10 },
{ messageId: "shadowingRestrictedName", data: { name: "NaN" }, type: "Identifier", column: 14 },
{ messageId: "shadowingRestrictedName", data: { name: "NaN" }, type: "Identifier", column: 25 },
{ messageId: "shadowingRestrictedName", data: { name: "NaN" }, type: "Identifier", column: 40 },
{ messageId: "shadowingRestrictedName", data: { name: "NaN" }, type: "Identifier", column: 44 },
{ messageId: "shadowingRestrictedName", data: { name: "NaN" }, type: "Identifier", column: 64 }
]
},
{
code: "function undefined(undefined) { !function undefined(undefined) { try {} catch(undefined) {} }; }",
errors: [
{ messageId: "shadowingRestrictedName", data: { name: "undefined" }, type: "Identifier" },
{ messageId: "shadowingRestrictedName", data: { name: "undefined" }, type: "Identifier" },
{ messageId: "shadowingRestrictedName", data: { name: "undefined" }, type: "Identifier" },
{ messageId: "shadowingRestrictedName", data: { name: "undefined" }, type: "Identifier" },
{ messageId: "shadowingRestrictedName", data: { name: "undefined" }, type: "Identifier" }
{ messageId: "shadowingRestrictedName", data: { name: "undefined" }, type: "Identifier", column: 10 },
{ messageId: "shadowingRestrictedName", data: { name: "undefined" }, type: "Identifier", column: 20 },
{ messageId: "shadowingRestrictedName", data: { name: "undefined" }, type: "Identifier", column: 43 },
{ messageId: "shadowingRestrictedName", data: { name: "undefined" }, type: "Identifier", column: 53 },
{ messageId: "shadowingRestrictedName", data: { name: "undefined" }, type: "Identifier", column: 79 }
]
},
{
code: "function Infinity(Infinity) { var Infinity; !function Infinity(Infinity) { try {} catch(Infinity) {} }; }",
errors: [
{ messageId: "shadowingRestrictedName", data: { name: "Infinity" }, type: "Identifier" },
{ messageId: "shadowingRestrictedName", data: { name: "Infinity" }, type: "Identifier" },
{ messageId: "shadowingRestrictedName", data: { name: "Infinity" }, type: "Identifier" },
{ messageId: "shadowingRestrictedName", data: { name: "Infinity" }, type: "Identifier" },
{ messageId: "shadowingRestrictedName", data: { name: "Infinity" }, type: "Identifier" },
{ messageId: "shadowingRestrictedName", data: { name: "Infinity" }, type: "Identifier" }
{ messageId: "shadowingRestrictedName", data: { name: "Infinity" }, type: "Identifier", column: 10 },
{ messageId: "shadowingRestrictedName", data: { name: "Infinity" }, type: "Identifier", column: 19 },
{ messageId: "shadowingRestrictedName", data: { name: "Infinity" }, type: "Identifier", column: 35 },
{ messageId: "shadowingRestrictedName", data: { name: "Infinity" }, type: "Identifier", column: 55 },
{ messageId: "shadowingRestrictedName", data: { name: "Infinity" }, type: "Identifier", column: 64 },
{ messageId: "shadowingRestrictedName", data: { name: "Infinity" }, type: "Identifier", column: 89 }
]
},
{
code: "function arguments(arguments) { var arguments; !function arguments(arguments) { try {} catch(arguments) {} }; }",
errors: [
{ messageId: "shadowingRestrictedName", data: { name: "arguments" }, type: "Identifier" },
{ messageId: "shadowingRestrictedName", data: { name: "arguments" }, type: "Identifier" },
{ messageId: "shadowingRestrictedName", data: { name: "arguments" }, type: "Identifier" },
{ messageId: "shadowingRestrictedName", data: { name: "arguments" }, type: "Identifier" },
{ messageId: "shadowingRestrictedName", data: { name: "arguments" }, type: "Identifier" },
{ messageId: "shadowingRestrictedName", data: { name: "arguments" }, type: "Identifier" }
{ messageId: "shadowingRestrictedName", data: { name: "arguments" }, type: "Identifier", column: 10 },
{ messageId: "shadowingRestrictedName", data: { name: "arguments" }, type: "Identifier", column: 20 },
{ messageId: "shadowingRestrictedName", data: { name: "arguments" }, type: "Identifier", column: 37 },
{ messageId: "shadowingRestrictedName", data: { name: "arguments" }, type: "Identifier", column: 58 },
{ messageId: "shadowingRestrictedName", data: { name: "arguments" }, type: "Identifier", column: 68 },
{ messageId: "shadowingRestrictedName", data: { name: "arguments" }, type: "Identifier", column: 94 }
]
},
{
code: "function eval(eval) { var eval; !function eval(eval) { try {} catch(eval) {} }; }",
errors: [
{ messageId: "shadowingRestrictedName", data: { name: "eval" }, type: "Identifier" },
{ messageId: "shadowingRestrictedName", data: { name: "eval" }, type: "Identifier" },
{ messageId: "shadowingRestrictedName", data: { name: "eval" }, type: "Identifier" },
{ messageId: "shadowingRestrictedName", data: { name: "eval" }, type: "Identifier" },
{ messageId: "shadowingRestrictedName", data: { name: "eval" }, type: "Identifier" },
{ messageId: "shadowingRestrictedName", data: { name: "eval" }, type: "Identifier" }
{ messageId: "shadowingRestrictedName", data: { name: "eval" }, type: "Identifier", column: 10 },
{ messageId: "shadowingRestrictedName", data: { name: "eval" }, type: "Identifier", column: 15 },
{ messageId: "shadowingRestrictedName", data: { name: "eval" }, type: "Identifier", column: 27 },
{ messageId: "shadowingRestrictedName", data: { name: "eval" }, type: "Identifier", column: 43 },
{ messageId: "shadowingRestrictedName", data: { name: "eval" }, type: "Identifier", column: 48 },
{ messageId: "shadowingRestrictedName", data: { name: "eval" }, type: "Identifier", column: 69 }
]
},
{
code: "var eval = (eval) => { var eval; !function eval(eval) { try {} catch(eval) {} }; }",
languageOptions: { ecmaVersion: 6 },
errors: [
{ messageId: "shadowingRestrictedName", data: { name: "eval" }, type: "Identifier" },
{ messageId: "shadowingRestrictedName", data: { name: "eval" }, type: "Identifier" },
{ messageId: "shadowingRestrictedName", data: { name: "eval" }, type: "Identifier" },
{ messageId: "shadowingRestrictedName", data: { name: "eval" }, type: "Identifier" },
{ messageId: "shadowingRestrictedName", data: { name: "eval" }, type: "Identifier" },
{ messageId: "shadowingRestrictedName", data: { name: "eval" }, type: "Identifier" }
{ messageId: "shadowingRestrictedName", data: { name: "eval" }, type: "Identifier", column: 5 },
{ messageId: "shadowingRestrictedName", data: { name: "eval" }, type: "Identifier", column: 13 },
{ messageId: "shadowingRestrictedName", data: { name: "eval" }, type: "Identifier", column: 28 },
{ messageId: "shadowingRestrictedName", data: { name: "eval" }, type: "Identifier", column: 44 },
{ messageId: "shadowingRestrictedName", data: { name: "eval" }, type: "Identifier", column: 49 },
{ messageId: "shadowingRestrictedName", data: { name: "eval" }, type: "Identifier", column: 70 }
]
},
{
code: "var [undefined] = [1]",
languageOptions: { ecmaVersion: 6 },
errors: [
{ messageId: "shadowingRestrictedName", data: { name: "undefined" }, type: "Identifier" }
{ messageId: "shadowingRestrictedName", data: { name: "undefined" }, type: "Identifier", column: 6 }
]
},
{
code: "var {undefined} = obj; var {a: undefined} = obj; var {a: {b: {undefined}}} = obj; var {a, ...undefined} = obj;",
languageOptions: { ecmaVersion: 9 },
errors: [
{ messageId: "shadowingRestrictedName", data: { name: "undefined" }, type: "Identifier" },
{ messageId: "shadowingRestrictedName", data: { name: "undefined" }, type: "Identifier" },
{ messageId: "shadowingRestrictedName", data: { name: "undefined" }, type: "Identifier" },
{ messageId: "shadowingRestrictedName", data: { name: "undefined" }, type: "Identifier" }
{ messageId: "shadowingRestrictedName", data: { name: "undefined" }, type: "Identifier", column: 6 },
{ messageId: "shadowingRestrictedName", data: { name: "undefined" }, type: "Identifier", column: 32 },
{ messageId: "shadowingRestrictedName", data: { name: "undefined" }, type: "Identifier", column: 63 },
{ messageId: "shadowingRestrictedName", data: { name: "undefined" }, type: "Identifier", column: 94 }
]
},
{
code: "var undefined; undefined = 5;",
errors: [
{ messageId: "shadowingRestrictedName", data: { name: "undefined" }, type: "Identifier" }
{ messageId: "shadowingRestrictedName", data: { name: "undefined" }, type: "Identifier", column: 5 }
]
},
{
code: "class undefined {}",
languageOptions: {
ecmaVersion: 2015
},
errors: [
{ messageId: "shadowingRestrictedName", data: { name: "undefined" }, type: "Identifier", column: 7 }
]
},
{
code: "(class undefined {})",
languageOptions: {
ecmaVersion: 2015
},
errors: [
{ messageId: "shadowingRestrictedName", data: { name: "undefined" }, type: "Identifier", column: 8 }
]
},
{
code: "import undefined from 'foo';",
languageOptions: {
ecmaVersion: 2015,
sourceType: "module"
},
errors: [
{ messageId: "shadowingRestrictedName", data: { name: "undefined" }, type: "Identifier", column: 8 }
]
},
{
code: "import { undefined } from 'foo';",
languageOptions: {
ecmaVersion: 2015,
sourceType: "module"
},
errors: [
{ messageId: "shadowingRestrictedName", data: { name: "undefined" }, type: "Identifier", column: 10 }
]
},
{
code: "import { baz as undefined } from 'foo';",
languageOptions: {
ecmaVersion: 2015,
sourceType: "module"
},
errors: [
{ messageId: "shadowingRestrictedName", data: { name: "undefined" }, type: "Identifier", column: 17 }
]
},
{
code: "import * as undefined from 'foo';",
languageOptions: {
ecmaVersion: 2015,
sourceType: "module"
},
errors: [
{ messageId: "shadowingRestrictedName", data: { name: "undefined" }, type: "Identifier", column: 13 }
]
}
]
Expand Down

0 comments on commit 87a9352

Please sign in to comment.