Skip to content

Commit

Permalink
feat: add ignoreClassFieldInitialValues option to no-magic-numbers (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
mdjermanovic committed Nov 16, 2022
1 parent c50ae4f commit 63bce44
Show file tree
Hide file tree
Showing 3 changed files with 166 additions and 1 deletion.
39 changes: 39 additions & 0 deletions docs/src/rules/no-magic-numbers.md
Expand Up @@ -193,6 +193,45 @@ let head;

:::

### ignoreClassFieldInitialValues

A boolean to specify if numbers used as initial values of class fields are considered okay. `false` by default.

Examples of **correct** code for the `{ "ignoreClassFieldInitialValues": true }` option:

::: correct

```js
/*eslint no-magic-numbers: ["error", { "ignoreClassFieldInitialValues": true }]*/

class C {
foo = 2;
bar = -3;
#baz = 4;
static qux = 5;
}
```

:::

Examples of **incorrect** code for the `{ "ignoreClassFieldInitialValues": true }` option:

::: incorrect

```js
/*eslint no-magic-numbers: ["error", { "ignoreClassFieldInitialValues": true }]*/

class C {
foo = 2 + 3;
}

class D {
2;
}
```

:::

### enforceConst

A boolean to specify if we should check for the const keyword in variable declaration of numbers. `false` by default.
Expand Down
19 changes: 18 additions & 1 deletion lib/rules/no-magic-numbers.js
Expand Up @@ -65,6 +65,10 @@ module.exports = {
ignoreDefaultValues: {
type: "boolean",
default: false
},
ignoreClassFieldInitialValues: {
type: "boolean",
default: false
}
},
additionalProperties: false
Expand All @@ -82,7 +86,8 @@ module.exports = {
enforceConst = !!config.enforceConst,
ignore = new Set((config.ignore || []).map(normalizeIgnoreValue)),
ignoreArrayIndexes = !!config.ignoreArrayIndexes,
ignoreDefaultValues = !!config.ignoreDefaultValues;
ignoreDefaultValues = !!config.ignoreDefaultValues,
ignoreClassFieldInitialValues = !!config.ignoreClassFieldInitialValues;

const okTypes = detectObjects ? [] : ["ObjectExpression", "Property", "AssignmentExpression"];

Expand All @@ -106,6 +111,17 @@ module.exports = {
return parent.type === "AssignmentPattern" && parent.right === fullNumberNode;
}

/**
* Returns whether the number is the initial value of a class field.
* @param {ASTNode} fullNumberNode `Literal` or `UnaryExpression` full number node
* @returns {boolean} true if the number is the initial value of a class field.
*/
function isClassFieldInitialValue(fullNumberNode) {
const parent = fullNumberNode.parent;

return parent.type === "PropertyDefinition" && parent.value === fullNumberNode;
}

/**
* Returns whether the given node is used as a radix within parseInt() or Number.parseInt()
* @param {ASTNode} fullNumberNode `Literal` or `UnaryExpression` full number node
Expand Down Expand Up @@ -194,6 +210,7 @@ module.exports = {
if (
isIgnoredValue(value) ||
(ignoreDefaultValues && isDefaultValue(fullNumberNode)) ||
(ignoreClassFieldInitialValues && isClassFieldInitialValue(fullNumberNode)) ||
isParseIntRadix(fullNumberNode) ||
isJSXNumber(fullNumberNode) ||
(ignoreArrayIndexes && isArrayIndex(fullNumberNode, value))
Expand Down
109 changes: 109 additions & 0 deletions tests/lib/rules/no-magic-numbers.js
Expand Up @@ -257,6 +257,33 @@ ruleTester.run("no-magic-numbers", rule, {
code: "foo?.[777]",
options: [{ ignoreArrayIndexes: true }],
parserOptions: { ecmaVersion: 2020 }
},

// ignoreClassFieldInitialValues
{
code: "class C { foo = 2; }",
options: [{ ignoreClassFieldInitialValues: true }],
parserOptions: { ecmaVersion: 2022 }
},
{
code: "class C { foo = -2; }",
options: [{ ignoreClassFieldInitialValues: true }],
parserOptions: { ecmaVersion: 2022 }
},
{
code: "class C { static foo = 2; }",
options: [{ ignoreClassFieldInitialValues: true }],
parserOptions: { ecmaVersion: 2022 }
},
{
code: "class C { #foo = 2; }",
options: [{ ignoreClassFieldInitialValues: true }],
parserOptions: { ecmaVersion: 2022 }
},
{
code: "class C { static #foo = 2; }",
options: [{ ignoreClassFieldInitialValues: true }],
parserOptions: { ecmaVersion: 2022 }
}
],
invalid: [
Expand Down Expand Up @@ -812,6 +839,88 @@ ruleTester.run("no-magic-numbers", rule, {
{ messageId: "noMagic", data: { raw: "1" }, line: 1 },
{ messageId: "noMagic", data: { raw: "2" }, line: 1 }
]
},

// ignoreClassFieldInitialValues
{
code: "class C { foo = 2; }",
parserOptions: { ecmaVersion: 2022 },
errors: [
{ messageId: "noMagic", data: { raw: "2" }, line: 1, column: 17 }
]
},
{
code: "class C { foo = 2; }",
options: [{}],
parserOptions: { ecmaVersion: 2022 },
errors: [
{ messageId: "noMagic", data: { raw: "2" }, line: 1, column: 17 }
]
},
{
code: "class C { foo = 2; }",
options: [{ ignoreClassFieldInitialValues: false }],
parserOptions: { ecmaVersion: 2022 },
errors: [
{ messageId: "noMagic", data: { raw: "2" }, line: 1, column: 17 }
]
},
{
code: "class C { foo = -2; }",
options: [{ ignoreClassFieldInitialValues: false }],
parserOptions: { ecmaVersion: 2022 },
errors: [
{ messageId: "noMagic", data: { raw: "-2" }, line: 1, column: 17 }
]
},
{
code: "class C { static foo = 2; }",
options: [{ ignoreClassFieldInitialValues: false }],
parserOptions: { ecmaVersion: 2022 },
errors: [
{ messageId: "noMagic", data: { raw: "2" }, line: 1, column: 24 }
]
},
{
code: "class C { #foo = 2; }",
options: [{ ignoreClassFieldInitialValues: false }],
parserOptions: { ecmaVersion: 2022 },
errors: [
{ messageId: "noMagic", data: { raw: "2" }, line: 1, column: 18 }
]
},
{
code: "class C { static #foo = 2; }",
options: [{ ignoreClassFieldInitialValues: false }],
parserOptions: { ecmaVersion: 2022 },
errors: [
{ messageId: "noMagic", data: { raw: "2" }, line: 1, column: 25 }
]
},
{
code: "class C { foo = 2 + 3; }",
options: [{ ignoreClassFieldInitialValues: true }],
parserOptions: { ecmaVersion: 2022 },
errors: [
{ messageId: "noMagic", data: { raw: "2" }, line: 1, column: 17 },
{ messageId: "noMagic", data: { raw: "3" }, line: 1, column: 21 }
]
},
{
code: "class C { 2; }",
options: [{ ignoreClassFieldInitialValues: true }],
parserOptions: { ecmaVersion: 2022 },
errors: [
{ messageId: "noMagic", data: { raw: "2" }, line: 1, column: 11 }
]
},
{
code: "class C { [2]; }",
options: [{ ignoreClassFieldInitialValues: true }],
parserOptions: { ecmaVersion: 2022 },
errors: [
{ messageId: "noMagic", data: { raw: "2" }, line: 1, column: 12 }
]
}
]
});

0 comments on commit 63bce44

Please sign in to comment.