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

Commit

Permalink
⭐ feat(rules/number-literal-format): add fix (#4496)
Browse files Browse the repository at this point in the history
* ⭐ feat(rules/number-literal-format): add fix

* 🔍 test(number-literal-format): return back testcases

* 😒 chore(rules/number-literal-format): rename matches, correct conditions

* 💄 style(rules/number-literal-format): multiline ternary
  • Loading branch information
ColCh authored and Josh Goldberg committed Feb 5, 2019
1 parent 39201ac commit 44febf9
Show file tree
Hide file tree
Showing 3 changed files with 131 additions and 15 deletions.
67 changes: 52 additions & 15 deletions src/rules/numberLiteralFormatRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export class Rule extends Lint.Rules.AbstractRule {
/* tslint:disable:object-literal-sort-keys */
public static metadata: Lint.IRuleMetadata = {
ruleName: "number-literal-format",
hasFix: true,
description:
"Checks that decimal literals should begin with '0.' instead of just '.', and should not end with a trailing '0'.",
optionsDescription: "Not configurable.",
Expand Down Expand Up @@ -63,6 +64,7 @@ function walk(ctx: Lint.WalkContext<void>): void {
function check(node: ts.NumericLiteral): void {
// Apparently the number literal '0.0' has a '.text' of '0', so use '.getText()' instead.
const text = node.getText(sourceFile);
const start = node.getStart();

if (text.length <= 1) {
return;
Expand All @@ -72,8 +74,14 @@ function walk(ctx: Lint.WalkContext<void>): void {
// Hex/octal/binary number can't have decimal point or exponent, so no other errors possible.
switch (text[1]) {
case "x":
if (!isUpperCase(text.slice(2))) {
ctx.addFailureAtNode(node, Rule.FAILURE_STRING_NOT_UPPERCASE);
// strip "0x"
const hexNumber = text.slice(2);
if (!isUpperCase(hexNumber)) {
ctx.addFailureAtNode(
node,
Rule.FAILURE_STRING_NOT_UPPERCASE,
Lint.Replacement.replaceNode(node, `0x${hexNumber.toUpperCase()}`),
);
}
return;
case "o":
Expand All @@ -82,35 +90,64 @@ function walk(ctx: Lint.WalkContext<void>): void {
case ".":
break;
default:
ctx.addFailureAtNode(node, Rule.FAILURE_STRING_LEADING_0);
ctx.addFailureAtNode(
node,
Rule.FAILURE_STRING_LEADING_0,
Lint.Replacement.deleteFromTo(start, start + /^0+/.exec(text)![0].length),
);
return;
}
}

const [num, exp] = text.split(/e/i);
if (exp !== undefined && (exp.startsWith("-0") || exp.startsWith("0"))) {
ctx.addFailureAt(node.getEnd() - exp.length, exp.length, Rule.FAILURE_STRING_LEADING_0);
const [num, exp = ""] = text.split(/e/i);
const [integer, float = ""] = num.split(".");
const matchedNumeric = /(\.)([1-9]*)(0+)/.exec(num);
const [dot = "", numbers = "", zeroes = ""] = Array.isArray(matchedNumeric)
? matchedNumeric.slice(1)
: [];

if (exp.startsWith("-0") || exp.startsWith("0")) {
const expStart = start + num.length + 1; // position of exp part
const expNumberStart = /\D/.test(exp.charAt(0)) ? expStart + 1 : expStart; // do not remove "-" or "+"
ctx.addFailureAt(
node.getEnd() - exp.length,
exp.length,
Rule.FAILURE_STRING_LEADING_0,
Lint.Replacement.deleteFromTo(
expNumberStart,
expNumberStart + /0+/.exec(exp)![0].length,
),
);
}

if (!num.includes(".")) {
return;
}

if (num.startsWith(".")) {
fail(Rule.FAILURE_STRING_LEADING_DECIMAL);
}

if (num.endsWith(".")) {
fail(Rule.FAILURE_STRING_TRAILING_DECIMAL);
// .1 -> 0.1
fail(Rule.FAILURE_STRING_LEADING_DECIMAL, Lint.Replacement.appendText(start, "0"));
} else if (num.endsWith(".")) {
// 1. -> 1
fail(
Rule.FAILURE_STRING_TRAILING_DECIMAL,
Lint.Replacement.deleteText(start + num.length - 1, 1),
);
}

// Allow '10', but not '1.0'
if (num.endsWith("0")) {
fail(Rule.FAILURE_STRING_TRAILING_0);
if (float.endsWith("0")) {
// 1.0 -> 1
const offset = numbers.length > 0 ? dot.length + numbers.length : 0;
const length = (numbers.length > 0 ? 0 : dot.length) + zeroes.length;
fail(
Rule.FAILURE_STRING_TRAILING_0,
Lint.Replacement.deleteText(start + integer.length + offset, length),
);
}

function fail(message: string): void {
ctx.addFailureAt(node.getStart(sourceFile), num.length, message);
function fail(message: string, fix?: Lint.Replacement | Lint.Replacement[]): void {
ctx.addFailureAt(node.getStart(sourceFile), num.length, message, fix);
}
}
}
45 changes: 45 additions & 0 deletions test/rules/number-literal-format/test.ts.fix
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
0;
0.5;
10;
1.1e10;

-6000;

-777;

-0;

-0.9;

-0.2;

-0.5;

-123e3;

-145E4;

-1467e-8;

-189e10;

-0xDEADBEEF;

1;

1

0;
0.5;

0.5;

0.5;

1e1;
1E1;
1e-1;
1e10;

0xDEADBEEF;

34 changes: 34 additions & 0 deletions test/rules/number-literal-format/test.ts.lint
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,40 @@
10;
1.1e10;

-0000006000;
~~~~~~~~~~ [leading-0]

-777.;
~~~~ [trailing-decimal]

-0.000;
~~~~~ [trailing-0]

-0.90000;
~~~~~~~ [trailing-0]

-.2;
~~ [leading-decimal]

-.50000;
~~~~~~ [trailing-0]
~~~~~~ [leading-decimal]

-123e0003;
~~~~ [leading-0]

-145E0004;
~~~~ [leading-0]

-1467e-0008;
~~~~~ [leading-0]

-189.000e10;
~~~~~~~ [trailing-0]

-0xDEAdBEEF;
~~~~~~~~~~ [uppercase]

01;
~~ [leading-0]

Expand Down

0 comments on commit 44febf9

Please sign in to comment.