Repository: swc-project/swc (rust)

Issue:
Missing parenthesis in initializer of for loop
### Describe the bug

SWC is removing some parentheses form this for loop, and the resulting code logs `0` instead of `1`

### Input code

```typescript
let count = 0;
for (var a = 1 || (2 in {}) in { x: 1 }) count++;
console.log(count);
```


### Config

```json
{
  "jsc": {
    "parser": {
      "syntax": "typescript",
      "tsx": true,
      "decorators": true
    },
    "loose": false,
    "minify": {
      "compress": false,
      "mangle": false
    },
    "target": "es2022"
  },
  "module": {
    "type": "es6"
  },
  "minify": false,
  "isModule": false
}
```


### Playground link (or link to the minimal reproduction)

https://play.swc.rs/?version=1.6.7&code=H4sIAAAAAAAAA8tJLVFIzi%2FNK1GwVTCw5krLL1LQKEssUkgE8g0VamoUNIwUMvMUqms1wZRChRVQWAHIA2vS1rbmSs7PK87PSdXLyU%2FXAAtqWnMBADlkkHNWAAAA&config=H4sIAAAAAAAAA1WPMQ7DIAxF95wCee5QMXToHXoIRJyIKgFkO1KjKHcvJICSDf%2F3P9%2FeOqXgyxbeakvPNERDjNTmpPDqxfySArJGZEsuCjwqFc5IaMEm9WgDGQnEhRxgPzlMITAmMJiJSwZm592wXkttmCMh892YrcaPU8vffhZDI0peFFk%2FtYauMJhDvxyhcmQ%2B5PS9Lqa6RCsEx5%2BaPOv2P70hJh0xAQAA

### SWC Info output

_No response_

### Expected behavior

Same code

### Actual behavior

```js
let count = 0;
for(var a = 1 || 2 in {} in {
    x: 1
})count++;
console.log(count);
```

### Version

1.6.7

### Additional context

Babel has the same bug: https://github.com/babel/babel/issues/16628

Pull request description:
fix(es/fixer): Wrap `in` expr in for-in head
**Related issue (if exists):**
- Closes #9200

Patch:
diff --git a/crates/swc_ecma_transforms_base/src/fixer.rs b/crates/swc_ecma_transforms_base/src/fixer.rs
index 265e64e6c8..1e8737a346 100644
--- a/crates/swc_ecma_transforms_base/src/fixer.rs
+++ b/crates/swc_ecma_transforms_base/src/fixer.rs
@@ -71,17 +71,6 @@ enum Context {
     FreeExpr,
 }
 
