Repository: swc-project/swc (rust)

Issue:
One comment line is removed
### Describe the bug

One of the comments gets removed

### Input code

```typescript
function x(y) {
  return y && // 96 is one less than the char code
  // for "a" so this is checking that
  // it's a lowercase character
  false;
};
```


### Config

```json
{
  "$schema": "https://json.schemastore.org/swcrc",
  "jsc": {
    "parser": {
      "syntax": "ecmascript",
      "jsx": true
    },
    "target": "es2019",
    "transform": {
      "react": {
        "runtime": "automatic"
      }
    }
  },
  "isModule": true,
  "module": {
    "type": "es6"
  }
}
```


### Playground link

https://play.swc.rs/?version=1.2.249&code=H4sIAAAAAAAAAyWMwQrCQAxE7%2F2KoYeqp94E6deEmLWLywaSFC3ivxspDHOZ96ZsnaNqx%2Fu8X%2FAZAJPYrGPHNGGecbuiOrQLmrgjVupZAl7JwHqXVBIrahhphGuuKWR4FX7W%2Fvg7cVA1Tg5C05cYkx8vxCGWe6Hmsgzf5QefqlMMlAAAAA%3D%3D&config=H4sIAAAAAAAAAy2MSw6CUAxF99I4JKAOTGQPLqKpFR7xfdL2RQlh7xZwdnvv6VngpDRyROhhNCvad92kObVHq5aF2yxDpx8SggYmJegXKCjKsiWdk%2BHX35mcJwnFdswrk8prA4YysG2EXs%2BXu68mmPSVJW4CYSTbQ00WIjuI1XJECwTr6oKgj%2Fysbz6MDcT%2FtYDNhXfxzckfbCK5rswAAAA%3D

### Expected behavior

= Input

### Actual behavior

```js
function x(y) {
    return y && // for "a" so this is checking that
    // it's a lowercase character
    false;
}
;
```

### Version

1.2.249

### Additional context

_No response_

Pull request description:
fix(es/parser): keep more comments around binop
<!-- Note: CI script will automatically rebase your PR so please do not rebase unless required -->

<!-- Thanks for submitting a pull request! Please provide enough information so that others can review your pull request. -->

**Description:**
attch comments to right of binExpr, instead of the operator
<!-- Explain the **motivation** for making this change. What existing problem does the pull request solve? -->

**BREAKING CHANGE:**

<!--
If this PR introduces a breaking change, it must contain a notice for it to be included in the CHANGELOG. Add description or remove entirely if not breaking.

You may need to update `MIGRATION.md` for the breaking changes.
-->

**Related issue (if exists):**
fix #5783

Patch:
diff --git a/crates/swc_ecma_parser/src/lexer/state.rs b/crates/swc_ecma_parser/src/lexer/state.rs
index a736eac82e..17c40a6045 100644
--- a/crates/swc_ecma_parser/src/lexer/state.rs
+++ b/crates/swc_ecma_parser/src/lexer/state.rs
@@ -371,6 +371,13 @@ impl State {
             .unwrap_or(false)
     }
 
