Repository: prettier/prettier (JavaScript)
Date: 2020-05-31 20:06:21+00:00
Task type: Bug Fix

Issue:
Prettier’s output of JSX edge case fails to parse
**Prettier 2.0.4**
[Playground link](https://prettier.io/playground/#N4Igxg9gdgLgprEAuEAKAPAEwJYDcD0AfAJQAE6pArANwgA0IEADjNtAM7KgCGATrxADuABT4JOKbgBtB3AJ6cGAI17cwAazgwAykzXYoAc2QxeAVzgMAFjAC2UgOpXs8dnrBxt4l3hdzk4OyKIAbscLwwwqqGttzIAGbSYQwAVuwAHgBCqhpa2ty2cAAyBnAJSZYgaenaBoZScACKZhDw5VLJIHq8YbwBStxKcFL0XbwGMA7YmDBWyAAcAAwMTAJhDqpMAatwvbhlDACOLfBRzBIg3OwAtFBwcJgPo7xwx9gvUdwxcUiJHZVhWzYEzmAF1BrNVplX4VBgwQZTGZzJAAJjhqmwUjqAGEILZYgFdpRRmYwgAVQYSP6dXAWACSUEesG0YHGLAAgoztDA5A12mEAL4CoA)
```sh
--parser babel
```

**Input:**
```jsx
(<div/>) < 5;
```

**Output:**
```jsx
<div /> < 5;

```

**Second Output:**
```jsx
SyntaxError: Adjacent JSX elements must be wrapped in an enclosing tag. Did you want a JSX fragment <>...</>? (1:9)
> 1 | <div /> < 5;
    |         ^
  2 | 
```

**Expected behavior:**
Print parens around the JSX like in the input?



Issue discussion:

Solution patch:
diff --git a/changelog_unreleased/javascript/pr-8461.md b/changelog_unreleased/javascript/pr-8461.md
new file mode 100644
index 000000000000..0a7027de133b
--- /dev/null
+++ b/changelog_unreleased/javascript/pr-8461.md
@@ -0,0 +1,19 @@
+#### Wrap jsx element on the left of "<" with parentheses ([#8461](https://github.com/prettier/prettier/pull/8461) by [@sosukesuzuki](https://github.com/sosukesuzuki))
+
+<!-- prettier-ignore -->
+```jsx
+// Input
+(<div/>) < 5;
+
+// Prettier stable
+<div/> < 5;
+
+// Prettier stable second outout
+SyntaxError: Adjacent JSX elements must be wrapped in an enclosing tag. Did you want a JSX fragment <>...</>? (1:9)
+> 1 | <div /> < 5;
+    |         ^
+  2 | 
+
+// Prettier master
+(<div />) < 5;
+```
diff --git a/src/language-js/needs-parens.js b/src/language-js/needs-parens.js
index 4e5a51f54808..3ae46702f773 100644
--- a/src/language-js/needs-parens.js
+++ b/src/language-js/needs-parens.js
@@ -705,6 +705,9 @@ function needsParens(path, options) {
     case "JSXElement":
       return (
         name === "callee" ||
+        (parent.type === "BinaryExpression" &&
+          parent.operator === "<" &&
+          name === "left") ||
         (parent.type !== "ArrayExpression" &&
           parent.type !== "ArrowFunctionExpression" &&
           parent.type !== "AssignmentExpression" &&


Test patch:
diff --git a/tests/jsx/binary-expressions/__snapshots__/jsfmt.spec.js.snap b/tests/jsx/binary-expressions/__snapshots__/jsfmt.spec.js.snap
new file mode 100644
index 000000000000..92e4ab74e94e
--- /dev/null
+++ b/tests/jsx/binary-expressions/__snapshots__/jsfmt.spec.js.snap
@@ -0,0 +1,51 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`relational-operators.js format 1`] = `
+====================================options=====================================
+parsers: ["babel", "typescript"]
+printWidth: 80
+                                                                                | printWidth
+=====================================input======================================
+(<div />) < 5;
+<div /> > 5;
+(<div></div>) < 5;
+<div></div> > 5;
+
+<div /> <= 5;
+<div /> >= 5;
+<div></div> <= 5;
+<div></div> >= 5;
+
+(<div />) < <div />;
+<div /> > <div />;
+(<div></div>) < <div></div>;
+<div></div> > <div></div>;
+
+<div /> <= <div />;
+<div /> >= <div />;
+<div></div> <= <div></div>;
+<div></div> >= <div></div>;
+
+=====================================output=====================================
+(<div />) < 5;
+<div /> > 5;
+(<div></div>) < 5;
+<div></div> > 5;
+
+<div /> <= 5;
+<div /> >= 5;
+<div></div> <= 5;
+<div></div> >= 5;
+
+(<div />) < <div />;
+<div /> > <div />;
+(<div></div>) < <div></div>;
+<div></div> > <div></div>;
+
+<div /> <= <div />;
+<div /> >= <div />;
+<div></div> <= <div></div>;
+<div></div> >= <div></div>;
+
+================================================================================
+`;
diff --git a/tests/jsx/binary-expressions/jsfmt.spec.js b/tests/jsx/binary-expressions/jsfmt.spec.js
new file mode 100644
index 000000000000..858ac91aadcc
--- /dev/null
+++ b/tests/jsx/binary-expressions/jsfmt.spec.js
@@ -0,0 +1,1 @@
+run_spec(__dirname, ["babel", "typescript"]);
diff --git a/tests/jsx/binary-expressions/relational-operators.js b/tests/jsx/binary-expressions/relational-operators.js
new file mode 100644
index 000000000000..41d6bcc8b722
--- /dev/null
+++ b/tests/jsx/binary-expressions/relational-operators.js
@@ -0,0 +1,19 @@
+(<div />) < 5;
+<div /> > 5;
+(<div></div>) < 5;
+<div></div> > 5;
+
+<div /> <= 5;
+<div /> >= 5;
+<div></div> <= 5;
+<div></div> >= 5;
+
+(<div />) < <div />;
+<div /> > <div />;
+(<div></div>) < <div></div>;
+<div></div> > <div></div>;
+
+<div /> <= <div />;
+<div /> >= <div />;
+<div></div> <= <div></div>;
+<div></div> >= <div></div>;