-macro_rules! array {
-    ($name:ident, $T:tt) => {
-        fn $name(&mut self, e: &mut $T) {
-            let old = self.ctx;
-            self.ctx = Context::ForcedExpr;
-            e.elems.visit_mut_with(self);
-            self.ctx = old;
-        }
-    };
-}
-
 impl Fixer<'_> {
     fn wrap_callee(&mut self, e: &mut Expr) {
         match e {
@@ -102,7 +91,13 @@ impl Fixer<'_> {
 impl VisitMut for Fixer<'_> {
     noop_visit_mut_type!();
 
-    array!(visit_mut_array_lit, ArrayLit);
+    fn visit_mut_array_lit(&mut self, e: &mut ArrayLit) {
+        let ctx = mem::replace(&mut self.ctx, Context::ForcedExpr);
+        let in_for_stmt_head = mem::replace(&mut self.in_for_stmt_head, false);
+        e.elems.visit_mut_with(self);
+        self.in_for_stmt_head = in_for_stmt_head;
+        self.ctx = ctx;
+    }
 
     fn visit_mut_arrow_expr(&mut self, node: &mut ArrowExpr) {
         let old = self.ctx;
@@ -173,7 +168,9 @@ impl VisitMut for Fixer<'_> {
     }
 
     fn visit_mut_assign_pat(&mut self, node: &mut AssignPat) {
+        let in_for_stmt_head = mem::replace(&mut self.in_for_stmt_head, false);
         node.visit_mut_children_with(self);
+        self.in_for_stmt_head = in_for_stmt_head;
 
         if let Expr::Seq(..) = &*node.right {
             self.wrap(&mut node.right);
@@ -185,7 +182,9 @@ impl VisitMut for Fixer<'_> {
 
         let old = self.ctx;
         self.ctx = Context::ForcedExpr;
+        let in_for_stmt_head = mem::replace(&mut self.in_for_stmt_head, false);
         node.value.visit_mut_with(self);
+        self.in_for_stmt_head = in_for_stmt_head;
         self.ctx = old;
     }
 
@@ -345,6 +344,12 @@ impl VisitMut for Fixer<'_> {
         }
     }
 
+    fn visit_mut_block_stmt(&mut self, n: &mut BlockStmt) {
+        let in_for_stmt_head = mem::replace(&mut self.in_for_stmt_head, false);
+        n.visit_mut_children_with(self);
+        self.in_for_stmt_head = in_for_stmt_head;
+    }
+
     fn visit_mut_block_stmt_or_expr(&mut self, body: &mut BlockStmtOrExpr) {
         body.visit_mut_children_with(self);
 
@@ -376,9 +381,14 @@ impl VisitMut for Fixer<'_> {
     }
 
     fn visit_mut_class(&mut self, node: &mut Class) {
-        let old = self.ctx;
-        self.ctx = Context::Default;
-        node.visit_mut_children_with(self);
+        let ctx = mem::replace(&mut self.ctx, Context::Default);
+
+        node.super_class.visit_mut_with(self);
+
+        let in_for_stmt_head = mem::replace(&mut self.in_for_stmt_head, false);
+        node.body.visit_mut_with(self);
+        self.in_for_stmt_head = in_for_stmt_head;
+
         match &mut node.super_class {
             Some(e)
                 if e.is_seq()
@@ -393,7 +403,7 @@ impl VisitMut for Fixer<'_> {
             }
             _ => {}
         };
-        self.ctx = old;
+        self.ctx = ctx;
 
         node.body.retain(|m| !matches!(m, ClassMember::Empty(..)));
     }
@@ -472,6 +482,12 @@ impl VisitMut for Fixer<'_> {
         self.handle_expr_stmt(&mut s.expr);
     }
 
+    fn visit_mut_for_head(&mut self, n: &mut ForHead) {
+        let in_for_stmt_head = mem::replace(&mut self.in_for_stmt_head, true);
+        n.visit_mut_children_with(self);
+        self.in_for_stmt_head = in_for_stmt_head;
+    }
+
     fn visit_mut_for_of_stmt(&mut self, s: &mut ForOfStmt) {
         s.visit_mut_children_with(self);
 
@@ -507,15 +523,13 @@ impl VisitMut for Fixer<'_> {
     }
 
     fn visit_mut_for_stmt(&mut self, n: &mut ForStmt) {
-        let old = self.in_for_stmt_head;
-        self.in_for_stmt_head = true;
+        let in_for_stmt_head = mem::replace(&mut self.in_for_stmt_head, true);
         n.init.visit_mut_with(self);
+        self.in_for_stmt_head = in_for_stmt_head;
+
         n.test.visit_mut_with(self);
         n.update.visit_mut_with(self);
-
-        self.in_for_stmt_head = false;
         n.body.visit_mut_with(self);
-        self.in_for_stmt_head = old;
     }
 
     fn visit_mut_if_stmt(&mut self, node: &mut IfStmt) {
@@ -594,10 +608,9 @@ impl VisitMut for Fixer<'_> {
     }
 
     fn visit_mut_new_expr(&mut self, node: &mut NewExpr) {
-        let old = self.ctx;
-        self.ctx = Context::ForcedExpr;
+        let ctx = mem::replace(&mut self.ctx, Context::ForcedExpr);
+
         node.args.visit_mut_with(self);
-        self.ctx = old;
 
         self.ctx = Context::Callee { is_new: true };
         node.callee.visit_mut_with(self);
@@ -612,7 +625,7 @@ impl VisitMut for Fixer<'_> {
             | Expr::Lit(..) => self.wrap(&mut node.callee),
             _ => {}
         }
