Skip to content
This repository has been archived by the owner on Mar 25, 2021. It is now read-only.

Added no-magic-numbers rule #1799

Merged
merged 7 commits into from
Dec 8, 2016
Merged

Added no-magic-numbers rule #1799

merged 7 commits into from
Dec 8, 2016

Conversation

SimonSchick
Copy link
Contributor

@SimonSchick SimonSchick commented Nov 29, 2016

PR checklist

  • Addresses an existing issue: #0000
  • New feature, bugfix, or enhancement
    • Includes tests
  • Documentation update

What changes did you make?

Added a rule to prevent magic numbers.

See the added tests for examples.

Basic usage: "no-magic-numbers": true disallows all except 0 and 1/-1.
Custom allow list: "no-magic-numbers": [true, 1337, 1338]" Only 1337 and 1338 are allowed.

Is there anything you'd like reviewers to focus on?

I am not very familiar with tslint and the TS API and it would love to get feedback on the filter method.

@palantirtech
Copy link
Member

Thanks for your interest in palantir/tslint, @SimonSchick! Before we can accept your pull request, you need to sign our contributor license agreement - just visit https://cla.palantir.com/ and follow the instructions. Once you sign, I'll automatically update this pull request.

/* tslint:disable:object-literal-sort-keys */
public static metadata: Lint.IRuleMetadata = {
ruleName: "no-magic-numbers",
description: "Disallows the use constant number values outside of variable assignment. -1, 0 and 1 are allowed by default.",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DEFAULT_ALLOWED does not include -1

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is as the minus sign is not part of number literal.

/* tslint:disable:object-literal-sort-keys */
public static metadata: Lint.IRuleMetadata = {
ruleName: "no-magic-numbers",
description: "Disallows the use constant number values outside of variable assignment. -1, 0 and 1 are allowed by default.",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Description should say that the default values are set if there are no list of numbers is supplied. When I read this, it sounded like the default values are unioned with the user-supplied list

rationale: Lint.Utils.dedent`
Magic numbers should be avoided as they often lack documentation, forcing
them to be stored in variables gives them implicit documentation.`,
optionsDescription: "A list of allowed number.",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

number -> numbers

Rule.ALLOWED_NODES.indexOf(node.parent.kind) === -1) {
const options = this.getOptions();

const allowed: number[] = options.length > 0 ? options : Rule.DEFAULT_ALLOWED;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

read options and do this logic in a constructor so you don't have to do this for every node

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I wasn't entirely sure if this.getOptions might change during operation and would thus break things. Thanks for clearing that up.


public static FAILURE_STRING = "'magic numbers' are no allowed";

public static ALLOWED_NODES = [
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use object literal with computed property names for faster lookups:

public static ALLOWED_NODES = {
    [ts.SyntaxKind.ExportAssignment]: true
    ...
}
Rule.ALLOWED_NODES[node.parent.kind]

@nchen63
Copy link
Contributor

nchen63 commented Dec 1, 2016

Looks pretty good in general. Have some minor changes


public visitNode(node: ts.Node) {
if (node.kind === ts.SyntaxKind.NumericLiteral && !Rule.ALLOWED_NODES[node.parent.kind]) {
if (!this.allowed[node.getText()]) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should be changed to handle negative numbers. If someone configures the rule to allow -1, it would never be matched.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll have to look into that, I'm a little short on time right now tho...

@@ -0,0 +1,30 @@
console.log(-1, 0, 1);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add test for floats

[ts.SyntaxKind.PropertyDeclaration]: true,
};

public static DEFAULT_ALLOWED = [
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor: can you just make this a one liner? i.e. ... = [0, 1];

super(sourceFile, options);

const configOptions = this.getOptions();
const allowedArray: number[] = configOptions.length > 0 ? configOptions : Rule.DEFAULT_ALLOWED;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please be more specific in the variable name and omit "Array" since it is redundant with the typdef. call this const allowedNumbers instead.

}

class NoMagicNumbersWalker extends Lint.RuleWalker {
private allowed: { [prop: string]: boolean };
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is the point of this object? its values are always true.

Copy link
Contributor Author

@SimonSchick SimonSchick Dec 8, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#1799 (comment) it's used as a lookup map (which is faster).

Copy link
Contributor

@nchen63 nchen63 Dec 8, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe add a comment so people know that this is for fast lookup

@SimonSchick
Copy link
Contributor Author

I think I addressed all comments for now.

@adidahiya adidahiya dismissed their stale review December 8, 2016 19:05

comments addressed

ruleName: "no-magic-numbers",
description: Lint.Utils.dedent`
Disallows the use constant number values outside of variable assignments.
When no list of allowed values is specified, 0 and 1 are allowed by default.`,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this doesn't match DEFAULT_ALLOWED

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not anymore, right 😛

};
/* tslint:enable:object-literal-sort-keys */

public static FAILURE_STRING = "'magic numbers' are no allowed";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no -> not

}

class NoMagicNumbersWalker extends Lint.RuleWalker {
private allowed: { [prop: string]: boolean };
Copy link
Contributor

@nchen63 nchen63 Dec 8, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe add a comment so people know that this is for fast lookup

@nchen63 nchen63 merged commit 8e6a0ce into palantir:master Dec 8, 2016
@nchen63
Copy link
Contributor

nchen63 commented Dec 8, 2016

@SimonSchick looks good. Thanks!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants