From 624d89e7a5c5cff3a4db949ea6d48f01acfa4b46 Mon Sep 17 00:00:00 2001 From: Lucas Azzola Date: Mon, 16 Oct 2017 09:13:25 +1100 Subject: [PATCH] Print pipeline and nullish-coalescing operators (#3036) --- src/fast-path.js | 2 +- src/parser-babylon.js | 4 +- src/printer.js | 16 ++++-- src/util.js | 3 +- .../__snapshots__/jsfmt.spec.js.snap | 36 +++++++++++++ tests/nullish_coalescing/jsfmt.spec.js | 1 + .../nullish_coalesing_operator.js | 15 ++++++ .../__snapshots__/jsfmt.spec.js.snap | 52 +++++++++++++++++++ tests/pipeline_operator/jsfmt.spec.js | 1 + tests/pipeline_operator/pipeline_operator.js | 24 +++++++++ 10 files changed, 146 insertions(+), 8 deletions(-) create mode 100644 tests/nullish_coalescing/__snapshots__/jsfmt.spec.js.snap create mode 100644 tests/nullish_coalescing/jsfmt.spec.js create mode 100644 tests/nullish_coalescing/nullish_coalesing_operator.js create mode 100644 tests/pipeline_operator/__snapshots__/jsfmt.spec.js.snap create mode 100644 tests/pipeline_operator/jsfmt.spec.js create mode 100644 tests/pipeline_operator/pipeline_operator.js diff --git a/src/fast-path.js b/src/fast-path.js index 9d1d5e9d5..96abe0ce9 100644 --- a/src/fast-path.js +++ b/src/fast-path.js @@ -334,7 +334,7 @@ FastPath.prototype.needsParens = function(options) { return true; } - if (po === "||" && no === "&&") { + if ((po === "||" || po === "??") && no === "&&") { return true; } diff --git a/src/parser-babylon.js b/src/parser-babylon.js index 400366c49..4226aa23d 100644 --- a/src/parser-babylon.js +++ b/src/parser-babylon.js @@ -26,7 +26,9 @@ function parse(text, parsers, opts) { "importMeta", "optionalCatchBinding", "optionalChaining", - "classPrivateProperties" + "classPrivateProperties", + "pipelineOperator", + "nullishCoalescingOperator" ] }; diff --git a/src/printer.js b/src/printer.js index 780dd2102..c2cdb79a7 100644 --- a/src/printer.js +++ b/src/printer.js @@ -4359,11 +4359,17 @@ function printBinaryishExpressions( parts.push(path.call(print, "left")); } - const right = concat([ - node.operator, - shouldInlineLogicalExpression(node) ? " " : line, - path.call(print, "right") - ]); + const shouldInline = shouldInlineLogicalExpression(node); + const lineBeforeOperator = node.operator === "|>"; + + const right = shouldInline + ? concat([node.operator, " ", path.call(print, "right")]) + : concat([ + lineBeforeOperator ? softline : "", + node.operator, + lineBeforeOperator ? " " : line, + path.call(print, "right") + ]); // If there's only a single binary expression, we want to create a group // in order to avoid having a small right part like -1 be on its own line. diff --git a/src/util.js b/src/util.js index 25bdea47d..704428b16 100644 --- a/src/util.js +++ b/src/util.js @@ -301,7 +301,8 @@ function setLocEnd(node, index) { const PRECEDENCE = {}; [ - ["||"], + ["|>"], + ["||", "??"], ["&&"], ["|"], ["^"], diff --git a/tests/nullish_coalescing/__snapshots__/jsfmt.spec.js.snap b/tests/nullish_coalescing/__snapshots__/jsfmt.spec.js.snap new file mode 100644 index 000000000..e11e17b0e --- /dev/null +++ b/tests/nullish_coalescing/__snapshots__/jsfmt.spec.js.snap @@ -0,0 +1,36 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`nullish_coalesing_operator.js 1`] = ` +obj.foo ?? "default"; + +const x = (foo, bar = foo ?? bar) => {}; + +foo ? bar ?? foo : baz; + +foo ?? (bar ?? baz); + +foo ?? baz || baz; + +(foo && baz) ?? baz; +foo && (baz ?? baz); + +foo |> (bar ?? baz); +(foo |> bar) ?? baz; +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +obj.foo ?? "default"; + +const x = (foo, bar = foo ?? bar) => {}; + +foo ? bar ?? foo : baz; + +foo ?? (bar ?? baz); + +foo ?? baz || baz; + +(foo && baz) ?? baz; +foo && (baz ?? baz); + +foo |> bar ?? baz; +(foo |> bar) ?? baz; + +`; diff --git a/tests/nullish_coalescing/jsfmt.spec.js b/tests/nullish_coalescing/jsfmt.spec.js new file mode 100644 index 000000000..f974ed6c7 --- /dev/null +++ b/tests/nullish_coalescing/jsfmt.spec.js @@ -0,0 +1 @@ +run_spec(__dirname, { parser: "babylon" }); diff --git a/tests/nullish_coalescing/nullish_coalesing_operator.js b/tests/nullish_coalescing/nullish_coalesing_operator.js new file mode 100644 index 000000000..d56e001fc --- /dev/null +++ b/tests/nullish_coalescing/nullish_coalesing_operator.js @@ -0,0 +1,15 @@ +obj.foo ?? "default"; + +const x = (foo, bar = foo ?? bar) => {}; + +foo ? bar ?? foo : baz; + +foo ?? (bar ?? baz); + +foo ?? baz || baz; + +(foo && baz) ?? baz; +foo && (baz ?? baz); + +foo |> (bar ?? baz); +(foo |> bar) ?? baz; diff --git a/tests/pipeline_operator/__snapshots__/jsfmt.spec.js.snap b/tests/pipeline_operator/__snapshots__/jsfmt.spec.js.snap new file mode 100644 index 000000000..a2af7f4e0 --- /dev/null +++ b/tests/pipeline_operator/__snapshots__/jsfmt.spec.js.snap @@ -0,0 +1,52 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`pipeline_operator.js 1`] = ` +a |> b |> c; + +a |> (b |> c); + +(a |> b) || c; +a |> (b || c); + +let result = "hello" + |> doubleSay + |> capitalize + |> exclaim; + +let newScore = person.score + |> double + |> (_ => add(7, _)) + |> (_ => subtract(2, _)) + |> (_ => boundScore(0, 100, _)); + +function createPerson (attrs) { + attrs + |> bounded('age', 1, 100) + |> format('name', /^[a-z]$/i) + |> Person.insertIntoDatabase; +} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +a |> b |> c; + +a |> (b |> c); + +(a |> b) || c; +a |> b || c; + +let result = "hello" |> doubleSay |> capitalize |> exclaim; + +let newScore = + person.score + |> double + |> (_ => add(7, _)) + |> (_ => subtract(2, _)) + |> (_ => boundScore(0, 100, _)); + +function createPerson(attrs) { + attrs + |> bounded("age", 1, 100) + |> format("name", /^[a-z]$/i) + |> Person.insertIntoDatabase; +} + +`; diff --git a/tests/pipeline_operator/jsfmt.spec.js b/tests/pipeline_operator/jsfmt.spec.js new file mode 100644 index 000000000..f974ed6c7 --- /dev/null +++ b/tests/pipeline_operator/jsfmt.spec.js @@ -0,0 +1 @@ +run_spec(__dirname, { parser: "babylon" }); diff --git a/tests/pipeline_operator/pipeline_operator.js b/tests/pipeline_operator/pipeline_operator.js new file mode 100644 index 000000000..57ccee0f9 --- /dev/null +++ b/tests/pipeline_operator/pipeline_operator.js @@ -0,0 +1,24 @@ +a |> b |> c; + +a |> (b |> c); + +(a |> b) || c; +a |> (b || c); + +let result = "hello" + |> doubleSay + |> capitalize + |> exclaim; + +let newScore = person.score + |> double + |> (_ => add(7, _)) + |> (_ => subtract(2, _)) + |> (_ => boundScore(0, 100, _)); + +function createPerson (attrs) { + attrs + |> bounded('age', 1, 100) + |> format('name', /^[a-z]$/i) + |> Person.insertIntoDatabase; +}