-        self.ctx = old;
+        self.ctx = ctx;
     }
 
     fn visit_mut_opt_call(&mut self, node: &mut OptCall) {
@@ -767,6 +780,31 @@ impl VisitMut for Fixer<'_> {
         expr.arg.visit_mut_with(self);
         self.ctx = old;
     }
+
+    fn visit_mut_object_lit(&mut self, n: &mut ObjectLit) {
+        let in_for_stmt_head = mem::replace(&mut self.in_for_stmt_head, false);
+        n.visit_mut_children_with(self);
+        self.in_for_stmt_head = in_for_stmt_head;
+    }
+
+    fn visit_mut_params(&mut self, n: &mut Vec<Param>) {
+        let in_for_stmt_head = mem::replace(&mut self.in_for_stmt_head, false);
+        n.visit_mut_children_with(self);
+        self.in_for_stmt_head = in_for_stmt_head;
+    }
+
+    // only used in ArrowExpr
+    fn visit_mut_pats(&mut self, n: &mut Vec<Pat>) {
+        let in_for_stmt_head = mem::replace(&mut self.in_for_stmt_head, false);
+        n.visit_mut_children_with(self);
+        self.in_for_stmt_head = in_for_stmt_head;
+    }
+
+    fn visit_mut_expr_or_spreads(&mut self, n: &mut Vec<ExprOrSpread>) {
+        let in_for_stmt_head = mem::replace(&mut self.in_for_stmt_head, false);
+        n.visit_mut_children_with(self);
+        self.in_for_stmt_head = in_for_stmt_head;
+    }
 }
 
 impl Fixer<'_> {
