Repository: swc-project/swc (rust)

Issue:
Can not remove constructor parentheses when using optional chaining after constructor. 
### Describe the bug

SWC is producing invalid output. Optional chaining can not occur after a constructor without parentheses. 

### Input code

```typescript
new Date()?.toLocaleDateString()
```


### Config

```json
{
  "jsc": {
    "parser": {
      "syntax": "typescript",
      "tsx": true
    },
    "transform": {
      "react": {
        "runtime": "automatic",
        "importSource": "preact",
        "development": true
      }
    },
    "target": "es2022",
    "loose": false,
    "minify": {
      "compress": {
        "arguments": false,
        "arrows": true,
        "booleans": true,
        "booleans_as_integers": false,
        "collapse_vars": true,
        "comparisons": true,
        "computed_props": true,
        "conditionals": true,
        "dead_code": true,
        "directives": true,
        "drop_console": false,
        "drop_debugger": true,
        "evaluate": true,
        "expression": false,
        "hoist_funs": false,
        "hoist_props": true,
        "hoist_vars": false,
        "if_return": true,
        "join_vars": true,
        "keep_classnames": false,
        "keep_fargs": true,
        "keep_fnames": false,
        "keep_infinity": false,
        "loops": true,
        "negate_iife": true,
        "properties": true,
        "reduce_funcs": false,
        "reduce_vars": false,
        "side_effects": true,
        "switches": true,
        "typeofs": true,
        "unsafe": false,
        "unsafe_arrows": false,
        "unsafe_comps": false,
        "unsafe_Function": false,
        "unsafe_math": false,
        "unsafe_symbols": false,
        "unsafe_methods": false,
        "unsafe_proto": false,
        "unsafe_regexp": false,
        "unsafe_undefined": false,
        "unused": true,
        "const_to_let": true,
        "pristine_globals": true,
        "passes": 2
      },
      "mangle": false
    }
  },
  "module": {
    "type": "es6"
  },
  "minify": true,
  "isModule": true
}
```


### Playground link

https://play.swc.rs/?version=1.3.16&code=H4sIAAAAAAAAA8tLLVdwSSxJ1dC01yvJ98lPTsxJBfGDS4oy89I1NAFDQfiVIAAAAA%3D%3D&config=H4sIAAAAAAAAA21TS7IbIQy8C2svUl5k8Q6QXVY5AIVBjHkBRCHh5ynXu3vEjM147OxQ090IfW7qk6z6uKliKkHtJ5ozm6v6UDwXIFtDYXVQTAJxbfAt52oyeayp0ysYy8uhZQ4JRGgaYzIcrOhCKlj5D7Zq%2B1VZ6Qfl4AIRS4LMd99ubOoEEiug44%2FjUWgRkUTnTSQ4qBRy8HN%2FzGISK6J%2BFlHrPjR4plb8otX3oE6IESTj11gb0iEzTFA3qcUYTSHQF1OHor9maiDMO6gxOF0qlic0u8ABs5g9MAfGaYsOBhAqWA4X2CjiIZRMktjIZAEdnNo09casTLiY2AwPL7guZZAXh%2B6MgVj7lukF2mW6Qusn76zgdQVuNT84nxjyrg5%2FASTPaIiySbApF9xLH%2FZM%2Fx9WyF6ayPNApcNbVhkm%2BZwOwY8f9qyhctiqVcE1C%2F2HdjO%2Fg7sPUXCgwXup9hDTV2B73sz6kKMfoVTN%2BK0Ha6gf87RH%2Bwi8gb8kK35uxx2XfTi%2FYjSnE8Y3iwR8RvcGSyEYX8Eq03str2jLDqTM4J4uGvVwjKk0n1FH4K3OMhCi0VPE09P4Ful2L9dR9jOZPI0J7Qub0LUO3JY6Lov7U31vi7paBPp95y2L%2Fg9snqxsdAQAAA%3D%3D

### Expected behavior

```
new Date()?.toLocaleDateString();
```

or 

```
(new Date)?.toLocaleDateString();
```



### Actual behavior

```
new Date?.toLocaleDateString();
```

### Version

1.3.16

### Additional context

_No response_

Pull request:
fix(es/codegen): Preserve parentheses for new expr in optional chaining
<!-- 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:**

