Repository: prettier/prettier (JavaScript)
Date: 2018-08-24 14:24:52+00:00
Task type: Bug Fix

Issue:
Pipe operator with comment problem
**Prettier 1.14.2**
[Playground link](https://prettier.io/playground/#N4Igxg9gdgLgprEAuEAdKcAeAHCAnGAAgBM4AzAQwFcAbIgYQgFtcNZ1DCB6LwgHwB8hAEZ4KUMAAsAFNjwRsAUQCO0gOQBLAM4AlOBWIBPNQBpClGlrgBKM3gSk8AOQgxJGqAHNrHfkMhQGGAw0r6cYPYU8ADKMHhUwVT2xNFwNHDB+NLAYZyE2noGhia5AL62vtYA3OggJiAKMBrQWsigFHjyAO4ACh0IrSgUAG4QGsR1IKIUYADWcDDR2DMenshxVHD1HlYEPWKeTBTIFlb1AFZamABCYnML0RRMcAAyHnAnFJZbIMt4u8gphRhIYaNBJnIPDAAOrjNzIAAcAAZ6nIIFZoWJsIC5HBdsMPvV7MoqBp7PsKIdjkhTj8rEwNOt4nTVukAIpUVwfGlfM4gGDA2HEeFIABM9TiFA0NFWjCYR0BUGghJAVCsABVgYNaaVSkA)
```sh
--parser babylon
```

**Input:**
```jsx

export default Component
  // |> branch(propEq('isReady', false), renderNothing)
  |> connect(
    createStructuredSelector({
      isReady,
    }),
  );

```

**Output:**
```jsx
export default Component
  |> // |> branch(propEq('isReady', false), renderNothing)
  connect(
    createStructuredSelector({
      isReady
    })
  );

```

**Expected behavior:**
(no change)
```jsx

export default Component
  // |> branch(propEq('isReady', false), renderNothing)
  |> connect(
    createStructuredSelector({
      isReady,
    }),
  );

```


Issue discussion:
Thanks for opening an issue @sylvainbaronnet! Can you fill out the “expected behavior” section of the issue?
Sure, I did it
Hey @j-f1 , I'd love to start contributing to Prettier :) And this sounds like a quite doable task, so I'd like to take on this!
However, it'd be quite cool to have some help from a maintainer here! 😊
@flxwu Welcome to Prettier!

This issue is caused by how we *attach* comments to nodes. In this process, we essentially specify that each comment comes before or after a specific node. This allows us to print them in the correct place. [`src/language-js/comments.js`](https://github.com/prettier/prettier/blob/master/src/language-js/comments.js) is the file where that work happens. Since this comment is on its own line, you’d probably need to add a new condition to the [`handleOwnLineComment`](https://github.com/prettier/prettier/blob/58d34bb8447695f257ca307c8670d43277ddb6e3/src/language-js/comments.js#L11) function.
Thanks! @j-f1 I'll take a look at it.

How do I properly do "test formats", so how can I see live how my changes format this block?
```
export default Component
  // |> branch(propEq('isReady', false), renderNothing)
  |> connect(
    createStructuredSelector({
      isReady,
    }),
  );
``` 

As well as how to debug it? Can I just add a `console.log` in the `handleOwnLineComment` function?

Thanks in advance! 😊
@flxwu One way of doing it is put your code you want to test format in `test.js` and running `./bin/prettier.js test.js`.
Thanks for the hint! @lydell . I now added the additional condition for this operator, but however I am a bit wondering whether 

```javascript
export default Component
  // |> branch(propEq('isReady', false), renderNothing)
  |> connect(
    createStructuredSelector({
      isReady,
    }),
  );
```
should really stay the same as @sylvainbaronnet suggests, because |>, just like Prettier does with any other binary expression like `*`, should be appended to `Component`, resulting in:

```js
export default Component |>
  // |> branch(propEq('isReady', false), renderNothing)
  connect(
    createStructuredSelector({
      isReady,
    }),
  );
```
after formatting, or not?
I don't think so, at least currently it doesn't
And it seems like line 5207 in `printer-estree.js` is causing the observed error:
```
    const lineBeforeOperator = node.operator === "|>";
```

This constant being true leads to the pipeline operator being put inline, i.e. in front of the ownLineComment.
@sylvainbaronnet Yeah it currently doesn't because it doesn't treat `|>` same like the other binary expressions like `*`, `+` etc. although IMHO it should, because

```js
export default Component
  // |> branch(propEq('isReady', false), renderNothing)
  * connect(
    createStructuredSelector({
      isReady,
    }),
  );
```

gets formatted to:
```js
export default Component *
  // |> branch(propEq('isReady', false), renderNothing)
  connect(
    createStructuredSelector({
      isReady,
    }),
  );
```

I think same should happen with the pipeline operator. cc @j-f1 @lydell 

Solution patch:
diff --git a/src/language-js/printer-estree.js b/src/language-js/printer-estree.js
index 025dae381ad0..53bc85efe050 100644
--- a/src/language-js/printer-estree.js
+++ b/src/language-js/printer-estree.js
@@ -5204,7 +5204,9 @@ function printBinaryishExpressions(
     }
 
     const shouldInline = shouldInlineLogicalExpression(node);
-    const lineBeforeOperator = node.operator === "|>";
+    const lineBeforeOperator =
+      node.operator === "|>" &&
+      !hasLeadingOwnLineComment(options.originalText, node.right, options);
 
     const right = shouldInline
       ? concat([node.operator, " ", path.call(print, "right")])


Test patch:
diff --git a/tests/comments/__snapshots__/jsfmt.spec.js.snap b/tests/comments/__snapshots__/jsfmt.spec.js.snap
index 5e6bdde5118e..d094b02bede0 100644
--- a/tests/comments/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/comments/__snapshots__/jsfmt.spec.js.snap
@@ -35,6 +35,153 @@ const foo = {
 
 `;
 
+exports[`binary-expressions.js - flow-verify 1`] = `
+function addition() {
+	0
+	// Comment
+	+ x
+}
+
+function multiplication() {
+	0
+	// Comment
+	* x
+}
+
+function division() {
+	0
+	// Comment
+	/ x
+}
+
+function substraction() {
+	0
+	// Comment
+	- x
+}
+
+function remainder() {
+	0
+	// Comment
+	% x
+}
+
+function exponentiation() {
+	0
+	// Comment
+	** x
+}
+
+function leftShift() {
+	0
+	// Comment
+	<< x
+}
+
+function rightShift() {
+	0
+	// Comment
+	>> x
+}
+
+function unsignedRightShift() {
+	0
+	// Comment
+	>>> x
+}
+
+function bitwiseAnd() {
+	0
+	// Comment
+	& x
+}
+
+function bitwiseOr() {
+	0
+	// Comment
+	| x
+}
+
+function bitwiseXor() {
+	0
+	// Comment
+	^ x
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+function addition() {
+  0 +
+    // Comment
+    x;
+}
+
+function multiplication() {
+  0 *
+    // Comment
+    x;
+}
+
+function division() {
+  0 /
+    // Comment
+    x;
+}
+
+function substraction() {
+  0 -
+    // Comment
+    x;
+}
+
+function remainder() {
+  0 %
+    // Comment
+    x;
+}
+
+function exponentiation() {
+  0 **
+    // Comment
+    x;
+}
+
+function leftShift() {
+  0 <<
+    // Comment
+    x;
+}
+
+function rightShift() {
+  0 >>
+    // Comment
+    x;
+}
+
+function unsignedRightShift() {
+  0 >>>
+    // Comment
+    x;
+}
+
+function bitwiseAnd() {
+  0 &
+    // Comment
+    x;
+}
+
+function bitwiseOr() {
+  0 |
+    // Comment
+    x;
+}
+
+function bitwiseXor() {
+  0 ^
+    // Comment
+    x;
+}
+
+`;
+
 exports[`blank.js - flow-verify 1`] = `
 // This file only
 // has comments. This comment
diff --git a/tests/comments/binary-expressions.js b/tests/comments/binary-expressions.js
new file mode 100644
index 000000000000..ba1f8b19567c
--- /dev/null
+++ b/tests/comments/binary-expressions.js
@@ -0,0 +1,71 @@
+function addition() {
+	0
+	// Comment
+	+ x
+}
+
+function multiplication() {
+	0
+	// Comment
+	* x
+}
+
+function division() {
+	0
+	// Comment
+	/ x
+}
+
+function substraction() {
+	0
+	// Comment
+	- x
+}
+
+function remainder() {
+	0
+	// Comment
+	% x
+}
+
+function exponentiation() {
+	0
+	// Comment
+	** x
+}
+
+function leftShift() {
+	0
+	// Comment
+	<< x
+}
+
+function rightShift() {
+	0
+	// Comment
+	>> x
+}
+
+function unsignedRightShift() {
+	0
+	// Comment
+	>>> x
+}
+
+function bitwiseAnd() {
+	0
+	// Comment
+	& x
+}
+
+function bitwiseOr() {
+	0
+	// Comment
+	| x
+}
+
+function bitwiseXor() {
+	0
+	// Comment
+	^ x
+}
diff --git a/tests/comments_pipeline_own_line/__snapshots__/jsfmt.spec.js.snap b/tests/comments_pipeline_own_line/__snapshots__/jsfmt.spec.js.snap
new file mode 100644
index 000000000000..2b23ae1c191d
--- /dev/null
+++ b/tests/comments_pipeline_own_line/__snapshots__/jsfmt.spec.js.snap
@@ -0,0 +1,16 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`pipeline_own_line.js - babylon-verify 1`] = `
+function pipeline() {
+	0
+	// Comment
+	|> x
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+function pipeline() {
+  0 |>
+    // Comment
+    x;
+}
+
+`;
diff --git a/tests/comments_pipeline_own_line/jsfmt.spec.js b/tests/comments_pipeline_own_line/jsfmt.spec.js
new file mode 100644
index 000000000000..968651cdbc2c
--- /dev/null
+++ b/tests/comments_pipeline_own_line/jsfmt.spec.js
@@ -0,0 +1,1 @@
+run_spec(__dirname, ["babylon"]);
diff --git a/tests/comments_pipeline_own_line/pipeline_own_line.js b/tests/comments_pipeline_own_line/pipeline_own_line.js
new file mode 100644
index 000000000000..61996b6b7bb2
--- /dev/null
+++ b/tests/comments_pipeline_own_line/pipeline_own_line.js
@@ -0,0 +1,5 @@
+function pipeline() {
+	0
+	// Comment
+	|> x
+}