+    pub fn can_have_trailing_line_comment(&self) -> bool {
+        match self.token_type {
+            Some(TokenType::BinOp(..)) => false,
+            _ => true,
+        }
+    }
+
     pub fn can_have_trailing_comment(&self) -> bool {
         match self.token_type {
             Some(TokenType::Keyword(..)) => false,
diff --git a/crates/swc_ecma_parser/src/lexer/util.rs b/crates/swc_ecma_parser/src/lexer/util.rs
index f277f0b8b9..f1c9046277 100644
--- a/crates/swc_ecma_parser/src/lexer/util.rs
+++ b/crates/swc_ecma_parser/src/lexer/util.rs
@@ -237,7 +237,7 @@ impl<'a, I: Input> Lexer<'a, I> {
         // // comment for bar
         // bar
         //
-        let is_for_next = self.state.had_line_break;
+        let is_for_next = self.state.had_line_break || !self.state.can_have_trailing_line_comment();
         let mut end = self.cur_pos();
 
         while let Some(c) = self.cur() {


Test patch:
diff --git a/crates/swc/tests/fixture/issues-5xxx/5783/input/input.js b/crates/swc/tests/fixture/issues-5xxx/5783/input/input.js
new file mode 100644
index 0000000000..e32148a356
--- /dev/null
+++ b/crates/swc/tests/fixture/issues-5xxx/5783/input/input.js
@@ -0,0 +1,44 @@
+function x1(y) {  
+    return a 
+    // leading of &&
+    && c;
+};
+function x2(y) {  
+    return a 
+    && 
+    // leading of c
+    c;
+};
+function x3(y) 
+{  
+    return a // trailing of a
+    && 
+    c;
+};
+function x4(y) 
+{  
+    return a && // trailing of &&
+    c;
+};
+function x5(y) {  
+    return a 
+    /* leading of && */
+    && c;
+};
+function x2(y) {  
+    return a 
+    && 
+    /* leading of c */
+    c;
+};
+function x3(y) 
+{  
+    return a /* trailing of a */
+    && 
+    c;
+};
+function x4(y) 
+{  
+    return a && /* trailing of && */
+    c;
+};
diff --git a/crates/swc/tests/fixture/issues-5xxx/5783/output/input.js b/crates/swc/tests/fixture/issues-5xxx/5783/output/input.js
new file mode 100644
index 0000000000..273b97546b
--- /dev/null
+++ b/crates/swc/tests/fixture/issues-5xxx/5783/output/input.js
@@ -0,0 +1,35 @@
+function x1(y) {
+    return a && c;
+}
+;
+function x2(y) {
+    return a && // leading of c
+    c;
+}
+;
+function x3(y) {
+    return a // trailing of a
+     && c;
+}
+;
+function x4(y) {
+    return a && // trailing of &&
+    c;
+}
+;
+function x5(y) {
+    return a && c;
+}
+;
+function x2(y) {
+    return a && /* leading of c */ c;
+}
+;
+function x3(y) {
+    return a /* trailing of a */  && c;
+}
+;
+function x4(y) {
+    return a && /* trailing of && */ c;
+}
+;
diff --git a/crates/swc/tests/fixture/next.js/server/render/1/output/index.tsx b/crates/swc/tests/fixture/next.js/server/render/1/output/index.tsx
index 74bc69119a..70b26ea89d 100644
--- a/crates/swc/tests/fixture/next.js/server/render/1/output/index.tsx
+++ b/crates/swc/tests/fixture/next.js/server/render/1/output/index.tsx
@@ -478,7 +478,8 @@ export async function renderToHTML(req, res, pathname, query, renderOpts) {
         props.pageProps = Object.assign({}, props.pageProps, data1.props);
         renderOpts.pageData = props;
     }
-    if (!isSSG && !getServerSideProps && process.env.NODE_ENV !== "production" && Object.keys(props?.pageProps || {}).includes("url")) {
+    if (!isSSG && // we only show this warning for legacy pages
+    !getServerSideProps && process.env.NODE_ENV !== "production" && Object.keys(props?.pageProps || {}).includes("url")) {
         console.warn(`The prop \`url\` is a reserved prop in Next.js for legacy reasons and will be overridden on page ${pathname}\n` + `See more info here: https://nextjs.org/docs/messages/reserved-page-prop`);
     }
     // Avoid rendering page un-necessarily for getServerSideProps data request
diff --git a/crates/swc/tests/tsc-references/parser15.4.4.14-9-2.1.normal.js b/crates/swc/tests/tsc-references/parser15.4.4.14-9-2.1.normal.js
index 416c3c3f0c..c66d0be421 100644
--- a/crates/swc/tests/tsc-references/parser15.4.4.14-9-2.1.normal.js
+++ b/crates/swc/tests/tsc-references/parser15.4.4.14-9-2.1.normal.js
@@ -16,7 +16,10 @@
     var one = 1;
     var _float = -4 / 3;
     var a = new Array(false, undefined, null, "0", obj, -1.3333333333333, "str", -0, true, +0, one, 1, 0, false, _float, -4 / 3);
-    if (a.indexOf(-4 / 3) === 14 && a.indexOf(0) === 7 && a.indexOf(-0) === 7 && a.indexOf(1) === 10) {
+    if (a.indexOf(-4 / 3) === 14 && // a[14]=_float===-(4/3)
+    a.indexOf(0) === 7 && // a[7] = +0, 0===+0
+    a.indexOf(-0) === 7 && // a[7] = +0, -0===+0
+    a.indexOf(1) === 10) {
         return true;
     }
 }
diff --git a/crates/swc/tests/tsc-references/parserGreaterThanTokenAmbiguity10.1.normal.js b/crates/swc/tests/tsc-references/parserGreaterThanTokenAmbiguity10.1.normal.js
index 0e7b12342f..04e7fa7e8a 100644
--- a/crates/swc/tests/tsc-references/parserGreaterThanTokenAmbiguity10.1.normal.js
+++ b/crates/swc/tests/tsc-references/parserGreaterThanTokenAmbiguity10.1.normal.js
@@ -1,2 +1,3 @@
 //// [parserGreaterThanTokenAmbiguity10.ts]
-1 >>> 2;
+1 >>> // after
+2;
diff --git a/crates/swc/tests/tsc-references/parserGreaterThanTokenAmbiguity5.1.normal.js b/crates/swc/tests/tsc-references/parserGreaterThanTokenAmbiguity5.1.normal.js
index 97a162bd59..bfffc2a79d 100644
--- a/crates/swc/tests/tsc-references/parserGreaterThanTokenAmbiguity5.1.normal.js
+++ b/crates/swc/tests/tsc-references/parserGreaterThanTokenAmbiguity5.1.normal.js
@@ -1,2 +1,3 @@
 //// [parserGreaterThanTokenAmbiguity5.ts]
-1 >> 2;
+1 >> // after
+2;
diff --git a/crates/swc/tests/tsc-references/typeGuardsInConditionalExpression.1.normal.js b/crates/swc/tests/tsc-references/typeGuardsInConditionalExpression.1.normal.js
index c654180c62..2c2e56103b 100644
--- a/crates/swc/tests/tsc-references/typeGuardsInConditionalExpression.1.normal.js
+++ b/crates/swc/tests/tsc-references/typeGuardsInConditionalExpression.1.normal.js
@@ -37,7 +37,8 @@ function foo7(x) {
 }
 function foo8(x) {
     var b;
-    return typeof x === "string" ? x === "hello" : (b = x) && (typeof x === "boolean" ? x // boolean
+    return typeof x === "string" ? x === "hello" : (b = x) && //  number | boolean
+    (typeof x === "boolean" ? x // boolean
      : x == 10); // boolean
 }
 function foo9(x) {
diff --git a/crates/swc_ecma_codegen/tests/test262/79a4d1fdd55febec.js b/crates/swc_ecma_codegen/tests/test262/79a4d1fdd55febec.js
index b85164d92b..9f1f284480 100644
--- a/crates/swc_ecma_codegen/tests/test262/79a4d1fdd55febec.js
+++ b/crates/swc_ecma_codegen/tests/test262/79a4d1fdd55febec.js
@@ -1,1 +1,2 @@
-var a = !b && (!c || d) && (!e || f) && g();
+var a = !b && // should not touch this one
+(!c || d) && (!e || f) && g();
diff --git a/crates/swc_ecma_transforms_typescript/tests/fixture/next/server/render/1/output.js b/crates/swc_ecma_transforms_typescript/tests/fixture/next/server/render/1/output.js
index fceb5db4c5..6a73a12759 100644
--- a/crates/swc_ecma_transforms_typescript/tests/fixture/next/server/render/1/output.js
+++ b/crates/swc_ecma_transforms_typescript/tests/fixture/next/server/render/1/output.js
@@ -487,7 +487,8 @@ export async function renderToHTML(req, res, pathname, query, renderOpts) {
         props.pageProps = Object.assign({}, props.pageProps, data1.props);
         renderOpts.pageData = props;
     }
-    if (!isSSG && !getServerSideProps && process.env.NODE_ENV !== "production" && Object.keys(props?.pageProps || {}).includes("url")) {
+    if (!isSSG && // we only show this warning for legacy pages
+    !getServerSideProps && process.env.NODE_ENV !== "production" && Object.keys(props?.pageProps || {}).includes("url")) {
         console.warn(`The prop \`url\` is a reserved prop in Next.js for legacy reasons and will be overridden on page ${pathname}\n` + `See more info here: https://nextjs.org/docs/messages/reserved-page-prop`);
     }
     // Avoid rendering page un-necessarily for getServerSideProps data request