Repository: prettier/prettier (JavaScript)

Issue:
Code-breaking semicolon added when formatting range in arrow function with comment
**Prettier 2.6.2**
[Playground link](https://prettier.io/playground/#N4Igxg9gdgLgprEAuEAbOMAEAzKmC8mAFEQJQEB8mwAOnpgE4YCuDUA3JgPRd0C+pdiAA0ICAAcYAS2gBnZKACGDBhADuABWUJ5KRajWKAnvNEAjBorABrDAGVFAWzgAZKVDjJs+2XHOWbe3ErdwBzZBgGZj8QOEczOAATRKSXRShQ5kVQuAAxCAZHRRhpDOQQRWYYCBEQAAsYR1QAdTqpeFlgsDg7HXapADd2o3KwWVMQd18GGA1LUKKvHxiAK1kADzsw9ABFZgh4JdRfUWCGafKzRQTUWvEGdxhmqUSYOuQADgAGU9VfZss4nK9zg0wGnlEAEd9vA5hJdBVZABaDxJJK1JjQqRMObZRZIbzHGK+RxSCJRYnbOB7A6eAnLUQwa7PV7vJAAJkZlikqDCAGEII58bFZABWWrMXwAFWuukJJxAA2iAEkoClYHYwA9JABBNV2GBGdBHBWWDI9JkzZAARg+ojNOQAomrkABma18PhAA)
<!-- prettier-ignore -->
```sh
--parser babel
--range-start 18
--range-end 31
```

**Input:**
<!-- prettier-ignore -->
```jsx
let fn = (() => {
  return; //
});
```

**Output:**
<!-- prettier-ignore -->
```jsx
let fn = (() => {
  return; //
};);
```

**Expected behavior:**
The semicolon after the arrow function is not added.

Note that this does NOT happen when the arrow function is replaced with a `function` expression, nor if the comment inside the arrow function is removed.



Hints:
I wonder if this is related to #12963, because a semicolon was added improperly in that issue as well.
> I wonder if this is related to #12963, because a semicolon was added improperly in that issue as well.

I don't think so. This happens with the Babel parser and the parse tree looks correct to me, unlike with #12963
Based on further experimentation, I think this happens WHENEVER formatting a range inside a braced arrow function expression where the range ends with a comment (either `//` or `/*..*/`) but does not start with a comment.
> Based on further experimentation, I think this happens WHENEVER formatting a range inside a braced arrow function expression where the range ends with a comment (either `//` or `/*..*/`) but does not start with a comment.

I can confirm this. I had commented out a line at the end of a modified range of lines and had the editor.formatOnSaveMode setting set to 'modifications' and this added a semicolon at the very end of my file (the closing part of an IIEF: `};)();`.

Once I uncommented the line in question (and removed the semicolon), a new one was not added on save.

My solution, in the meantime, was to just go back to 'file' for editor.formatOnSaveMode. This solves it, since I never end a file with a comment.
> My solution, in the meantime, was to just go back to 'file' for editor.formatOnSaveMode. This solves it, since I never end a file with a comment.

That's an unfortunate solution, if understandably pragmatic. This is a pretty nasty bug since it corrupts correct code.

Even a comment at the end of the file wouldn't trigger this. It's just about a comment at the end of the *edited range inside* an arrow function.

I noticed another curious thing about this bug - if you have `--no-semi` enabled, instead of a code-breaking semicolon added *after* the arrow function, it inserts a code-breaking semicolon *before* the arrow function!
We are seeing an issue here too. We have the noSemi option and it's adding a semi-colon before the code and breaking it. 
We are working in react. Not sure if that is relevant but worth mentioning
any solution ? Otherwise, I have to disable prettier 
same here v2.7.1
input
```
          map((data) => {
            // this can be anything, code or comment, if I remove this, then it works
            return data.sort();
          }),
```

output
```
         map((data) => {
            // this can be anything, code or comment, if I remove this, then it works
            return data.sort();
          });,
```

Patch:
diff --git a/src/main/range-util.js b/src/main/range-util.js
--- a/src/main/range-util.js
+++ b/src/main/range-util.js
@@ -64,6 +64,9 @@ function findSiblingAncestors(
     } else {
       break;
     }
+    if (resultStartNode === resultEndNode) {
+      break;
+    }
   }
 
   return {


Test patch:
diff --git a/tests/format/js/range/__snapshots__/jsfmt.spec.js.snap b/tests/format/js/range/__snapshots__/jsfmt.spec.js.snap
--- a/tests/format/js/range/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/format/js/range/__snapshots__/jsfmt.spec.js.snap
@@ -182,6 +182,27 @@ rangeStart: 0
 ================================================================================
 `;
 
+exports[`function-body.js format 1`] = `
+====================================options=====================================
+parsers: ["babel", "flow", "typescript"]
+printWidth: 80
+rangeEnd: 33
+rangeStart: 20
+     |                                                                                | printWidth
+=====================================input======================================
+  1 | let fn =a((x ) => {
+> 2 |   quux (); //
+    | ^^^^^^^^^^^^^
+  3 | });
+  4 |
+=====================================output=====================================
+let fn =a((x ) => {
+  quux(); //
+});
+
+================================================================================
+`;
+
 exports[`function-declaration.js format 1`] = `
 ====================================options=====================================
 parsers: ["babel", "flow", "typescript"]
diff --git a/tests/format/js/range/function-body.js b/tests/format/js/range/function-body.js
new file mode 100644
--- /dev/null
+++ b/tests/format/js/range/function-body.js
@@ -0,0 +1,3 @@
+let fn =a((x ) => {
+<<<PRETTIER_RANGE_START>>>  quux (); //<<<PRETTIER_RANGE_END>>>
+});