diff --git a/changelog_unreleased/javascript/pr-8901.md b/changelog_unreleased/javascript/pr-8901.md new file mode 100644 index 000000000..e27ba1633 --- /dev/null +++ b/changelog_unreleased/javascript/pr-8901.md @@ -0,0 +1,16 @@ +#### Support Decimal Proposal ([#8901](https://github.com/prettier/prettier/pull/8901) by [@fisker](https://github.com/fisker)) + +Support Stage-1 proposal [Decimal Proposal](https://github.com/tc39/proposal-decimal). + + +```js +// Input +0.3m; + +// Prettier stable +SyntaxError: Identifier directly after number (1:4) +> 1 | 0.3m; + +// Prettier master +0.3m; +``` diff --git a/src/language-js/clean.js b/src/language-js/clean.js index 5704aff18..4fb52ec9f 100644 --- a/src/language-js/clean.js +++ b/src/language-js/clean.js @@ -27,6 +27,10 @@ function clean(ast, newObj, parent) { newObj.value = newObj.value.toLowerCase(); } + if (ast.type === "DecimalLiteral") { + newObj.value = Number(newObj.value); + } + // We remove extra `;` and add them when needed if (ast.type === "EmptyStatement") { return null; diff --git a/src/language-js/parser-babel.js b/src/language-js/parser-babel.js index c3a9b7326..e0a2f6d06 100644 --- a/src/language-js/parser-babel.js +++ b/src/language-js/parser-babel.js @@ -33,6 +33,7 @@ function babelOptions({ sourceType, extraPlugins = [] }) { "privateIn", ["moduleAttributes", { version: "may-2020" }], ["recordAndTuple", { syntaxType: "hash" }], + "decimal", ...extraPlugins, ], tokens: true, diff --git a/src/language-js/printer-estree.js b/src/language-js/printer-estree.js index bf5d31f0d..5f28d07a2 100644 --- a/src/language-js/printer-estree.js +++ b/src/language-js/printer-estree.js @@ -1424,6 +1424,8 @@ function printPathNoParens(path, options, print, args) { return printRegex(n); case "NumericLiteral": // Babel 6 Literal split return printNumber(n.extra.raw); + case "DecimalLiteral": + return printNumber(n.value) + "m"; case "BigIntLiteral": // babel: n.extra.raw, flow: n.bigint return (n.bigint || n.extra.raw).toLowerCase(); diff --git a/src/language-js/utils.js b/src/language-js/utils.js index 362656a51..063cf3eab 100644 --- a/src/language-js/utils.js +++ b/src/language-js/utils.js @@ -146,6 +146,7 @@ function isLiteral(node) { node.type === "NullLiteral" || node.type === "NumericLiteral" || node.type === "BigIntLiteral" || + node.type === "DecimalLiteral" || node.type === "RegExpLiteral" || node.type === "StringLiteral" || node.type === "TemplateLiteral" || @@ -904,6 +905,7 @@ function isSimpleCallArgument(node, depth) { if ( node.type === "Literal" || node.type === "BigIntLiteral" || + node.type === "DecimalLiteral" || node.type === "BooleanLiteral" || node.type === "NullLiteral" || node.type === "NumericLiteral" || diff --git a/tests/js/babel-plugins/__snapshots__/jsfmt.spec.js.snap b/tests/js/babel-plugins/__snapshots__/jsfmt.spec.js.snap index 6c75679f5..40076372a 100644 --- a/tests/js/babel-plugins/__snapshots__/jsfmt.spec.js.snap +++ b/tests/js/babel-plugins/__snapshots__/jsfmt.spec.js.snap @@ -356,6 +356,69 @@ console.log(Bork.staticFunction()); // > "babelIsCool" ================================================================================ `; +exports[`decimal.js format 1`] = ` +====================================options===================================== +parsers: ["babel", "babel-ts", "babel-flow"] +printWidth: 80 + | printWidth +=====================================input====================================== +// https://github.com/babel/babel/pull/11640 + +100m; +9223372036854775807m; +0.m; +3.1415926535897932m; +100.000m; +.1m; +({ 0m: 0, .1m() {}, get 0.2m(){}, set 3m(_){}, async 4m() {}, *.5m() {} }); +1.m; +100m; +9223372036854775807m; +100.m; + +// Invalid decimal +2e9m; +016432m; +089m; + +// https://github.com/tc39/proposal-decimal +.1m + .2m === .3m; +2.00m; +-0m; +typeof 1m === "bigdecimal"; +typeof 1m === "decimal128"; + + +=====================================output===================================== +// https://github.com/babel/babel/pull/11640 + +100m; +9223372036854775807m; +0m; +3.1415926535897932m; +100.0m; +0.1m; +({ 0m: 0, 0.1m() {}, get 0.2m() {}, set 3m(_) {}, async 4m() {}, *0.5m() {} }); +1m; +100m; +9223372036854775807m; +100m; + +// Invalid decimal +2e9m; +016432m; +089m; + +// https://github.com/tc39/proposal-decimal +0.1m + 0.2m === 0.3m; +2.0m; +-0m; +typeof 1m === "bigdecimal"; +typeof 1m === "decimal128"; + +================================================================================ +`; + exports[`decorators.js format 1`] = ` ====================================options===================================== parsers: ["babel", "babel-ts", "babel-flow"] diff --git a/tests/js/babel-plugins/decimal.js b/tests/js/babel-plugins/decimal.js new file mode 100644 index 000000000..1d2b96ca8 --- /dev/null +++ b/tests/js/babel-plugins/decimal.js @@ -0,0 +1,26 @@ +// https://github.com/babel/babel/pull/11640 + +100m; +9223372036854775807m; +0.m; +3.1415926535897932m; +100.000m; +.1m; +({ 0m: 0, .1m() {}, get 0.2m(){}, set 3m(_){}, async 4m() {}, *.5m() {} }); +1.m; +100m; +9223372036854775807m; +100.m; + +// Invalid decimal +2e9m; +016432m; +089m; + +// https://github.com/tc39/proposal-decimal +.1m + .2m === .3m; +2.00m; +-0m; +typeof 1m === "bigdecimal"; +typeof 1m === "decimal128"; + diff --git a/tests/misc/errors/js/__snapshots__/jsfmt.spec.js.snap b/tests/misc/errors/js/__snapshots__/jsfmt.spec.js.snap index 66d639967..d5b7068fa 100644 --- a/tests/misc/errors/js/__snapshots__/jsfmt.spec.js.snap +++ b/tests/misc/errors/js/__snapshots__/jsfmt.spec.js.snap @@ -93,6 +93,24 @@ exports[`snippet: #9 error test 1`] = ` | ^" `; +exports[`snippet: #10 error test 1`] = ` +"Invalid decimal (1:1) +> 1 | 0b101011101m; + | ^" +`; + +exports[`snippet: #11 error test 1`] = ` +"Invalid decimal (1:1) +> 1 | 0x16432m; + | ^" +`; + +exports[`snippet: #12 error test 1`] = ` +"Invalid decimal (1:1) +> 1 | 0o16432m; + | ^" +`; + exports[`static-import-source-should-not-has-extra-token.js error test 1`] = ` "Unexpected token (4:16) 2 | // be parenthesized, that accidentally break #8016 diff --git a/tests/misc/errors/js/jsfmt.spec.js b/tests/misc/errors/js/jsfmt.spec.js index 76be2ae78..043451a7f 100644 --- a/tests/misc/errors/js/jsfmt.spec.js +++ b/tests/misc/errors/js/jsfmt.spec.js @@ -39,6 +39,11 @@ run_spec( // Don't support `syntaxType: "bar"` "[| 1 |]", // "{| a: 1 |}", // babel didn't throw on this + + // Invalid decimal + "0b101011101m;", + "0x16432m;", + "0o16432m;", ], }, ["babel"]