Skip to content

Commit 87a9352

Browse files
authoredDec 27, 2024··
feat: check imports and class names in no-shadow-restricted-names (#19272)
Fixes #19271
1 parent 5db226f commit 87a9352

File tree

3 files changed

+147
-48
lines changed

3 files changed

+147
-48
lines changed
 

‎docs/src/rules/no-shadow-restricted-names.md

+24
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,20 @@ try {} catch(eval){}
3838

3939
:::
4040

41+
::: incorrect
42+
43+
```js
44+
/*eslint no-shadow-restricted-names: "error"*/
45+
46+
import NaN from "foo";
47+
48+
import { undefined } from "bar";
49+
50+
class Infinity {}
51+
```
52+
53+
:::
54+
4155
Examples of **correct** code for this rule:
4256

4357
::: correct { "sourceType": "script" }
@@ -54,3 +68,13 @@ var undefined;
5468
```
5569

5670
:::
71+
72+
::: correct
73+
74+
```js
75+
/*eslint no-shadow-restricted-names: "error"*/
76+
77+
import { undefined as undef } from "bar";
78+
```
79+
80+
:::

‎lib/rules/no-shadow-restricted-names.js

+17-7
Original file line numberDiff line numberDiff line change
@@ -45,17 +45,27 @@ module.exports = {
4545
const RESTRICTED = new Set(["undefined", "NaN", "Infinity", "arguments", "eval"]);
4646
const sourceCode = context.sourceCode;
4747

48+
// Track reported nodes to avoid duplicate reports. For example, on class declarations.
49+
const reportedNodes = new Set();
50+
4851
return {
49-
"VariableDeclaration, :function, CatchClause"(node) {
52+
"VariableDeclaration, :function, CatchClause, ImportDeclaration, ClassDeclaration, ClassExpression"(node) {
5053
for (const variable of sourceCode.getDeclaredVariables(node)) {
5154
if (variable.defs.length > 0 && RESTRICTED.has(variable.name) && !safelyShadowsUndefined(variable)) {
52-
context.report({
53-
node: variable.defs[0].name,
54-
messageId: "shadowingRestrictedName",
55-
data: {
56-
name: variable.name
55+
for (const def of variable.defs) {
56+
const nodeToReport = def.name;
57+
58+
if (!reportedNodes.has(nodeToReport)) {
59+
reportedNodes.add(nodeToReport);
60+
context.report({
61+
node: nodeToReport,
62+
messageId: "shadowingRestrictedName",
63+
data: {
64+
name: variable.name
65+
}
66+
});
5767
}
58-
});
68+
}
5969
}
6070
}
6171
}

‎tests/lib/rules/no-shadow-restricted-names.js

+106-41
Original file line numberDiff line numberDiff line change
@@ -40,96 +40,161 @@ ruleTester.run("no-shadow-restricted-names", rule, {
4040
{
4141
code: "let undefined",
4242
languageOptions: { ecmaVersion: 2015 }
43+
},
44+
{
45+
code: "import { undefined as undef } from 'foo';",
46+
languageOptions: {
47+
sourceType: "module",
48+
ecmaVersion: 2015
49+
}
4350
}
4451
],
4552
invalid: [
4653
{
4754
code: "function NaN(NaN) { var NaN; !function NaN(NaN) { try {} catch(NaN) {} }; }",
4855
errors: [
49-
{ messageId: "shadowingRestrictedName", data: { name: "NaN" }, type: "Identifier" },
50-
{ messageId: "shadowingRestrictedName", data: { name: "NaN" }, type: "Identifier" },
51-
{ messageId: "shadowingRestrictedName", data: { name: "NaN" }, type: "Identifier" },
52-
{ messageId: "shadowingRestrictedName", data: { name: "NaN" }, type: "Identifier" },
53-
{ messageId: "shadowingRestrictedName", data: { name: "NaN" }, type: "Identifier" },
54-
{ messageId: "shadowingRestrictedName", data: { name: "NaN" }, type: "Identifier" }
56+
{ messageId: "shadowingRestrictedName", data: { name: "NaN" }, type: "Identifier", column: 10 },
57+
{ messageId: "shadowingRestrictedName", data: { name: "NaN" }, type: "Identifier", column: 14 },
58+
{ messageId: "shadowingRestrictedName", data: { name: "NaN" }, type: "Identifier", column: 25 },
59+
{ messageId: "shadowingRestrictedName", data: { name: "NaN" }, type: "Identifier", column: 40 },
60+
{ messageId: "shadowingRestrictedName", data: { name: "NaN" }, type: "Identifier", column: 44 },
61+
{ messageId: "shadowingRestrictedName", data: { name: "NaN" }, type: "Identifier", column: 64 }
5562
]
5663
},
5764
{
5865
code: "function undefined(undefined) { !function undefined(undefined) { try {} catch(undefined) {} }; }",
5966
errors: [
60-
{ messageId: "shadowingRestrictedName", data: { name: "undefined" }, type: "Identifier" },
61-
{ messageId: "shadowingRestrictedName", data: { name: "undefined" }, type: "Identifier" },
62-
{ messageId: "shadowingRestrictedName", data: { name: "undefined" }, type: "Identifier" },
63-
{ messageId: "shadowingRestrictedName", data: { name: "undefined" }, type: "Identifier" },
64-
{ messageId: "shadowingRestrictedName", data: { name: "undefined" }, type: "Identifier" }
67+
{ messageId: "shadowingRestrictedName", data: { name: "undefined" }, type: "Identifier", column: 10 },
68+
{ messageId: "shadowingRestrictedName", data: { name: "undefined" }, type: "Identifier", column: 20 },
69+
{ messageId: "shadowingRestrictedName", data: { name: "undefined" }, type: "Identifier", column: 43 },
70+
{ messageId: "shadowingRestrictedName", data: { name: "undefined" }, type: "Identifier", column: 53 },
71+
{ messageId: "shadowingRestrictedName", data: { name: "undefined" }, type: "Identifier", column: 79 }
6572
]
6673
},
6774
{
6875
code: "function Infinity(Infinity) { var Infinity; !function Infinity(Infinity) { try {} catch(Infinity) {} }; }",
6976
errors: [
70-
{ messageId: "shadowingRestrictedName", data: { name: "Infinity" }, type: "Identifier" },
71-
{ messageId: "shadowingRestrictedName", data: { name: "Infinity" }, type: "Identifier" },
72-
{ messageId: "shadowingRestrictedName", data: { name: "Infinity" }, type: "Identifier" },
73-
{ messageId: "shadowingRestrictedName", data: { name: "Infinity" }, type: "Identifier" },
74-
{ messageId: "shadowingRestrictedName", data: { name: "Infinity" }, type: "Identifier" },
75-
{ messageId: "shadowingRestrictedName", data: { name: "Infinity" }, type: "Identifier" }
77+
{ messageId: "shadowingRestrictedName", data: { name: "Infinity" }, type: "Identifier", column: 10 },
78+
{ messageId: "shadowingRestrictedName", data: { name: "Infinity" }, type: "Identifier", column: 19 },
79+
{ messageId: "shadowingRestrictedName", data: { name: "Infinity" }, type: "Identifier", column: 35 },
80+
{ messageId: "shadowingRestrictedName", data: { name: "Infinity" }, type: "Identifier", column: 55 },
81+
{ messageId: "shadowingRestrictedName", data: { name: "Infinity" }, type: "Identifier", column: 64 },
82+
{ messageId: "shadowingRestrictedName", data: { name: "Infinity" }, type: "Identifier", column: 89 }
7683
]
7784
},
7885
{
7986
code: "function arguments(arguments) { var arguments; !function arguments(arguments) { try {} catch(arguments) {} }; }",
8087
errors: [
81-
{ messageId: "shadowingRestrictedName", data: { name: "arguments" }, type: "Identifier" },
82-
{ messageId: "shadowingRestrictedName", data: { name: "arguments" }, type: "Identifier" },
83-
{ messageId: "shadowingRestrictedName", data: { name: "arguments" }, type: "Identifier" },
84-
{ messageId: "shadowingRestrictedName", data: { name: "arguments" }, type: "Identifier" },
85-
{ messageId: "shadowingRestrictedName", data: { name: "arguments" }, type: "Identifier" },
86-
{ messageId: "shadowingRestrictedName", data: { name: "arguments" }, type: "Identifier" }
88+
{ messageId: "shadowingRestrictedName", data: { name: "arguments" }, type: "Identifier", column: 10 },
89+
{ messageId: "shadowingRestrictedName", data: { name: "arguments" }, type: "Identifier", column: 20 },
90+
{ messageId: "shadowingRestrictedName", data: { name: "arguments" }, type: "Identifier", column: 37 },
91+
{ messageId: "shadowingRestrictedName", data: { name: "arguments" }, type: "Identifier", column: 58 },
92+
{ messageId: "shadowingRestrictedName", data: { name: "arguments" }, type: "Identifier", column: 68 },
93+
{ messageId: "shadowingRestrictedName", data: { name: "arguments" }, type: "Identifier", column: 94 }
8794
]
8895
},
8996
{
9097
code: "function eval(eval) { var eval; !function eval(eval) { try {} catch(eval) {} }; }",
9198
errors: [
92-
{ messageId: "shadowingRestrictedName", data: { name: "eval" }, type: "Identifier" },
93-
{ messageId: "shadowingRestrictedName", data: { name: "eval" }, type: "Identifier" },
94-
{ messageId: "shadowingRestrictedName", data: { name: "eval" }, type: "Identifier" },
95-
{ messageId: "shadowingRestrictedName", data: { name: "eval" }, type: "Identifier" },
96-
{ messageId: "shadowingRestrictedName", data: { name: "eval" }, type: "Identifier" },
97-
{ messageId: "shadowingRestrictedName", data: { name: "eval" }, type: "Identifier" }
99+
{ messageId: "shadowingRestrictedName", data: { name: "eval" }, type: "Identifier", column: 10 },
100+
{ messageId: "shadowingRestrictedName", data: { name: "eval" }, type: "Identifier", column: 15 },
101+
{ messageId: "shadowingRestrictedName", data: { name: "eval" }, type: "Identifier", column: 27 },
102+
{ messageId: "shadowingRestrictedName", data: { name: "eval" }, type: "Identifier", column: 43 },
103+
{ messageId: "shadowingRestrictedName", data: { name: "eval" }, type: "Identifier", column: 48 },
104+
{ messageId: "shadowingRestrictedName", data: { name: "eval" }, type: "Identifier", column: 69 }
98105
]
99106
},
100107
{
101108
code: "var eval = (eval) => { var eval; !function eval(eval) { try {} catch(eval) {} }; }",
102109
languageOptions: { ecmaVersion: 6 },
103110
errors: [
104-
{ messageId: "shadowingRestrictedName", data: { name: "eval" }, type: "Identifier" },
105-
{ messageId: "shadowingRestrictedName", data: { name: "eval" }, type: "Identifier" },
106-
{ messageId: "shadowingRestrictedName", data: { name: "eval" }, type: "Identifier" },
107-
{ messageId: "shadowingRestrictedName", data: { name: "eval" }, type: "Identifier" },
108-
{ messageId: "shadowingRestrictedName", data: { name: "eval" }, type: "Identifier" },
109-
{ messageId: "shadowingRestrictedName", data: { name: "eval" }, type: "Identifier" }
111+
{ messageId: "shadowingRestrictedName", data: { name: "eval" }, type: "Identifier", column: 5 },
112+
{ messageId: "shadowingRestrictedName", data: { name: "eval" }, type: "Identifier", column: 13 },
113+
{ messageId: "shadowingRestrictedName", data: { name: "eval" }, type: "Identifier", column: 28 },
114+
{ messageId: "shadowingRestrictedName", data: { name: "eval" }, type: "Identifier", column: 44 },
115+
{ messageId: "shadowingRestrictedName", data: { name: "eval" }, type: "Identifier", column: 49 },
116+
{ messageId: "shadowingRestrictedName", data: { name: "eval" }, type: "Identifier", column: 70 }
110117
]
111118
},
112119
{
113120
code: "var [undefined] = [1]",
114121
languageOptions: { ecmaVersion: 6 },
115122
errors: [
116-
{ messageId: "shadowingRestrictedName", data: { name: "undefined" }, type: "Identifier" }
123+
{ messageId: "shadowingRestrictedName", data: { name: "undefined" }, type: "Identifier", column: 6 }
117124
]
118125
},
119126
{
120127
code: "var {undefined} = obj; var {a: undefined} = obj; var {a: {b: {undefined}}} = obj; var {a, ...undefined} = obj;",
121128
languageOptions: { ecmaVersion: 9 },
122129
errors: [
123-
{ messageId: "shadowingRestrictedName", data: { name: "undefined" }, type: "Identifier" },
124-
{ messageId: "shadowingRestrictedName", data: { name: "undefined" }, type: "Identifier" },
125-
{ messageId: "shadowingRestrictedName", data: { name: "undefined" }, type: "Identifier" },
126-
{ messageId: "shadowingRestrictedName", data: { name: "undefined" }, type: "Identifier" }
130+
{ messageId: "shadowingRestrictedName", data: { name: "undefined" }, type: "Identifier", column: 6 },
131+
{ messageId: "shadowingRestrictedName", data: { name: "undefined" }, type: "Identifier", column: 32 },
132+
{ messageId: "shadowingRestrictedName", data: { name: "undefined" }, type: "Identifier", column: 63 },
133+
{ messageId: "shadowingRestrictedName", data: { name: "undefined" }, type: "Identifier", column: 94 }
127134
]
128135
},
129136
{
130137
code: "var undefined; undefined = 5;",
131138
errors: [
132-
{ messageId: "shadowingRestrictedName", data: { name: "undefined" }, type: "Identifier" }
139+
{ messageId: "shadowingRestrictedName", data: { name: "undefined" }, type: "Identifier", column: 5 }
140+
]
141+
},
142+
{
143+
code: "class undefined {}",
144+
languageOptions: {
145+
ecmaVersion: 2015
146+
},
147+
errors: [
148+
{ messageId: "shadowingRestrictedName", data: { name: "undefined" }, type: "Identifier", column: 7 }
149+
]
150+
},
151+
{
152+
code: "(class undefined {})",
153+
languageOptions: {
154+
ecmaVersion: 2015
155+
},
156+
errors: [
157+
{ messageId: "shadowingRestrictedName", data: { name: "undefined" }, type: "Identifier", column: 8 }
158+
]
159+
},
160+
{
161+
code: "import undefined from 'foo';",
162+
languageOptions: {
163+
ecmaVersion: 2015,
164+
sourceType: "module"
165+
},
166+
errors: [
167+
{ messageId: "shadowingRestrictedName", data: { name: "undefined" }, type: "Identifier", column: 8 }
168+
]
169+
},
170+
{
171+
code: "import { undefined } from 'foo';",
172+
languageOptions: {
173+
ecmaVersion: 2015,
174+
sourceType: "module"
175+
},
176+
errors: [
177+
{ messageId: "shadowingRestrictedName", data: { name: "undefined" }, type: "Identifier", column: 10 }
178+
]
179+
},
180+
{
181+
code: "import { baz as undefined } from 'foo';",
182+
languageOptions: {
183+
ecmaVersion: 2015,
184+
sourceType: "module"
185+
},
186+
errors: [
187+
{ messageId: "shadowingRestrictedName", data: { name: "undefined" }, type: "Identifier", column: 17 }
188+
]
189+
},
190+
{
191+
code: "import * as undefined from 'foo';",
192+
languageOptions: {
193+
ecmaVersion: 2015,
194+
sourceType: "module"
195+
},
196+
errors: [
197+
{ messageId: "shadowingRestrictedName", data: { name: "undefined" }, type: "Identifier", column: 13 }
133198
]
134199
}
135200
]

0 commit comments

Comments
 (0)
Please sign in to comment.