<!-- 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 #6438 

Patch:
diff --git a/crates/swc_ecma_codegen/src/lib.rs b/crates/swc_ecma_codegen/src/lib.rs
index 0d273d1b92..21b76e4d21 100644
--- a/crates/swc_ecma_codegen/src/lib.rs
+++ b/crates/swc_ecma_codegen/src/lib.rs
@@ -810,7 +810,11 @@ where
 
         match n.base {
             OptChainBase::Member(ref e) => {
-                emit!(e.obj);
+                if let Expr::New(new) = &*e.obj {
+                    self.emit_new(new, false)?;
+                } else {
+                    emit!(e.obj);
+                }
                 punct!("?.");
 
                 match &e.prop {
@@ -820,11 +824,8 @@ where
                 }
             }
             OptChainBase::Call(ref e) => {
-                if let Expr::New(new) = &*e.callee {
-                    self.emit_new(new, false)?;
-                } else {
-                    emit!(e.callee);
-                }
+                debug_assert!(!e.callee.is_new());
+                emit!(e.callee);
                 punct!("?.");
 
                 punct!("(");


Test patch:
diff --git a/crates/swc/tests/fixture/issues-6xxx/6438/input/.swcrc b/crates/swc/tests/fixture/issues-6xxx/6438/input/.swcrc
new file mode 100644
index 0000000000..6f7554d71d
--- /dev/null
+++ b/crates/swc/tests/fixture/issues-6xxx/6438/input/.swcrc
@@ -0,0 +1,72 @@
+{
+    "jsc": {
+        "parser": {
+            "syntax": "typescript",
+            "tsx": true
+        },
+        "transform": {
+            "react": {
+                "runtime": "automatic",
+                "importSource": "preact",
+                "development": true
+            }
+        },
+        "target": "es2022",
+        "loose": false,
+        "minify": {
+            "compress": {
+                "arguments": false,
+                "arrows": true,
+                "booleans": true,
+                "booleans_as_integers": false,
+                "collapse_vars": true,
+                "comparisons": true,
+                "computed_props": true,
+                "conditionals": true,
+                "dead_code": true,
+                "directives": true,
+                "drop_console": false,
+                "drop_debugger": true,
+                "evaluate": true,
+                "expression": false,
+                "hoist_funs": false,
+                "hoist_props": true,
+                "hoist_vars": false,
+                "if_return": true,
+                "join_vars": true,
+                "keep_classnames": false,
+                "keep_fargs": true,
+                "keep_fnames": false,
+                "keep_infinity": false,
+                "loops": true,
+                "negate_iife": true,
+                "properties": true,
+                "reduce_funcs": false,
+                "reduce_vars": false,
+                "side_effects": true,
+                "switches": true,
+                "typeofs": true,
+                "unsafe": false,
+                "unsafe_arrows": false,
+                "unsafe_comps": false,
+                "unsafe_Function": false,
+                "unsafe_math": false,
+                "unsafe_symbols": false,
+                "unsafe_methods": false,
+                "unsafe_proto": false,
+                "unsafe_regexp": false,
+                "unsafe_undefined": false,
+                "unused": true,
+                "const_to_let": true,
+                "pristine_globals": true,
+                "passes": 2
+            },
+            "mangle": false
+        }
+    },
+    "module": {
+        "type": "es6"
+    },
+    "minify": true,
+    "isModule": true
+}
\ No newline at end of file
diff --git a/crates/swc/tests/fixture/issues-6xxx/6438/input/index.js b/crates/swc/tests/fixture/issues-6xxx/6438/input/index.js
new file mode 100644
index 0000000000..6e45f4deee
--- /dev/null
+++ b/crates/swc/tests/fixture/issues-6xxx/6438/input/index.js
@@ -0,0 +1,1 @@
+new Date()?.toLocaleDateString()
\ No newline at end of file
diff --git a/crates/swc/tests/fixture/issues-6xxx/6438/output/index.js b/crates/swc/tests/fixture/issues-6xxx/6438/output/index.js
new file mode 100644
index 0000000000..2dac17589e
--- /dev/null
+++ b/crates/swc/tests/fixture/issues-6xxx/6438/output/index.js
@@ -0,0 +1,1 @@
+new Date()?.toLocaleDateString();