Skip to content

Commit

Permalink
New: prefer-numeric-literals rule (fixes #6068) (#7029)
Browse files Browse the repository at this point in the history
  • Loading branch information
annie authored and btmills committed Sep 4, 2016
1 parent fa760f9 commit 3960617
Show file tree
Hide file tree
Showing 4 changed files with 159 additions and 0 deletions.
1 change: 1 addition & 0 deletions conf/eslint.json
Expand Up @@ -199,6 +199,7 @@
"padded-blocks": "off",
"prefer-arrow-callback": "off",
"prefer-const": "off",
"prefer-numeric-literals": "off",
"prefer-reflect": "off",
"prefer-rest-params": "off",
"prefer-spread": "off",
Expand Down
49 changes: 49 additions & 0 deletions docs/rules/prefer-numeric-literals.md
@@ -0,0 +1,49 @@
# disallow `parseInt()` in favor of binary, octal, and hexadecimal literals (prefer-numeric-literals)

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
0b111110111 === 503;
0o767 === 503;
```

## Rule Details

This rule disallows `parseInt()` if it is called with two arguments: a string and a radix option of 2 (binary), 8 (octal), or 16 (hexadecimal).

Examples of **incorrect** code for this rule:

```js
/*eslint prefer-numeric-literals: "error"*/

parseInt("111110111", 2) === 503;
parseInt("767", 8) === 503;
parseInt("1F7", 16) === 255;
```

Examples of **correct** code for this rule:

```js
/*eslint prefer-numeric-literals: "error"*/
/*eslint-env es6*/

parseInt(1);
parseInt(1, 3);

0b111110111 === 503;
0o767 === 503;
0x1F7 === 503;

a[parseInt](1,2);

parseInt(foo);
parseInt(foo, 2);
```

## When Not To Use It

If you want to allow use of `parseInt()` for binary, octal, or hexadecimal integers. If you are not using ES6 (because binary and octal literals are not supported in ES5 and below).

## Compatibility

* **JSCS**: [requireNumericLiterals](http://jscs.info/rule/requireNumericLiterals)
62 changes: 62 additions & 0 deletions lib/rules/prefer-numeric-literals.js
@@ -0,0 +1,62 @@
/**
* @fileoverview Rule to disallow `parseInt()` in favor of binary, octal, and hexadecimal literals
* @author Annie Zhang, Henry Zhu
*/

"use strict";

//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------

module.exports = {
meta: {
docs: {
description: "disallow `parseInt()` in favor of binary, octal, and hexadecimal literals",
category: "ECMAScript 6",
recommended: false
},

schema: []
},

create(context) {
const radixMap = {
2: "binary",
8: "octal",
16: "hexadecimal"
};

//--------------------------------------------------------------------------
// Public
//--------------------------------------------------------------------------

return {

CallExpression(node) {

// doesn't check parseInt() if it doesn't have a radix argument
if (node.arguments.length !== 2) {
return;
}

// only error if the radix is 2, 8, or 16
const radixName = radixMap[node.arguments[1].value];

if (node.callee.type === "Identifier" &&
node.callee.name === "parseInt" &&
radixName &&
node.arguments[0].type === "Literal"
) {
context.report({
node,
message: "Use {{radixName}} literals instead of parseInt().",
data: {
radixName
}
});
}
}
};
}
};
47 changes: 47 additions & 0 deletions tests/lib/rules/prefer-numeric-literals.js
@@ -0,0 +1,47 @@
/**
* @fileoverview Tests for prefer-numeric-literals rule.
* @author Annie Zhang
*/

"use strict";

//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------

const rule = require("../../../lib/rules/prefer-numeric-literals"),
RuleTester = require("../../../lib/testers/rule-tester");

//------------------------------------------------------------------------------
// Tests
//------------------------------------------------------------------------------

const ruleTester = new RuleTester();

ruleTester.run("prefer-numeric-literals", rule, {
valid: [
"parseInt(1);",
"parseInt(1, 3);",
{ code: "0b111110111 === 503;", parserOptions: { ecmaVersion: 6 } },
{ code: "0o767 === 503;", parserOptions: { ecmaVersion: 6 } },
"0x1F7 === 503;",
"a[parseInt](1,2);",
"parseInt(foo);",
"parseInt(foo, 2);"
],
invalid: [
{
code: "parseInt(\"111110111\", 2) === 503;",
parserOptions: { ecmaVersion: 6 },
errors: [{ message: "Use binary literals instead of parseInt()." }]
}, {
code: "parseInt(\"767\", 8) === 503;",
parserOptions: { ecmaVersion: 6 },
errors: [{ message: "Use octal literals instead of parseInt()." }]
}, {
code: "parseInt(\"1F7\", 16) === 255;",
parserOptions: { ecmaVersion: 6 },
errors: [{ message: "Use hexadecimal literals instead of parseInt()." }]
}
]
});

0 comments on commit 3960617

Please sign in to comment.