@@ -774,6 +812,14 @@ impl Fixer<'_> {
         let mut has_padding_value = false;
         match e {
             Expr::Bin(BinExpr { op: op!("in"), .. }) if self.in_for_stmt_head => {
+                // TODO:
+                // if the in expression is in a parentheses, we should not wrap it with a
+                // parentheses again. But the parentheses is added later,
+                // so we don't have enough information to detect it at this moment.
+                // Example:
+                // for(var a = 1 + (2 || b in c) in {});
+                //                 |~~~~~~~~~~~|
+                // this parentheses is removed by unwrap_expr and added again later
                 self.wrap(e);
             }
 


Test patch:
diff --git a/crates/swc/tests/fixture/issues-9xxx/9200/input/.swcrc b/crates/swc/tests/fixture/issues-9xxx/9200/input/.swcrc
new file mode 100644
index 0000000000..a56e12b83d
--- /dev/null
+++ b/crates/swc/tests/fixture/issues-9xxx/9200/input/.swcrc
@@ -0,0 +1,20 @@
+{
+    "jsc": {
+        "parser": {
+            "syntax": "typescript",
+            "tsx": true,
+            "decorators": true
+        },
+        "loose": false,
+        "minify": {
+            "compress": false,
+            "mangle": false
+        },
+        "target": "es2022"
+    },
+    "module": {
+        "type": "es6"
+    },
+    "minify": false,
+    "isModule": false
+}
\ No newline at end of file
diff --git a/crates/swc/tests/fixture/issues-9xxx/9200/input/1.js b/crates/swc/tests/fixture/issues-9xxx/9200/input/1.js
new file mode 100644
index 0000000000..407f397c15
--- /dev/null
+++ b/crates/swc/tests/fixture/issues-9xxx/9200/input/1.js
@@ -0,0 +1,3 @@
+let count = 0;
+for (var a = 1 || (2 in {}) in { x: 1 }) count++;
+console.log(count);
\ No newline at end of file
diff --git a/crates/swc/tests/fixture/issues-9xxx/9200/input/2.js b/crates/swc/tests/fixture/issues-9xxx/9200/input/2.js
new file mode 100644
index 0000000000..eda3b1cacf
--- /dev/null
+++ b/crates/swc/tests/fixture/issues-9xxx/9200/input/2.js
@@ -0,0 +1,47 @@
+for (var a = (b in c) in {});
+for (var a = 1 || (b in c) in {});
+for (var a = 1 + (2 || (b in c)) in {});
+for (var a = (() => b in c) in {});
+for (var a = 1 || (() => b in c) in {});
+for (var a = (() => { b in c; }) in {});
+for (var a = [b in c] in {});
+for (var a = {b: b in c} in {});
+for (var a = (x = b in c) => {} in {});
+for (var a = class extends (b in c) {} in {});
+for (var a = function (x = b in c) {} in {});
+
+for (var a = (b in c);;);
+for (var a = 1 || (b in c);;);
+for (var a = 1 + (2 || (b in c));;);
+for (var a = (() => b in c);;);
+for (var a = 1 || (() => b in c);;);
+for (var a = (() => { b in c; });;);
+for (var a = [b in c];;);
+for (var a = {b: b in c};;);
+for (var a = (x = b in c) => {};;);
+for (var a = class extends (b in c) {};;);
+for (var a = function (x = b in c) {};;);
+
+for (var a in (b in c));
+for (var a in 1 || (b in c));
+for (var a in 1 + (2 || (b in c)));
+for (var a in (() => b in c));
+for (var a in 1 || (() => b in c));
+for (var a in (() => { b in c; }));
+for (var a in [b in c]);
+for (var a in {b: b in c});
+for (var a in (x = b in c) => {});
+for (var a in class extends (b in c) {});
+for (var a in function (x = b in c) {});
+
+for (;a = (b in c););
+for (;a = 1 || (b in c););
+for (;a = 1 + (2 || (b in c)););
+for (;a = (() => b in c););
+for (;a = 1 || (() => b in c););
+for (;a = (() => { b in c; }););
+for (;a = [b in c];);
+for (;a = {b: b in c};);
+for (;a = (x = b in c) => {};);
+for (;a = class extends (b in c) {};);
+for (;a = function (x = b in c) {};);
diff --git a/crates/swc/tests/fixture/issues-9xxx/9200/output/1.js b/crates/swc/tests/fixture/issues-9xxx/9200/output/1.js
new file mode 100644
index 0000000000..994d293e8b
--- /dev/null
+++ b/crates/swc/tests/fixture/issues-9xxx/9200/output/1.js
@@ -0,0 +1,5 @@
+let count = 0;
+for(var a = 1 || (2 in {}) in {
+    x: 1
+})count++;
+console.log(count);
diff --git a/crates/swc/tests/fixture/issues-9xxx/9200/output/2.js b/crates/swc/tests/fixture/issues-9xxx/9200/output/2.js
new file mode 100644
index 0000000000..066c4d076d
--- /dev/null
+++ b/crates/swc/tests/fixture/issues-9xxx/9200/output/2.js
@@ -0,0 +1,72 @@
+for(var a = (b in c) in {});
+for(var a = 1 || (b in c) in {});
+for(var a = 1 + (2 || (b in c)) in {});
+for(var a = ()=>(b in c) in {});
+for(var a = 1 || (()=>(b in c)) in {});
+for(var a = ()=>{
+    b in c;
+} in {});
+for(var a = [
+    b in c
+] in {});
+for(var a = {
+    b: b in c
+} in {});
+for(var a = (x = b in c)=>{} in {});
+for(var a = class extends (b in c) {
+} in {});
+for(var a = function(x = b in c) {} in {});
+for(var a = (b in c);;);
+for(var a = 1 || (b in c);;);
+for(var a = 1 + (2 || (b in c));;);
+for(var a = ()=>(b in c);;);
+for(var a = 1 || (()=>(b in c));;);
+for(var a = ()=>{
+    b in c;
+};;);
+for(var a = [
+    b in c
+];;);
+for(var a = {
+    b: b in c
+};;);
+for(var a = (x = b in c)=>{};;);
+for(var a = class extends (b in c) {
+};;);
+for(var a = function(x = b in c) {};;);
+for(var a in b in c);
+for(var a in 1 || b in c);
+for(var a in 1 + (2 || b in c));
+for(var a in ()=>b in c);
+for(var a in 1 || (()=>b in c));
+for(var a in ()=>{
+    b in c;
+});
+for(var a in [
+    b in c
+]);
+for(var a in {
+    b: b in c
+});
+for(var a in (x = b in c)=>{});
+for(var a in class extends (b in c) {
+});
+for(var a in function(x = b in c) {});
+for(; a = b in c;);
+for(; a = 1 || b in c;);
+for(; a = 1 + (2 || b in c););
+for(; a = ()=>b in c;);
+for(; a = 1 || (()=>b in c););
+for(; a = ()=>{
+    b in c;
+};);
+for(; a = [
+    b in c
+];);
+for(; a = {
+    b: b in c
+};);
+for(; a = (x = b in c)=>{};);
+for(; a = class extends (b in c) {
+};);
+for(; a = function(x = b in c) {};);
diff --git a/crates/swc_ecma_minifier/tests/benches-full/echarts.js b/crates/swc_ecma_minifier/tests/benches-full/echarts.js
index 3899d71743..cf1578a6c8 100644
--- a/crates/swc_ecma_minifier/tests/benches-full/echarts.js
+++ b/crates/swc_ecma_minifier/tests/benches-full/echarts.js
@@ -6154,7 +6154,7 @@
                 needDrawBg && this._renderBackground(style, style, boxX, boxY, outerWidth_1, outerHeight);
             }
             textY += lineHeight / 2, textPadding && (textX = getTextXForPadding(baseX, textAlign, textPadding), 'top' === verticalAlign ? textY += textPadding[0] : 'bottom' === verticalAlign && (textY -= textPadding[2]));
