Skip to content

Commit

Permalink
Update: add fixer for prefer-numeric-literals (#7205)
Browse files Browse the repository at this point in the history
  • Loading branch information
not-an-aardvark authored and nzakas committed Sep 30, 2016
1 parent 2f171f3 commit c05a19c
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 1 deletion.
2 changes: 2 additions & 0 deletions docs/rules/prefer-numeric-literals.md
@@ -1,5 +1,7 @@
# disallow `parseInt()` in favor of binary, octal, and hexadecimal literals (prefer-numeric-literals)

(fixable) The `--fix` option on the [command line](../user-guide/command-line-interface#fix) automatically fixes problems reported by this rule.

The `parseInt()` function can be used to turn binary, octal, and hexadecimal strings into integers. As binary, octal, and hexadecimal literals are supported in ES6, this rule encourages use of those numeric literals instead of `parseInt()`.

```js
Expand Down
21 changes: 20 additions & 1 deletion lib/rules/prefer-numeric-literals.js
Expand Up @@ -17,7 +17,9 @@ module.exports = {
recommended: false
},

schema: []
schema: [],

fixable: "code"
},

create(context) {
Expand All @@ -27,6 +29,12 @@ module.exports = {
16: "hexadecimal"
};

const prefixMap = {
2: "0b",
8: "0o",
16: "0x"
};

//--------------------------------------------------------------------------
// Public
//--------------------------------------------------------------------------
Expand All @@ -53,6 +61,17 @@ module.exports = {
message: "Use {{radixName}} literals instead of parseInt().",
data: {
radixName
},
fix(fixer) {
const newPrefix = prefixMap[node.arguments[1].value];

if (+(newPrefix + node.arguments[0].value) !== parseInt(node.arguments[0].value, node.arguments[1].value)) {

// If the newly-produced literal would be invalid, (e.g. 0b1234),
// or it would yield an incorrect parseInt result for some other reason, don't make a fix.
return null;
}
return fixer.replaceText(node, prefixMap[node.arguments[1].value] + node.arguments[0].value);
}
});
}
Expand Down
23 changes: 23 additions & 0 deletions tests/lib/rules/prefer-numeric-literals.js
Expand Up @@ -32,16 +32,39 @@ ruleTester.run("prefer-numeric-literals", rule, {
invalid: [
{
code: "parseInt(\"111110111\", 2) === 503;",
output: "0b111110111 === 503;",
parserOptions: { ecmaVersion: 6 },
errors: [{ message: "Use binary literals instead of parseInt()." }]
}, {
code: "parseInt(\"767\", 8) === 503;",
output: "0o767 === 503;",
parserOptions: { ecmaVersion: 6 },
errors: [{ message: "Use octal literals instead of parseInt()." }]
}, {
code: "parseInt(\"1F7\", 16) === 255;",
output: "0x1F7 === 255;",
parserOptions: { ecmaVersion: 6 },
errors: [{ message: "Use hexadecimal literals instead of parseInt()." }]
}, {
code: "parseInt('7999', 8);",
output: "parseInt('7999', 8);", // not fixed, unexpected 9 in parseInt string
parserOptions: { ecmaVersion: 6 },
errors: [{ message: "Use octal literals instead of parseInt()." }]
}, {
code: "parseInt('1234', 2);",
output: "parseInt('1234', 2);", // not fixed, invalid binary string
parserOptions: { ecmaVersion: 6 },
errors: [{ message: "Use binary literals instead of parseInt()." }]
}, {
code: "parseInt('1234.5', 8);",
output: "parseInt('1234.5', 8);", // not fixed, this isn't an integer
parserOptions: { ecmaVersion: 6 },
errors: [{ message: "Use octal literals instead of parseInt()." }]
}, {
code: "parseInt('1️⃣3️⃣3️⃣7️⃣', 16);",
output: "parseInt('1️⃣3️⃣3️⃣7️⃣', 16);", // not fixed, javascript doesn't support emoji literals
parserOptions: { ecmaVersion: 6 },
errors: [{ message: "Use hexadecimal literals instead of parseInt()."}]
}
]
});

0 comments on commit c05a19c

Please sign in to comment.