aboutsummaryrefslogtreecommitdiffstats
path: root/packages/tslint-config/rules/customNoMagicNumbersRule.ts
diff options
context:
space:
mode:
authorFabio Berger <me@fabioberger.com>2018-05-23 00:04:50 +0800
committerGitHub <noreply@github.com>2018-05-23 00:04:50 +0800
commitcc840a6911850856c3254f7ac73cd70c527e1a5c (patch)
treec7435ac7ce09541a67f0106a85f391dc48921e10 /packages/tslint-config/rules/customNoMagicNumbersRule.ts
parenta26cc7c14d4e59102d5f84d534f75c42b8683cad (diff)
parentc4a2f700172e8be367225d90a1c51cef8cf0d7dd (diff)
downloaddexon-0x-contracts-cc840a6911850856c3254f7ac73cd70c527e1a5c.tar
dexon-0x-contracts-cc840a6911850856c3254f7ac73cd70c527e1a5c.tar.gz
dexon-0x-contracts-cc840a6911850856c3254f7ac73cd70c527e1a5c.tar.bz2
dexon-0x-contracts-cc840a6911850856c3254f7ac73cd70c527e1a5c.tar.lz
dexon-0x-contracts-cc840a6911850856c3254f7ac73cd70c527e1a5c.tar.xz
dexon-0x-contracts-cc840a6911850856c3254f7ac73cd70c527e1a5c.tar.zst
dexon-0x-contracts-cc840a6911850856c3254f7ac73cd70c527e1a5c.zip
Merge pull request #594 from 0xProject/improvement/addCustomTslintRules
Add more tslint rules
Diffstat (limited to 'packages/tslint-config/rules/customNoMagicNumbersRule.ts')
-rw-r--r--packages/tslint-config/rules/customNoMagicNumbersRule.ts76
1 files changed, 76 insertions, 0 deletions
diff --git a/packages/tslint-config/rules/customNoMagicNumbersRule.ts b/packages/tslint-config/rules/customNoMagicNumbersRule.ts
new file mode 100644
index 000000000..e358221eb
--- /dev/null
+++ b/packages/tslint-config/rules/customNoMagicNumbersRule.ts
@@ -0,0 +1,76 @@
+import * as Lint from 'tslint';
+import { isPrefixUnaryExpression } from 'tsutils';
+import * as ts from 'typescript';
+
+/**
+ * A modified version of the no-magic-numbers rule that allows for magic numbers
+ * when instantiating a BigNumber instance.
+ * E.g We want to be able to write:
+ * const amount = new BigNumber(5);
+ * Original source: https://github.com/palantir/tslint/blob/42b058a6baa688f8be8558b277eb056c3ff79818/src/rules/noMagicNumbersRule.ts
+ */
+export class Rule extends Lint.Rules.AbstractRule {
+ public static ALLOWED_NODES = new Set<ts.SyntaxKind>([
+ ts.SyntaxKind.ExportAssignment,
+ ts.SyntaxKind.FirstAssignment,
+ ts.SyntaxKind.LastAssignment,
+ ts.SyntaxKind.PropertyAssignment,
+ ts.SyntaxKind.ShorthandPropertyAssignment,
+ ts.SyntaxKind.VariableDeclaration,
+ ts.SyntaxKind.VariableDeclarationList,
+ ts.SyntaxKind.EnumMember,
+ ts.SyntaxKind.PropertyDeclaration,
+ ts.SyntaxKind.Parameter,
+ ]);
+
+ public static DEFAULT_ALLOWED = [-1, 0, 1];
+
+ public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
+ const allowedNumbers = this.ruleArguments.length > 0 ? this.ruleArguments : Rule.DEFAULT_ALLOWED;
+ return this.applyWithWalker(
+ new CustomNoMagicNumbersWalker(sourceFile, this.ruleName, new Set(allowedNumbers.map(String))),
+ );
+ }
+}
+
+// tslint:disable-next-line:max-classes-per-file
+class CustomNoMagicNumbersWalker extends Lint.AbstractWalker<Set<string>> {
+ public static FAILURE_STRING = "'magic numbers' are not allowed";
+ private static _isNegativeNumberLiteral(
+ node: ts.Node,
+ ): node is ts.PrefixUnaryExpression & { operand: ts.NumericLiteral } {
+ return (
+ isPrefixUnaryExpression(node) &&
+ node.operator === ts.SyntaxKind.MinusToken &&
+ node.operand.kind === ts.SyntaxKind.NumericLiteral
+ );
+ }
+ public walk(sourceFile: ts.SourceFile): void {
+ const cb = (node: ts.Node): void => {
+ if (node.kind === ts.SyntaxKind.NumericLiteral) {
+ return this.checkNumericLiteral(node, (node as ts.NumericLiteral).text);
+ }
+ if (CustomNoMagicNumbersWalker._isNegativeNumberLiteral(node)) {
+ return this.checkNumericLiteral(node, `-${(node.operand as ts.NumericLiteral).text}`);
+ }
+ return ts.forEachChild(node, cb);
+ };
+ return ts.forEachChild(sourceFile, cb);
+ }
+
+ // tslint:disable:no-non-null-assertion
+ // tslint:disable-next-line:underscore-private-and-protected
+ private checkNumericLiteral(node: ts.Node, num: string): void {
+ if (!Rule.ALLOWED_NODES.has(node.parent!.kind) && !this.options.has(num)) {
+ if (node.parent!.kind === ts.SyntaxKind.NewExpression) {
+ const className = (node.parent! as any).expression.escapedText;
+ const BIG_NUMBER_NEW_EXPRESSION = 'BigNumber';
+ if (className === BIG_NUMBER_NEW_EXPRESSION) {
+ return; // noop
+ }
+ }
+ this.addFailureAtNode(node, CustomNoMagicNumbersWalker.FAILURE_STRING);
+ }
+ }
+ // tslint:enable:no-non-null-assertion
+}