-            for(var defaultLineWidth = 0, useDefaultFill = !1, textFill = null == (fill = ('fill' in style) ? style.fill : (useDefaultFill = !0, defaultStyle.fill)) || 'none' === fill ? null : fill.image || fill.colorStops ? '#000' : fill, textStroke = getStroke(('stroke' in style) ? style.stroke : bgColorDrawn || defaultStyle.autoStroke && !useDefaultFill ? null : (defaultLineWidth = 2, defaultStyle.stroke)), hasShadow = style.textShadowBlur > 0, fixedBoundingRect = null != style.width && ('truncate' === style.overflow || 'break' === style.overflow || 'breakAll' === style.overflow), calculatedLineHeight = contentBlock.calculatedLineHeight, i = 0; i < textLines.length; i++){
+            for(var defaultLineWidth = 0, useDefaultFill = !1, textFill = null == (fill = ('fill' in style) ? style.fill : (useDefaultFill = !0, defaultStyle.fill)) || 'none' === fill ? null : fill.image || fill.colorStops ? '#000' : fill, textStroke = getStroke('stroke' in style ? style.stroke : bgColorDrawn || defaultStyle.autoStroke && !useDefaultFill ? null : (defaultLineWidth = 2, defaultStyle.stroke)), hasShadow = style.textShadowBlur > 0, fixedBoundingRect = null != style.width && ('truncate' === style.overflow || 'break' === style.overflow || 'breakAll' === style.overflow), calculatedLineHeight = contentBlock.calculatedLineHeight, i = 0; i < textLines.length; i++){
                 var el = this._getOrCreateChild(TSpan), subElStyle = el.createStyle();
                 el.useStyle(subElStyle), subElStyle.text = textLines[i], subElStyle.x = textX, subElStyle.y = textY, textAlign && (subElStyle.textAlign = textAlign), subElStyle.textBaseline = 'middle', subElStyle.opacity = style.opacity, subElStyle.strokeFirst = !0, hasShadow && (subElStyle.shadowBlur = style.textShadowBlur || 0, subElStyle.shadowColor = style.textShadowColor || 'transparent', subElStyle.shadowOffsetX = style.textShadowOffsetX || 0, subElStyle.shadowOffsetY = style.textShadowOffsetY || 0), textStroke && (subElStyle.stroke = textStroke, subElStyle.lineWidth = style.lineWidth || defaultLineWidth, subElStyle.lineDash = style.lineDash, subElStyle.lineDashOffset = style.lineDashOffset || 0), textFill && (subElStyle.fill = textFill), subElStyle.font = textFont, textY += lineHeight, fixedBoundingRect && el.setBoundingRect(new BoundingRect(adjustTextX(subElStyle.x, style.width, subElStyle.textAlign), adjustTextY(subElStyle.y, calculatedLineHeight, subElStyle.textBaseline), style.width, calculatedLineHeight));
             }
diff --git a/crates/swc_ecma_minifier/tests/benches-full/jquery.js b/crates/swc_ecma_minifier/tests/benches-full/jquery.js
index 1fb3fa08fb..0b5f113a35 100644
--- a/crates/swc_ecma_minifier/tests/benches-full/jquery.js
+++ b/crates/swc_ecma_minifier/tests/benches-full/jquery.js
@@ -3125,9 +3125,9 @@
         for(!function(props, specialEasing) {
             var index, name, easing, value, hooks;
             // camelCase, specialEasing and expand cssHook pass
-            for(index in props)if (easing = specialEasing[name = camelCase(index)], Array.isArray(value = props[index]) && (easing = value[1], value = props[index] = value[0]), index !== name && (props[name] = value, delete props[index]), (hooks = jQuery.cssHooks[name]) && ("expand" in hooks)) // Not quite $.extend, this won't overwrite existing keys.
+            for(index in props)if (easing = specialEasing[name = camelCase(index)], Array.isArray(value = props[index]) && (easing = value[1], value = props[index] = value[0]), index !== name && (props[name] = value, delete props[index]), (hooks = jQuery.cssHooks[name]) && "expand" in hooks) // Not quite $.extend, this won't overwrite existing keys.
             // Reusing 'index' because we have the correct "name"
-            for(index in value = hooks.expand(value), delete props[name], value)(index in props) || (props[index] = value[index], specialEasing[index] = easing);
+            for(index in value = hooks.expand(value), delete props[name], value)index in props || (props[index] = value[index], specialEasing[index] = easing);
             else specialEasing[name] = easing;
         }(props, animation.opts.specialEasing); index < length; index++)if (result = Animation.prefilters[index].call(animation, elem, props, animation.opts)) return isFunction(result.stop) && (jQuery._queueHooks(animation.elem, animation.opts.queue).stop = result.stop.bind(result)), result;
         return jQuery.map(props, createTween, animation), isFunction(animation.opts.start) && animation.opts.start.call(elem, animation), // Attach callbacks from options
diff --git a/crates/swc_ecma_minifier/tests/fixture/issues/2257/full/output.js b/crates/swc_ecma_minifier/tests/fixture/issues/2257/full/output.js
index 9f1e158a48..0dec27404a 100644
--- a/crates/swc_ecma_minifier/tests/fixture/issues/2257/full/output.js
+++ b/crates/swc_ecma_minifier/tests/fixture/issues/2257/full/output.js
@@ -8201,14 +8201,14 @@
                 for(var RegExpWrapper = function(pattern, flags) {
                     var rawFlags, dotAll, sticky, handled, result, state, thisIsRegExp = this instanceof RegExpWrapper, patternIsRegExp = isRegExp(pattern), flagsAreUndefined = void 0 === flags, groups = [], rawPattern = pattern;
                     if (!thisIsRegExp && patternIsRegExp && flagsAreUndefined && pattern.constructor === RegExpWrapper) return pattern;
-                    if ((patternIsRegExp || pattern instanceof RegExpWrapper) && (pattern = pattern.source, flagsAreUndefined && (flags = ("flags" in rawPattern) ? rawPattern.flags : getFlags.call(rawPattern))), pattern = void 0 === pattern ? "" : toString1(pattern), flags = void 0 === flags ? "" : toString1(flags), rawPattern = pattern, UNSUPPORTED_DOT_ALL && ("dotAll" in re1) && (dotAll = !!flags && flags.indexOf("s") > -1) && (flags = flags.replace(/s/g, "")), rawFlags = flags, UNSUPPORTED_Y && ("sticky" in re1) && (sticky = !!flags && flags.indexOf("y") > -1) && (flags = flags.replace(/y/g, "")), UNSUPPORTED_NCG && (pattern = (handled = handleNCG(pattern))[0], groups = handled[1]), result = inheritIfRequired(NativeRegExp(pattern, flags), thisIsRegExp ? this : RegExpPrototype, RegExpWrapper), (dotAll || sticky || groups.length) && (state = enforceInternalState(result), dotAll && (state.dotAll = !0, state.raw = RegExpWrapper(handleDotAll(pattern), rawFlags)), sticky && (state.sticky = !0), groups.length && (state.groups = groups)), pattern !== rawPattern) try {
+                    if ((patternIsRegExp || pattern instanceof RegExpWrapper) && (pattern = pattern.source, flagsAreUndefined && (flags = "flags" in rawPattern ? rawPattern.flags : getFlags.call(rawPattern))), pattern = void 0 === pattern ? "" : toString1(pattern), flags = void 0 === flags ? "" : toString1(flags), rawPattern = pattern, UNSUPPORTED_DOT_ALL && "dotAll" in re1 && (dotAll = !!flags && flags.indexOf("s") > -1) && (flags = flags.replace(/s/g, "")), rawFlags = flags, UNSUPPORTED_Y && "sticky" in re1 && (sticky = !!flags && flags.indexOf("y") > -1) && (flags = flags.replace(/y/g, "")), UNSUPPORTED_NCG && (pattern = (handled = handleNCG(pattern))[0], groups = handled[1]), result = inheritIfRequired(NativeRegExp(pattern, flags), thisIsRegExp ? this : RegExpPrototype, RegExpWrapper), (dotAll || sticky || groups.length) && (state = enforceInternalState(result), dotAll && (state.dotAll = !0, state.raw = RegExpWrapper(handleDotAll(pattern), rawFlags)), sticky && (state.sticky = !0), groups.length && (state.groups = groups)), pattern !== rawPattern) try {
                         // fails in old engines, but we have no alternatives for unsupported regex syntax
                         createNonEnumerableProperty(result, "source", "" === rawPattern ? "(?:)" : rawPattern);
                     } catch (error) {
                     /* empty */ }
                     return result;
                 }, proxy = function(key) {
-                    (key in RegExpWrapper) || defineProperty(RegExpWrapper, key, {
+                    key in RegExpWrapper || defineProperty(RegExpWrapper, key, {
                         configurable: !0,
                         get: function() {
                             return NativeRegExp[key];
diff --git a/crates/swc_ecma_minifier/tests/projects/output/jquery-1.9.1.js b/crates/swc_ecma_minifier/tests/projects/output/jquery-1.9.1.js
index b3cf88a988..22b38bee1e 100644
--- a/crates/swc_ecma_minifier/tests/projects/output/jquery-1.9.1.js
+++ b/crates/swc_ecma_minifier/tests/projects/output/jquery-1.9.1.js
@@ -3855,9 +3855,9 @@
         for(function(props, specialEasing) {
             var value, name1, index, easing, hooks;
             // camelCase, specialEasing and expand cssHook pass
-            for(index in props)if (easing = specialEasing[name1 = jQuery.camelCase(index)], value = props[index], jQuery.isArray(value) && (easing = value[1], value = props[index] = value[0]), index !== name1 && (props[name1] = value, delete props[index]), (hooks = jQuery.cssHooks[name1]) && ("expand" in hooks)) // not quite $.extend, this wont overwrite keys already present.
+            for(index in props)if (easing = specialEasing[name1 = jQuery.camelCase(index)], value = props[index], jQuery.isArray(value) && (easing = value[1], value = props[index] = value[0]), index !== name1 && (props[name1] = value, delete props[index]), (hooks = jQuery.cssHooks[name1]) && "expand" in hooks) // not quite $.extend, this wont overwrite keys already present.
             // also - reusing 'index' from above because we have the correct "name"
-            for(index in value = hooks.expand(value), delete props[name1], value)(index in props) || (props[index] = value[index], specialEasing[index] = easing);
+            for(index in value = hooks.expand(value), delete props[name1], value)index in props || (props[index] = value[index], specialEasing[index] = easing);
             else specialEasing[name1] = easing;
         }(props, animation.opts.specialEasing); index < length; index++)if (result = animationPrefilters[index].call(animation, elem, props, animation.opts)) return result;
         // attach callbacks from options