Repository: swc-project/swc (rust)

Issue:
Stage 3 Decorator on computed method breaks future inner classes
### Describe the bug

If you use a stage 3 decorator on a computed method, the decorator gets applied to subsequent classes contained inside of other methods (decorated or not).

The decorated method needs to have a computed name, but the subsequent method does not. The contents of the decorated method don't seem to matter: a completely empty decorated method produces the bug.

The computed property can be a string literal (it doesn't have to be a `[computed]`).

### Input code

```typescript
class Tests {
  @test
  'computed'() {}

  id() { class Bar {} }
}

function test(fn) {
  return fn;
}


let t = new Tests();
t.id()
```


### Config

```json
{
  "$schema": "https://json.schemastore.org/swcrc.json",
  "module": { "type": "es6" },
  "jsc": {
    "target": "es2022",
    "transform": { "useDefineForClassFields": true, "decoratorVersion": "2022-03" },
    "parser": { "syntax": "typescript", "tsx": false, "decorators": true }
  }
}
```


### Playground link

https://play.swc.rs/?version=1.3.62&code=H4sIAAAAAAAAAx1NOQrDMBDs9xXTWWryARMI7tPlA0ZagcBeBWlFCuO%2FZ6VqhjnDsbeGDzdtwEXAS40bLqGc364cF%2Bdx3WRSjoMizMq2V5Nxk1mpS9BcBKPrkvi5VFl7FSRZR4YOViieEP7hXWJOmev8dX4lfYzxP3lb6juNAAAA&config=H4sIAAAAAAAAA2WPwQqDQAxE736F5GxBLPTQf%2Bi190WzZYtuJIlQEf%2FdrFax9JZM5s2QKctzeEsN93yy0RZlF8UTd4dkYoM1sVPiJ7IEinaDqqyqS3mF1TMXG907FuQzKmNU90mAjj1KzaFXKP6CxRzKA%2F6kqeMXamJRUt2Xg5ZI0GTvWsGkrQB01Awtnl6xwg2%2BwWEK8thtqW8DQwx%2B3AOzeQEzww6KFgEAAA%3D%3D

### Expected behavior

I expect the class in the `id` method to have no decorators applied to it.

### Actual behavior

The `test` decorator is applied to the `id` method.

### Version

1.3.62

### Additional context

_No response_

Pull request:
fix(es/compat): Make stage 3 decorator pass use correct state for inner classes
**Description:**


**Related issue:**

 - Closes #7499.

Patch:
diff --git a/crates/swc_ecma_transforms_proposal/src/decorator_2022_03.rs b/crates/swc_ecma_transforms_proposal/src/decorator_2022_03.rs
index a4dea37f85..b08bb7522c 100644
--- a/crates/swc_ecma_transforms_proposal/src/decorator_2022_03.rs
+++ b/crates/swc_ecma_transforms_proposal/src/decorator_2022_03.rs
@@ -1,4 +1,7 @@
-use std::{iter::once, mem::transmute};
+use std::{
+    iter::once,
+    mem::{take, transmute},
+};
 
 use rustc_hash::FxHashMap;
 use swc_atoms::JsWord;
@@ -15,10 +18,25 @@ pub fn decorator_2022_03() -> impl VisitMut + Fold {
     as_folder(Decorator202203::default())
 }
 
-#[derive(Debug, Default)]
+#[derive(Default)]
 struct Decorator202203 {
     /// Variables without initializer.
     extra_vars: Vec<VarDeclarator>,
+
+    extra_lets: Vec<VarDeclarator>,
+
+    state: ClassState,
+
+    /// Prepended before the class
+    pre_class_inits: Vec<Box<Expr>>,
+
+    rename_map: FxHashMap<Id, Id>,
+
+    extra_exports: Vec<ExportSpecifier>,
+}
+
+#[derive(Default)]
+struct ClassState {
     static_lhs: Vec<Ident>,
     proto_lhs: Vec<Ident>,
 
@@ -33,17 +51,8 @@ struct Decorator202203 {
     /// Injected into static blocks.
     extra_stmts: Vec<Stmt>,
 
-    /// Prepended before the class
-    pre_class_inits: Vec<Box<Expr>>,
-
     class_lhs: Vec<Option<Pat>>,
     class_decorators: Vec<Option<ExprOrSpread>>,
-
-    extra_lets: Vec<VarDeclarator>,
-
-    extra_exports: Vec<ExportSpecifier>,
-
-    rename_map: FxHashMap<Id, Id>,
 }
 
 impl Decorator202203 {
@@ -81,11 +90,11 @@ impl Decorator202203 {
 
     /// Moves `cur_inits` to `extra_stmts`.
     fn consume_inits(&mut self) {
-        if self.init_proto_args.is_empty()
-            && self.init_static_args.is_empty()
-            && self.init_proto.is_none()
-            && self.init_static.is_none()
-            && self.class_decorators.is_empty()
+        if self.state.init_proto_args.is_empty()
+            && self.state.init_static_args.is_empty()
+            && self.state.init_proto.is_none()
+            && self.state.init_static.is_none()
+            && self.state.class_decorators.is_empty()
         {
             return;
         }
@@ -93,11 +102,16 @@ impl Decorator202203 {
         let mut e_lhs = vec![];
         let mut combined_args = vec![ThisExpr { span: DUMMY_SP }.as_arg()];
 
-        for id in self.static_lhs.drain(..).chain(self.proto_lhs.drain(..)) {
+        for id in self
+            .state
+            .static_lhs
+            .drain(..)
+            .chain(self.state.proto_lhs.drain(..))
+        {
             e_lhs.push(Some(id.into()));
         }
 
-        if let Some(init) = self.init_proto.clone() {
+        if let Some(init) = self.state.init_proto.clone() {
             self.extra_vars.push(VarDeclarator {
                 span: DUMMY_SP,
                 name: Pat::Ident(init.clone().into()),
@@ -108,7 +122,7 @@ impl Decorator202203 {
             e_lhs.push(Some(init.into()));
         }
 
-        if let Some(init) = self.init_static.clone() {
+        if let Some(init) = self.state.init_static.clone() {
             self.extra_vars.push(VarDeclarator {
                 span: DUMMY_SP,
                 name: Pat::Ident(init.clone().into()),
@@ -123,9 +137,10 @@ impl Decorator202203 {
             ArrayLit {
                 span: DUMMY_SP,
                 elems: self
+                    .state
                     .init_static_args
                     .drain(..)
-                    .chain(self.init_proto_args.drain(..))
+                    .chain(self.state.init_proto_args.drain(..))
                     .collect(),
             }
             .as_arg(),
@@ -134,7 +149,7 @@ impl Decorator202203 {
         combined_args.push(
             ArrayLit {
                 span: DUMMY_SP,
-                elems: self.class_decorators.take(),
+                elems: self.state.class_decorators.take(),
             }
             .as_arg(),
         );
@@ -153,14 +168,14 @@ impl Decorator202203 {
             }))
         };
 
-        let c_pat = if self.class_lhs.is_empty() {
+        let c_pat = if self.state.class_lhs.is_empty() {
             None
         } else {
             Some(ObjectPatProp::KeyValue(KeyValuePatProp {
                 key: PropName::Ident(quote_ident!("c")),
                 value: Box::new(Pat::Array(ArrayPat {
                     span: DUMMY_SP,
-                    elems: self.class_lhs.take(),
+                    elems: self.state.class_lhs.take(),
                     type_ann: Default::default(),
                     optional: false,
                 })),
@@ -184,13 +199,13 @@ impl Decorator202203 {
             })),
         }));
 
-        self.extra_stmts.push(Stmt::Expr(ExprStmt {
+        self.state.extra_stmts.push(Stmt::Expr(ExprStmt {
             span: DUMMY_SP,
             expr,
         }));
 
-        if let Some(init) = self.init_static.take() {
-            self.extra_stmts.push(Stmt::Expr(ExprStmt {
+        if let Some(init) = self.state.init_static.take() {
+            self.state.extra_stmts.push(Stmt::Expr(ExprStmt {
                 span: DUMMY_SP,
                 expr: Box::new(Expr::Call(CallExpr {
                     span: DUMMY_SP,
@@ -332,8 +347,10 @@ impl Decorator202203 {
             replace_ident(&mut class.body, ident.to_id(), &new_class_name);
         }
 
-        self.class_lhs.push(Some(new_class_name.clone().into()));
-        self.class_lhs.push(Some(init_class.clone().into()));
+        self.state
+            .class_lhs
+            .push(Some(new_class_name.clone().into()));
+        self.state.class_lhs.push(Some(init_class.clone().into()));
 
         self.extra_vars.push(VarDeclarator {
             span: DUMMY_SP,
@@ -343,7 +360,7 @@ impl Decorator202203 {
         });
 
         let decorators = self.preserve_side_effect_of_decorators(class.decorators.take());
-        self.class_decorators.extend(decorators);
+        self.state.class_decorators.extend(decorators);
 
         {
             let call_stmt = CallExpr {
@@ -367,6 +384,8 @@ impl Decorator202203 {
     }
 
     fn handle_class_decl(&mut self, c: &mut ClassDecl) -> Option<Stmt> {
+        let old_state = take(&mut self.state);
+
         if !c.class.decorators.is_empty() {
             let decorators = self.preserve_side_effect_of_decorators(c.class.decorators.take());
 
@@ -392,10 +411,12 @@ impl Decorator202203 {
             self.rename_map
                 .insert(c.ident.to_id(), new_class_name.to_id());
 
-            self.class_lhs.push(Some(new_class_name.clone().into()));
-            self.class_lhs.push(Some(init_class.clone().into()));
+            self.state
+                .class_lhs
+                .push(Some(new_class_name.clone().into()));
+            self.state.class_lhs.push(Some(init_class.clone().into()));
 
-            self.class_decorators.extend(decorators);
+            self.state.class_decorators.extend(decorators);
 
             let mut body = c.class.body.take();
 
@@ -594,6 +615,8 @@ impl Decorator202203 {
                     implements: Default::default(),
                 });
 
+                self.state = old_state;
+
                 return Some(
                     NewExpr {
                         span: DUMMY_SP,
@@ -633,10 +656,14 @@ impl Decorator202203 {
                     },
                 }));
 
+                self.state = old_state;
+
                 return Some(Stmt::Decl(Decl::Class(c.take())));
             }
         }
 
+        self.state = old_state;
+
         None
     }
 
@@ -706,12 +733,12 @@ impl VisitMut for Decorator202203 {
     noop_visit_mut_type!();
 
     fn visit_mut_class(&mut self, n: &mut Class) {
-        let old_stmts = self.extra_stmts.take();
+        let old_stmts = self.state.extra_stmts.take();
 
         n.visit_mut_children_with(self);
 
-        if !self.is_init_proto_called {
-            if let Some(init_proto) = self.init_proto.clone() {
+        if !self.state.is_init_proto_called {
+            if let Some(init_proto) = self.state.init_proto.clone() {
                 let c = self.ensure_constructor(n);
 
                 inject_after_super(
@@ -728,23 +755,23 @@ impl VisitMut for Decorator202203 {
 
         self.consume_inits();
 
-        if !self.extra_stmts.is_empty() {
+        if !self.state.extra_stmts.is_empty() {
             n.body.insert(
                 0,
                 ClassMember::StaticBlock(StaticBlock {
                     span: DUMMY_SP,
                     body: BlockStmt {
                         span: DUMMY_SP,
-                        stmts: self.extra_stmts.take(),
+                        stmts: self.state.extra_stmts.take(),
                     },
                 }),
             );
         }
 
-        self.init_proto = None;
-        self.is_init_proto_called = false;
+        self.state.init_proto = None;
+        self.state.is_init_proto_called = false;
 
-        self.extra_stmts = old_stmts;
+        self.state.extra_stmts = old_stmts;
     }
 
     fn visit_mut_class_member(&mut self, n: &mut ClassMember) {
@@ -768,10 +795,12 @@ impl VisitMut for Decorator202203 {
             });
 
             if p.is_static {
-                self.init_static
+                self.state
+                    .init_static
                     .get_or_insert_with(|| private_ident!("_initStatic"));
             } else {
-                self.init_proto
+                self.state
+                    .init_proto
                     .get_or_insert_with(|| private_ident!("_initProto"));
             }
 
@@ -808,15 +837,15 @@ impl VisitMut for Decorator202203 {
                 .as_arg(),
             );
             if p.is_static {
-                self.init_static_args.push(arg);
+                self.state.init_static_args.push(arg);
             } else {
-                self.init_proto_args.push(arg);
+                self.state.init_proto_args.push(arg);
             }
 
             if p.is_static {
-                self.static_lhs.push(init.clone());
+                self.state.static_lhs.push(init.clone());
             } else {
-                self.proto_lhs.push(init.clone());
+                self.state.proto_lhs.push(init.clone());
             }
 
             match p.kind {
@@ -920,23 +949,25 @@ impl VisitMut for Decorator202203 {
                         value: if accessor.decorators.is_empty() {
                             accessor.value
                         } else {
-                            let init_proto = if self.is_init_proto_called || accessor.is_static {
-                                None
-                            } else {
-                                self.is_init_proto_called = true;
-
-                                let init_proto = self
-                                    .init_proto
-                                    .get_or_insert_with(|| private_ident!("_initProto"))
-                                    .clone();
-
-                                Some(Box::new(Expr::Call(CallExpr {
-                                    span: DUMMY_SP,
-                                    callee: init_proto.clone().as_callee(),
-                                    args: vec![ThisExpr { span: DUMMY_SP }.as_arg()],
-                                    type_args: Default::default(),
-                                })))
-                            };
+                            let init_proto =
+                                if self.state.is_init_proto_called || accessor.is_static {
+                                    None
+                                } else {
+                                    self.state.is_init_proto_called = true;
+
+                                    let init_proto = self
+                                        .state
+                                        .init_proto
+                                        .get_or_insert_with(|| private_ident!("_initProto"))
+                                        .clone();
+
+                                    Some(Box::new(Expr::Call(CallExpr {
+                                        span: DUMMY_SP,
+                                        callee: init_proto.clone().as_callee(),
+                                        args: vec![ThisExpr { span: DUMMY_SP }.as_arg()],
+                                        type_args: Default::default(),
+                                    })))
+                                };
 
                             let init_call = Box::new(Expr::Call(CallExpr {
                                 span: DUMMY_SP,
@@ -1161,22 +1192,26 @@ impl VisitMut for Decorator202203 {
                         };
 
                         if accessor.is_static {
-                            self.static_lhs.push(init);
-                            self.init_static_args.push(Some(initialize_init));
-                            self.static_lhs
+                            self.state.static_lhs.push(init);
+                            self.state.init_static_args.push(Some(initialize_init));
+                            self.state
+                                .static_lhs
                                 .extend(getter_var.into_iter().chain(setter_var));
                         } else {
-                            self.proto_lhs.push(init);
-                            self.init_proto_args.push(Some(initialize_init));
-                            self.proto_lhs
+                            self.state.proto_lhs.push(init);
+                            self.state.init_proto_args.push(Some(initialize_init));
+                            self.state
+                                .proto_lhs
                                 .extend(getter_var.into_iter().chain(setter_var));
                         }
 
                         if accessor.is_static {
-                            self.init_static
+                            self.state
+                                .init_static
                                 .get_or_insert_with(|| private_ident!("_initStatic"));
                         } else {
-                            self.init_proto
+                            self.state
+                                .init_proto
                                 .get_or_insert_with(|| private_ident!("_initProto"));
                         }
                     }
@@ -1283,10 +1318,12 @@ impl VisitMut for Decorator202203 {
         let (name, _init) = self.initializer_name(&mut n.key, "call");
 
         if n.is_static {
-            self.init_static
+            self.state
+                .init_static
                 .get_or_insert_with(|| private_ident!("_initStatic"));
         } else {
-            self.init_proto
+            self.state
+                .init_proto
                 .get_or_insert_with(|| private_ident!("_initProto"));
         }
 
@@ -1312,9 +1349,9 @@ impl VisitMut for Decorator202203 {
             .as_arg(),
         );
         if n.is_static {
-            self.init_static_args.push(arg);
+            self.state.init_static_args.push(arg);
         } else {
-            self.init_proto_args.push(arg);
+            self.state.init_proto_args.push(arg);
         }
     }
 
@@ -1361,11 +1398,11 @@ impl VisitMut for Decorator202203 {
         };
 
         if p.is_static {
-            self.static_lhs.push(init);
-            self.init_static_args.push(initialize_init);
+            self.state.static_lhs.push(init);
+            self.state.init_static_args.push(initialize_init);
         } else {
-            self.proto_lhs.push(init);
-            self.init_proto_args.push(initialize_init);
+            self.state.proto_lhs.push(init);
+            self.state.init_proto_args.push(initialize_init);
         }
     }
 
@@ -1586,11 +1623,11 @@ impl VisitMut for Decorator202203 {
         };
 
         if p.is_static {
-            self.static_lhs.push(init);
-            self.init_static_args.push(Some(initialize_init));
+            self.state.static_lhs.push(init);
+            self.state.init_static_args.push(Some(initialize_init));
         } else {
-            self.proto_lhs.push(init);
-            self.init_proto_args.push(Some(initialize_init));
+            self.state.proto_lhs.push(init);
+            self.state.init_proto_args.push(Some(initialize_init));
         }
     }
 
@@ -1608,9 +1645,9 @@ impl VisitMut for Decorator202203 {
     }
 
     fn visit_mut_stmts(&mut self, n: &mut Vec<Stmt>) {
+        let old_state = take(&mut self.state);
         let old_pre_class_inits = self.pre_class_inits.take();
         let old_extra_lets = self.extra_lets.take();
-        let old_extra_stmts = self.extra_stmts.take();
         let old_extra_vars = self.extra_vars.take();
 
         let mut new = Vec::with_capacity(n.len());
@@ -1650,9 +1687,9 @@ impl VisitMut for Decorator202203 {
         *n = new;
 
         self.extra_vars = old_extra_vars;
-        self.extra_stmts = old_extra_stmts;
         self.extra_lets = old_extra_lets;
         self.pre_class_inits = old_pre_class_inits;
+        self.state = old_state;
     }
 }
 


Test patch:
diff --git a/crates/swc_ecma_transforms_proposal/tests/decorators/2022-03-misc--to-es2015/valid-expression-formats/output.js b/crates/swc_ecma_transforms_proposal/tests/decorators/2022-03-misc--to-es2015/valid-expression-formats/output.js
index 12ff37928a..055b87f437 100644
--- a/crates/swc_ecma_transforms_proposal/tests/decorators/2022-03-misc--to-es2015/valid-expression-formats/output.js
+++ b/crates/swc_ecma_transforms_proposal/tests/decorators/2022-03-misc--to-es2015/valid-expression-formats/output.js
@@ -1,4 +1,4 @@
-var _dec, _dec1, _dec2, _dec3, _initClass, _dec4, _dec5, _dec6, _dec7;
+var _dec, _dec1, _dec2, _dec3, _initClass, _dec4, _dec5, _dec6, _dec7, _initProto;
 const dec = ()=>{};
 let _Foo;
 _dec = call(), _dec1 = chain.expr(), _dec2 = arbitrary + expr, _dec3 = array[expr], _dec4 = call(), _dec5 = chain.expr(), _dec6 = arbitrary + expr, _dec7 = array[expr];
@@ -7,40 +7,22 @@ class Foo {
     method() {}
     makeClass() {
         var _Nested, __;
-        var _dec8, _init_bar, _initProto;
-        _dec8 = _class_private_field_get(this, _a);
+        var _dec, _init_bar;
+        _dec = _class_private_field_get(this, _a);
         return _Nested = class Nested {
             constructor(){
                 _define_property(this, "bar", _init_bar(this));
-                _initProto(this);
             }
         }, __ = {
             writable: true,
             value: (()=>{
-                ({ e: [_init_bar, _initProto] , c: [_Foo, _initClass]  } = _apply_decs_2203_r(_Nested, [
+                ({ e: [_init_bar] } = _apply_decs_2203_r(_Nested, [
                     [
-                        [
-                            dec,
-                            _dec4,
-                            _dec5,
-                            _dec6,
-                            _dec7
-                        ],
-                        2,
-                        "method"
-                    ],
-                    [
-                        _dec8,
+                        _dec,
                         0,
                         "bar"
                     ]
-                ], [
-                    dec,
-                    _dec,
-                    _dec1,
-                    _dec2,
-                    _dec3
-                ]));
+                ], []));
             })()
         }, _Nested;
     }
@@ -49,9 +31,34 @@ class Foo {
             writable: true,
             value: void 0
         });
+        _initProto(this);
     }
 }
 var __ = {
+    writable: true,
+    value: (()=>{
+        ({ e: [_initProto], c: [_Foo, _initClass] } = _apply_decs_2203_r(Foo, [
+            [
+                [
+                    dec,
+                    _dec4,
+                    _dec5,
+                    _dec6,
+                    _dec7
+                ],
+                2,
+                "method"
+            ]
+        ], [
+            dec,
+            _dec,
+            _dec1,
+            _dec2,
+            _dec3
+        ]));
+    })()
+};
+var __1 = {
     writable: true,
     value: (()=>{
         _initClass();
diff --git a/crates/swc_ecma_transforms_proposal/tests/decorators/2022-03-misc/valid-expression-formats/output.js b/crates/swc_ecma_transforms_proposal/tests/decorators/2022-03-misc/valid-expression-formats/output.js
index aea1c01093..203e60bff0 100644
--- a/crates/swc_ecma_transforms_proposal/tests/decorators/2022-03-misc/valid-expression-formats/output.js
+++ b/crates/swc_ecma_transforms_proposal/tests/decorators/2022-03-misc/valid-expression-formats/output.js
@@ -1,42 +1,46 @@
-var _dec, _dec1, _dec2, _dec3, _initClass, _dec4, _dec5, _dec6, _dec7;
+var _dec, _dec1, _dec2, _dec3, _initClass, _dec4, _dec5, _dec6, _dec7, _initProto;
 const dec = ()=>{};
 let _Foo;
 _dec = call(), _dec1 = chain.expr(), _dec2 = arbitrary + expr, _dec3 = array[expr], _dec4 = call(), _dec5 = chain.expr(), _dec6 = arbitrary + expr, _dec7 = array[expr];
 class Foo {
+    static{
+        ({ e: [_initProto], c: [_Foo, _initClass] } = _apply_decs_2203_r(this, [
+            [
+                [
+                    dec,
+                    _dec4,
+                    _dec5,
+                    _dec6,
+                    _dec7
+                ],
+                2,
+                "method"
+            ]
+        ], [
+            dec,
+            _dec,
+            _dec1,
+            _dec2,
+            _dec3
+        ]));
+    }
+    constructor(){
+        _initProto(this);
+    }
     #a;
     method() {}
     makeClass() {
-        var _dec8, _init_bar, _initProto;
-        _dec8 = this.#a;
+        var _dec, _init_bar;
+        _dec = this.#a;
         return class Nested {
             static{
-                ({ e: [_init_bar, _initProto] , c: [_Foo, _initClass]  } = _apply_decs_2203_r(this, [
+                ({ e: [_init_bar] } = _apply_decs_2203_r(this, [
                     [
-                        [
-                            dec,
-                            _dec4,
-                            _dec5,
-                            _dec6,
-                            _dec7
-                        ],
-                        2,
-                        "method"
-                    ],
-                    [
-                        _dec8,
+                        _dec,
                         0,
                         "bar"
                     ]
-                ], [
-                    dec,
-                    _dec,
-                    _dec1,
-                    _dec2,
-                    _dec3
-                ]));
-            }
-            constructor(){
-                _initProto(this);
+                ], []));
             }
             bar = _init_bar(this);
         };
diff --git a/crates/swc_ecma_transforms_proposal/tests/decorators/issue-7499/1/input.js b/crates/swc_ecma_transforms_proposal/tests/decorators/issue-7499/1/input.js
new file mode 100644
index 0000000000..758c78ba5d
--- /dev/null
+++ b/crates/swc_ecma_transforms_proposal/tests/decorators/issue-7499/1/input.js
@@ -0,0 +1,14 @@
+class Tests {
+    @test
+    'computed'() { }
+
+    id() { class Bar { } }
+}
+
+function test(fn) {
+    return fn;
+}
+
+
+let t = new Tests();
+t.id()
\ No newline at end of file
diff --git a/crates/swc_ecma_transforms_proposal/tests/decorators/issue-7499/1/output.js b/crates/swc_ecma_transforms_proposal/tests/decorators/issue-7499/1/output.js
new file mode 100644
index 0000000000..55883d6e8f
--- /dev/null
+++ b/crates/swc_ecma_transforms_proposal/tests/decorators/issue-7499/1/output.js
@@ -0,0 +1,26 @@
+var _computedKey, _initProto;
+_computedKey = 'computed';
+class Tests {
+    static{
+        ({ e: [_initProto] } = _apply_decs_2203_r(this, [
+            [
+                test,
+                2,
+                _computedKey
+            ]
+        ], []));
+    }
+    constructor(){
+        _initProto(this);
+    }
+    [_computedKey]() {}
+    id() {
+        class Bar {
+        }
+    }
+}
+function test(fn) {
+    return fn;
+}
+let t = new Tests();
+t.id();
diff --git a/crates/swc_ecma_transforms_proposal/tests/decorators/issue-7499/options.json b/crates/swc_ecma_transforms_proposal/tests/decorators/issue-7499/options.json
new file mode 100644
index 0000000000..4ad37b6e47
--- /dev/null
+++ b/crates/swc_ecma_transforms_proposal/tests/decorators/issue-7499/options.json
@@ -0,0 +1,3 @@
+{
+    "plugins": [["proposal-decorators", { "version": "2022-03" }]]
+}