Skip to content

Commit d17fb1b

Browse files
alejo90Josh Goldberg
authored and
Josh Goldberg
committed
implement no-shadowed-variable converter (#218)
1 parent dbd749f commit d17fb1b

File tree

3 files changed

+136
-1
lines changed

3 files changed

+136
-1
lines changed

src/rules/converters.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ import { convertNoReference } from "./converters/no-reference";
7070
import { convertNoRegexSpaces } from "./converters/no-regex-spaces";
7171
import { convertNoRequireImports } from "./converters/no-require-imports";
7272
import { convertNoReturnAwait } from "./converters/no-return-await";
73+
import { convertNoShadowedVariable } from "./converters/no-shadowed-variable";
7374
import { convertNoSparseArrays } from "./converters/no-sparse-arrays";
7475
import { convertNoStringLiteral } from "./converters/no-string-literal";
7576
import { convertNoStringThrow } from "./converters/no-string-throw";
@@ -191,6 +192,7 @@ export const converters = new Map([
191192
["no-regex-spaces", convertNoRegexSpaces],
192193
["no-require-imports", convertNoRequireImports],
193194
["no-return-await", convertNoReturnAwait],
195+
["no-shadowed-variable", convertNoShadowedVariable],
194196
["no-sparse-arrays", convertNoSparseArrays],
195197
["no-string-literal", convertNoStringLiteral],
196198
["no-string-throw", convertNoStringThrow],
@@ -245,7 +247,6 @@ export const converters = new Map([
245247
// ["ban", convertBan], // no-restricted-properties
246248
// ["import-blacklist", convertImportBlacklist], // no-restricted-imports
247249
// ["no-duplicate-variable", convertNoDuplicateVariable], // no-redeclare
248-
// ["no-shadowed-variable", convertNoShadowedVariable], // no-shadow
249250
// ["no-unused-expression", convertNoUnusedExpression], // no-unused-expressions
250251
// ["space-within-parens", convertSpaceWithinParens], // space-in-parens
251252
// ["variable-name", convertVariableName], // a bunch of rules...
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import { RuleConverter } from "../converter";
2+
3+
const SELECTIVE_DISABLE_NOTICE =
4+
"ESLint does not support selectively disabling shadowed declaration checks " +
5+
"depending on the type of declaration, so all kinds of declarations are checked.";
6+
7+
const UNDERSCORE_DISABLE_NOTICE =
8+
"ESLint does not support disabling shadowed variable checks based on " +
9+
"whether their names start with underscore or not, please use 'allow' in eslint configuration to " +
10+
"provide specific variable names you want to disable the rule for.";
11+
12+
export const convertNoShadowedVariable: RuleConverter = tslintRule => {
13+
const ruleArguments: { hoist: "all" | "never" }[] = [];
14+
const notices: string[] = [];
15+
16+
if (tslintRule.ruleArguments.length === 0 || !(tslintRule.ruleArguments[0] instanceof Object)) {
17+
ruleArguments.push({ hoist: "all" });
18+
} else {
19+
const config: Record<string, boolean> = tslintRule.ruleArguments[0];
20+
21+
if (config.underscore === false) {
22+
notices.push(UNDERSCORE_DISABLE_NOTICE);
23+
}
24+
25+
if (config.temporalDeadZone === false) {
26+
ruleArguments.push({ hoist: "never" });
27+
} else {
28+
ruleArguments.push({ hoist: "all" });
29+
}
30+
31+
const hasUnsupportedDisables = Object.entries(config).some(
32+
([key, value]) => value === false && key !== "underscore" && key !== "temporalDeadZone",
33+
);
34+
35+
if (hasUnsupportedDisables) {
36+
notices.push(SELECTIVE_DISABLE_NOTICE);
37+
}
38+
}
39+
40+
return {
41+
rules: [
42+
{
43+
...(notices.length > 0 && { notices }),
44+
...(ruleArguments.length > 0 && { ruleArguments }),
45+
ruleName: "no-shadow",
46+
},
47+
],
48+
};
49+
};
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
import { convertNoShadowedVariable } from "../no-shadowed-variable";
2+
3+
describe(convertNoShadowedVariable, () => {
4+
test("conversion without parameter", () => {
5+
const result = convertNoShadowedVariable({
6+
ruleArguments: [],
7+
});
8+
9+
expect(result).toEqual({
10+
rules: [
11+
{
12+
ruleArguments: [{ hoist: "all" }],
13+
ruleName: "no-shadow",
14+
},
15+
],
16+
});
17+
});
18+
19+
test("conversion with non-object parameter", () => {
20+
const result = convertNoShadowedVariable({
21+
ruleArguments: ["will-be-ignored"],
22+
});
23+
24+
expect(result).toEqual({
25+
rules: [
26+
{
27+
ruleArguments: [{ hoist: "all" }],
28+
ruleName: "no-shadow",
29+
},
30+
],
31+
});
32+
});
33+
34+
test("conversion with empty parameter object", () => {
35+
const result = convertNoShadowedVariable({
36+
ruleArguments: [{}],
37+
});
38+
39+
expect(result).toEqual({
40+
rules: [
41+
{
42+
ruleArguments: [{ hoist: "all" }],
43+
ruleName: "no-shadow",
44+
},
45+
],
46+
});
47+
});
48+
49+
test("conversion with disabled 'temporalDeadZone'", () => {
50+
const result = convertNoShadowedVariable({
51+
ruleArguments: [{ temporalDeadZone: false }],
52+
});
53+
54+
expect(result).toEqual({
55+
rules: [
56+
{
57+
ruleArguments: [{ hoist: "never" }],
58+
ruleName: "no-shadow",
59+
},
60+
],
61+
});
62+
});
63+
64+
test("conversion with disabled declaration types", () => {
65+
const result = convertNoShadowedVariable({
66+
ruleArguments: [{ class: false, underscore: false }],
67+
});
68+
69+
expect(result).toEqual({
70+
rules: [
71+
{
72+
notices: [
73+
"ESLint does not support disabling shadowed variable checks based on " +
74+
"whether their names start with underscore or not, please use 'allow' in eslint configuration to " +
75+
"provide specific variable names you want to disable the rule for.",
76+
"ESLint does not support selectively disabling shadowed declaration checks " +
77+
"depending on the type of declaration, so all kinds of declarations are checked.",
78+
],
79+
ruleArguments: [{ hoist: "all" }],
80+
ruleName: "no-shadow",
81+
},
82+
],
83+
});
84+
});
85+
});

0 commit comments

Comments
 (0)