Skip to content

Commit

Permalink
feat(eslint-plugin): [no-magic-numbers] add ignoreReadonlyClassProper…
Browse files Browse the repository at this point in the history
…ties option (#938)
  • Loading branch information
a-tarasyuk authored and JamesHenry committed Sep 12, 2019
1 parent 46ee4c9 commit aeea4cd
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 0 deletions.
28 changes: 28 additions & 0 deletions packages/eslint-plugin/docs/rules/no-magic-numbers.md
Expand Up @@ -41,6 +41,34 @@ Examples of **correct** code for the `{ "ignoreNumericLiteralTypes": true }` opt
type SmallPrimes = 2 | 3 | 5 | 7 | 11;
```

### ignoreReadonlyClassProperties

Examples of **incorrect** code for the `{ "ignoreReadonlyClassProperties": false }` option:

```ts
/*eslint @typescript-eslint/no-magic-numbers: ["error", { "ignoreReadonlyClassProperties": false }]*/

class Foo {
readonly A = 1;
readonly B = 2;
public static readonly C = 1;
static readonly D = 1;
}
```

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

```ts
/*eslint @typescript-eslint/no-magic-numbers: ["error", { "ignoreReadonlyClassProperties": true }]*/

class Foo {
readonly A = 1;
readonly B = 2;
public static readonly C = 1;
static readonly D = 1;
}
```

### ignoreEnums

A boolean to specify if enums used in Typescript are considered okay. `false` by default.
Expand Down
25 changes: 25 additions & 0 deletions packages/eslint-plugin/src/rules/no-magic-numbers.ts
Expand Up @@ -33,6 +33,9 @@ export default util.createRule<Options, MessageIds>({
ignoreEnums: {
type: 'boolean',
},
ignoreReadonlyClassProperties: {
type: 'boolean',
},
},
},
],
Expand All @@ -46,6 +49,7 @@ export default util.createRule<Options, MessageIds>({
detectObjects: false,
ignoreNumericLiteralTypes: false,
ignoreEnums: false,
ignoreReadonlyClassProperties: false,
},
],
create(context, [options]) {
Expand Down Expand Up @@ -149,13 +153,34 @@ export default util.createRule<Options, MessageIds>({
return false;
}

/**
* Checks if the node parent is a readonly class property
* @param node the node to be validated.
* @returns true if the node parent is a readonly class property
* @private
*/
function isParentTSReadonlyClassProperty(node: TSESTree.Node): boolean {
return (
!!node.parent &&
node.parent.type === AST_NODE_TYPES.ClassProperty &&
!!node.parent.readonly
);
}

return {
Literal(node): void {
// Check if the node is a TypeScript enum declaration
if (options.ignoreEnums && isParentTSEnumDeclaration(node)) {
return;
}

if (
options.ignoreReadonlyClassProperties &&
isParentTSReadonlyClassProperty(node)
) {
return;
}

// Check TypeScript specific nodes for Numeric Literal
if (
options.ignoreNumericLiteralTypes &&
Expand Down
44 changes: 44 additions & 0 deletions packages/eslint-plugin/tests/rules/no-magic-numbers.test.ts
Expand Up @@ -41,6 +41,17 @@ ruleTester.run('no-magic-numbers', rule, {
code: 'enum foo { SECOND = 1000, NUM = "0123456789" }',
options: [{ ignoreEnums: true }],
},
{
code: `
class Foo {
readonly A = 1;
readonly B = 2;
public static readonly C = 1;
static readonly D = 1;
}
`,
options: [{ ignoreReadonlyClassProperties: true }],
},
],

invalid: [
Expand Down Expand Up @@ -166,5 +177,38 @@ ruleTester.run('no-magic-numbers', rule, {
},
],
},
{
code: `
class Foo {
readonly A = 1;
readonly B = 2;
public static readonly C = 1;
static readonly D = 1;
}
`,
options: [{ ignoreReadonlyClassProperties: false }],
errors: [
{
messageId: 'noMagic',
line: 3,
column: 16,
},
{
messageId: 'noMagic',
line: 4,
column: 16,
},
{
messageId: 'noMagic',
line: 5,
column: 30,
},
{
messageId: 'noMagic',
line: 6,
column: 23,
},
],
},
],
});
1 change: 1 addition & 0 deletions packages/eslint-plugin/typings/eslint-rules.d.ts
Expand Up @@ -199,6 +199,7 @@ declare module 'eslint/lib/rules/no-magic-numbers' {
detectObjects?: boolean;
ignoreNumericLiteralTypes?: boolean;
ignoreEnums?: boolean;
ignoreReadonlyClassProperties?: boolean;
},
],
{
Expand Down

0 comments on commit aeea4cd

Please sign in to comment.