Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update: support numeric-separator in no-loss-of-precision (refs #13568) #13574

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/rules/no-loss-of-precision.md
Expand Up @@ -16,6 +16,7 @@ const x = 5123000000000000000000000000001
const x = 1230000000000000000000000.0
const x = .1230000000000000000000000
const x = 0X20000000000001
const x = 0X2_000000000_0001;
```

Examples of **correct** code for this rule:
Expand All @@ -29,4 +30,5 @@ const x = 123e34
const x = 12300000000000000000000000
const x = 0x1FFFFFFFFFFFFF
const x = 9007199254740991
const x = 9007_1992547409_91
```
12 changes: 10 additions & 2 deletions lib/rules/no-loss-of-precision.js
Expand Up @@ -36,6 +36,14 @@ module.exports = {
return typeof node.value === "number";
}

/**
* Gets the source code of the given number literal. Removes `_` numeric separators from the result.
* @param {Node} node the number `Literal` node
* @returns {string} raw source code of the literal, without numeric separators
*/
function getRaw(node) {
return node.raw.replace(/_/gu, "");
}

/**
* Checks whether the number is base ten
Expand All @@ -55,7 +63,7 @@ module.exports = {
* @returns {boolean} true if they do not match
*/
function notBaseTenLosesPrecision(node) {
const rawString = node.raw.toUpperCase();
const rawString = getRaw(node).toUpperCase();
let base = 0;

if (rawString.startsWith("0B")) {
Expand Down Expand Up @@ -161,7 +169,7 @@ module.exports = {
* @returns {boolean} true if they do not match
*/
function baseTenLosesPrecision(node) {
const normalizedRawNumber = convertNumberToScientificNotation(node.raw);
const normalizedRawNumber = convertNumberToScientificNotation(getRaw(node));
const requestedPrecision = normalizedRawNumber.split("e")[0].replace(".", "").length;

if (requestedPrecision > 100) {
Expand Down
122 changes: 118 additions & 4 deletions tests/lib/rules/no-loss-of-precision.js
Expand Up @@ -47,14 +47,33 @@ ruleTester.run("no-loss-of-precision", rule, {
"var x = 0195",
"var x = 0e5",

{ code: "var x = 12_34_56", parserOptions: { ecmaVersion: 2021 } },
{ code: "var x = 12_3.4_56", parserOptions: { ecmaVersion: 2021 } },
{ code: "var x = -12_3.4_56", parserOptions: { ecmaVersion: 2021 } },
{ code: "var x = -12_34_56", parserOptions: { ecmaVersion: 2021 } },
{ code: "var x = 12_3e3_4", parserOptions: { ecmaVersion: 2021 } },
{ code: "var x = 123.0e3_4", parserOptions: { ecmaVersion: 2021 } },
{ code: "var x = 12_3e-3_4", parserOptions: { ecmaVersion: 2021 } },
{ code: "var x = 12_3.0e-3_4", parserOptions: { ecmaVersion: 2021 } },
{ code: "var x = -1_23e-3_4", parserOptions: { ecmaVersion: 2021 } },
{ code: "var x = -1_23.8e-3_4", parserOptions: { ecmaVersion: 2021 } },
{ code: "var x = 1_230000000_00000000_00000_000", parserOptions: { ecmaVersion: 2021 } },
{ code: "var x = -1_230000000_00000000_00000_000", parserOptions: { ecmaVersion: 2021 } },
{ code: "var x = 0.0_00_000000000_000000000_00123", parserOptions: { ecmaVersion: 2021 } },
{ code: "var x = -0.0_00_000000000_000000000_00123", parserOptions: { ecmaVersion: 2021 } },
{ code: "var x = 0e5_3", parserOptions: { ecmaVersion: 2021 } },

{ code: "var x = 0b11111111111111111111111111111111111111111111111111111", parserOptions: { ecmaVersion: 6 } },
{ code: "var x = 0b111_111_111_111_1111_11111_111_11111_1111111111_11111111_111_111", parserOptions: { ecmaVersion: 2021 } },

{ code: "var x = 0B11111111111111111111111111111111111111111111111111111", parserOptions: { ecmaVersion: 6 } },
{ code: "var x = 0B111_111_111_111_1111_11111_111_11111_1111111111_11111111_111_111", parserOptions: { ecmaVersion: 2021 } },

{ code: "var x = 0o377777777777777777", parserOptions: { ecmaVersion: 6 } },
{ code: "var x = 0o3_77_777_777_777_777_777", parserOptions: { ecmaVersion: 2021 } },
{ code: "var x = 0O377777777777777777", parserOptions: { ecmaVersion: 6 } },
"var x = 0377777777777777777",

"var x = 0377777777777777777",
"var x = 0x1FFFFFFFFFFFFF",
"var x = 0X1FFFFFFFFFFFFF",
"var x = true",
Expand All @@ -65,8 +84,10 @@ ruleTester.run("no-loss-of-precision", rule, {
"var x = {}",
"var x = ['a', 'b']",
"var x = new Date()",
"var x = '9007199254740993'"
"var x = '9007199254740993'",

{ code: "var x = 0x1FFF_FFFF_FFF_FFF", parserOptions: { ecmaVersion: 2021 } },
{ code: "var x = 0X1_FFF_FFFF_FFF_FFF", parserOptions: { ecmaVersion: 2021 } }
],
invalid: [
{
Expand All @@ -93,7 +114,36 @@ ruleTester.run("no-loss-of-precision", rule, {
code: "var x = -900719.9254740994",
errors: [{ messageId: "noLossOfPrecision" }]
},

{
code: "var x = 900719925474099_3",
parserOptions: { ecmaVersion: 2021 },
errors: [{ messageId: "noLossOfPrecision" }]
},
{
code: "var x = 90_0719925_4740.9_93e3",
parserOptions: { ecmaVersion: 2021 },
errors: [{ messageId: "noLossOfPrecision" }]
},
{
code: "var x = 9.0_0719925_474099_3e15",
parserOptions: { ecmaVersion: 2021 },
errors: [{ messageId: "noLossOfPrecision" }]
},
{
code: "var x = -9_00719_9254_740993",
parserOptions: { ecmaVersion: 2021 },
errors: [{ messageId: "noLossOfPrecision" }]
},
{
code: "var x = 900_719.92_54740_994",
parserOptions: { ecmaVersion: 2021 },
errors: [{ messageId: "noLossOfPrecision" }]
},
{
code: "var x = -900_719.92_5474_0994",
parserOptions: { ecmaVersion: 2021 },
errors: [{ messageId: "noLossOfPrecision" }]
},
{
code: "var x = 5123000000000000000000000000001",
errors: [{ messageId: "noLossOfPrecision" }]
Expand Down Expand Up @@ -153,7 +203,71 @@ ruleTester.run("no-loss-of-precision", rule, {
{
code: "var x = 0X20000000000001",
errors: [{ messageId: "noLossOfPrecision" }]
},
{
code: "var x = 5123_00000000000000000000000000_1",
parserOptions: { ecmaVersion: 2021 },
errors: [{ messageId: "noLossOfPrecision" }]
},
{
code: "var x = -5_12300000000000000000000_0000001",
parserOptions: { ecmaVersion: 2021 },
errors: [{ messageId: "noLossOfPrecision" }]
},
{
code: "var x = 123_00000000000000000000_00.0_0",
parserOptions: { ecmaVersion: 2021 },
errors: [{ messageId: "noLossOfPrecision" }]
},
{
code: "var x = 1.0_00000000000000000_0000123",
parserOptions: { ecmaVersion: 2021 },
errors: [{ messageId: "noLossOfPrecision" }]
},
{
code: "var x = 174_980057982_640953949800178169_409709228253554471456994_914061648512796239935950073857881054_1618443059_2",
parserOptions: { ecmaVersion: 2021 },
errors: [{ messageId: "noLossOfPrecision" }]
},
{
code: "var x = 2e9_99",
parserOptions: { ecmaVersion: 2021 },
errors: [{ messageId: "noLossOfPrecision" }]
},
{
code: "var x = .1_23000000000000_00000_0000_0",
parserOptions: { ecmaVersion: 2021 },
errors: [{ messageId: "noLossOfPrecision" }]
},
{
code: "var x = 0b1_0000000000000000000000000000000000000000000000000000_1",
parserOptions: { ecmaVersion: 2021 },
errors: [{ messageId: "noLossOfPrecision" }]
},
{
code: "var x = 0B10000000000_0000000000000000000000000000_000000000000001",
parserOptions: { ecmaVersion: 2021 },
errors: [{ messageId: "noLossOfPrecision" }]
},
{
code: "var x = 0o4_00000000000000_001",
parserOptions: { ecmaVersion: 2021 },
errors: [{ messageId: "noLossOfPrecision" }]
},
{
code: "var x = 0O4_0000000000000000_1",
parserOptions: { ecmaVersion: 2021 },
errors: [{ messageId: "noLossOfPrecision" }]
},
{
code: "var x = 0x2_0000000000001",
parserOptions: { ecmaVersion: 2021 },
errors: [{ messageId: "noLossOfPrecision" }]
},
{
code: "var x = 0X200000_0000000_1",
parserOptions: { ecmaVersion: 2021 },
errors: [{ messageId: "noLossOfPrecision" }]
}

]
});