From d27482e2fc9a78e4c947ffe106f42ea40bc425af Mon Sep 17 00:00:00 2001 From: Simon Lydell Date: Mon, 30 Jan 2017 18:36:23 +0100 Subject: [PATCH] Print numbers in a uniform way (#498) * Print numbers in a uniform way - Still preserve the radix (binary, octal, hexadecimal or decimal) used in the original source code. - Still preserve scientific notation. - Add 0 to fractions. `.1` -> `0.1` - Remove trailing dots from integers. `1.` -> `1` - Always print the radix letters lowercase. `0b`, `0o`, `0x` - Always print scientific notation lowercase. `1e1` - Always print hexadecimal digits uppercase. `0x123ABCDEF` - Remove unneeded plus in scientific notation. `1e+1` -> `1e1` - Remove unneeded zeroes in scientific notation. `1e-001` -> `1e-1` - Preserve leading zeroes in non-decimal radix. This can be useful when working in binary, and having both `0b111000` and `0b000111` for example. * Always print numbers lowercase * Remove trailing dot in scientific notation * Update snapshots --- src/printer.js | 14 ++- .../unicode/__snapshots__/jsfmt.spec.js.snap | 2 +- .../literal/__snapshots__/jsfmt.spec.js.snap | 106 ++++++++++++++++++ tests/literal/jsfmt.spec.js | 3 +- tests/literal/number.js | 53 +++++++++ 5 files changed, 174 insertions(+), 4 deletions(-) diff --git a/src/printer.js b/src/printer.js index b766f099f..75472aab8 100644 --- a/src/printer.js +++ b/src/printer.js @@ -729,13 +729,13 @@ function genericPrintNoParens(path, options, print) { return n.extra.raw; // Babel 6 Literal split case "NumericLiteral": - return n.extra.raw; + return printNumber(n.extra.raw); // Babel 6 Literal split case "BooleanLiteral": // Babel 6 Literal split case "StringLiteral": case "Literal": - if (typeof n.value === "number") return n.raw; + if (typeof n.value === "number") return printNumber(n.raw); if (typeof n.value !== "string") return "" + n.value; return nodeStr(n, options); // Babel 6 @@ -2523,6 +2523,16 @@ function makeString(rawContent, enclosingQuote) { return enclosingQuote + newContent + enclosingQuote; } +function printNumber(rawNumber) { + return rawNumber.toLowerCase() + // Remove unnecessary plus and zeroes from scientific notation. + .replace(/^([\d.]+e)(?:\+|(-))?0*/, "$1$2") + // Make sure numbers always start with a digit. + .replace(/^\./, "0.") + // Remove trailing dot. + .replace(/\.(?=e|$)/, ""); +} + function isFirstStatement(path) { const parent = path.getParentNode(); const node = path.getValue(); diff --git a/tests/flow/unicode/__snapshots__/jsfmt.spec.js.snap b/tests/flow/unicode/__snapshots__/jsfmt.spec.js.snap index 54ba75502..b89d04cce 100644 --- a/tests/flow/unicode/__snapshots__/jsfmt.spec.js.snap +++ b/tests/flow/unicode/__snapshots__/jsfmt.spec.js.snap @@ -43,7 +43,7 @@ function utf16Length(str, pos) { * @return {boolean} Whether code-unit is in a surrogate (hi/low) range */ function inSurrogateRange(codeUnit) { - return 0xD800 <= codeUnit && codeUnit <= 0xDFFF; + return 0xd800 <= codeUnit && codeUnit <= 0xdfff; } /** diff --git a/tests/literal/__snapshots__/jsfmt.spec.js.snap b/tests/literal/__snapshots__/jsfmt.spec.js.snap index 9ece4dcff..9e26c22ac 100644 --- a/tests/literal/__snapshots__/jsfmt.spec.js.snap +++ b/tests/literal/__snapshots__/jsfmt.spec.js.snap @@ -3,10 +3,116 @@ exports[`test number.js 1`] = ` function test5(): string { return (100).toString(); } + +0 +1 + +0.1 +1.1 + +.1 +1. + +0b1 +0B1 +0o1 +0O1 +0x1 +0X1 + +0x123abcdef456ABCDEF +0X123abcdef456ABCDEF +0xdeadbeef; + +0b111000 +0b000111 +0B111000 +0B000111 +0o111000 +0o000111 +0O111000 +0O000111 +0x111000 +0x000111 +0X111000 +0X000111 + +1e1 +1e+1 +1e-1 +1.e1 +.1e1 +1.1e1 +1.1e0010 +.1e+0010 +.1e-0010 + +1E1 +1E+1 +1E-1 +1.E1 +.1E1 +1.1E1 +1.1E0010 +.1E+0010 +.1E-0010 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // parentheses around numeric literal should be preserved function test5(): string { return (100).toString(); } + +0; +1; + +0.1; +1.1; + +0.1; +1; + +0b1; +0b1; +0o1; +0o1; +0x1; +0x1; + +0x123abcdef456abcdef; +0x123abcdef456abcdef; +0xdeadbeef; + +0b111000; +0b000111; +0b111000; +0b000111; +0o111000; +0o000111; +0o111000; +0o000111; +0x111000; +0x000111; +0x111000; +0x000111; + +1e1; +1e1; +1e-1; +1e1; +0.1e1; +1.1e1; +1.1e10; +0.1e10; +0.1e-10; + +1e1; +1e1; +1e-1; +1e1; +0.1e1; +1.1e1; +1.1e10; +0.1e10; +0.1e-10; " `; diff --git a/tests/literal/jsfmt.spec.js b/tests/literal/jsfmt.spec.js index 989047bcc..c2c47fa7f 100644 --- a/tests/literal/jsfmt.spec.js +++ b/tests/literal/jsfmt.spec.js @@ -1 +1,2 @@ -run_spec(__dirname); +// flow-parser@0.38.0 fails to parse `1.e1`, so use babylon here. +run_spec(__dirname, { parser: "babylon" }); diff --git a/tests/literal/number.js b/tests/literal/number.js index 4184bf11c..c39990ab2 100644 --- a/tests/literal/number.js +++ b/tests/literal/number.js @@ -2,3 +2,56 @@ function test5(): string { return (100).toString(); } + +0 +1 + +0.1 +1.1 + +.1 +1. + +0b1 +0B1 +0o1 +0O1 +0x1 +0X1 + +0x123abcdef456ABCDEF +0X123abcdef456ABCDEF +0xdeadbeef; + +0b111000 +0b000111 +0B111000 +0B000111 +0o111000 +0o000111 +0O111000 +0O000111 +0x111000 +0x000111 +0X111000 +0X000111 + +1e1 +1e+1 +1e-1 +1.e1 +.1e1 +1.1e1 +1.1e0010 +.1e+0010 +.1e-0010 + +1E1 +1E+1 +1E-1 +1.E1 +.1E1 +1.1E1 +1.1E0010 +.1E+0010 +.1E-0010