Repository: swc-project/swc (rust)

Issue:
Class fields named 'export' not allowed when using decorators
### Describe the bug

When using the option `"decorators": true`, using the name `export` for class fields and methods is no longer allowed, returning this error:

```
  × `export` is not allowed here
   ╭─[file.js:3:3]
 3 │ export = true;
   · ──────
   ╰────


Caused by:
    0: failed to process input file
    1: Syntax Error
Error: Failed to compile 1 file with swc.
    at Object.assertCompilationResult (/Users/maclockard/workspace/hex-inc/hex/node_modules/@swc/cli/lib/swc/util.js:113:15)
    at files (/Users/maclockard/workspace/hex-inc/hex/node_modules/@swc/cli/lib/swc/file.js:173:18)
    at async _default (/Users/maclockard/workspace/hex-inc/hex/node_modules/@swc/cli/lib/swc/file.js:192:9)
```

This error occurs for both syntax `"ecmascript"` and `"typescript"`. Also worth noting with the same config, the name `export` is allowed if there is not a decorator on the field.

### Input code

```typescript
export class MyClass {
  @MyDecorator()
  export = true;
}
```


### Config

```json
{
  "$schema": "https://json.schemastore.org/swcrc",
  "jsc": {
    "parser": {
      "syntax": "ecmascript",
      "decorators": true
    }
  }
}
```


### Playground link

https://play.swc.rs/?version=1.2.218&code=H4sIAAAAAAAAA0utKMgvKlFIzkksLlbwrXQG09VcCgoOvpUuqcn5RYkl%2BUUamkCBVIhKW4WSotJUa65aAJrlKr86AAAA&config=H4sIAAAAAAAAA0WOQQoDIQxF75K123bhHXqI4GQGy2gkyUBFvHu1WGYX%2Fn%2F%2FkQZvDeAbFBQlmZfWbPgBDxQSapBYDBxsFFjQWBS8yUVuDAe046nUHRjKQTZH%2Bhj0yay0Wgcp5rjX6Q6cipDqXWE%2Bzj%2FZhyjxds2ggdVCP%2BET%2Bu1Yu6ivBc5n%2BhejSMoXxwAAAA%3D%3D

### Expected behavior

I would expect swc to be able to compile a class that uses the word `export` as a field name or method name when using decorators.

### Actual behavior

_No response_

### Version

1.2.218

### Additional context

Here's an example of typescript compiling the exact same code: [playground link](https://www.typescriptlang.org/play?#code/KYDwDg9gTgLgBAYwDYEMDOa4FkCeBhVDOAbwCg44ABXAEWAWhRmgAoBKcuUSWOAXjgwoAV2ABuUgF8gA) (ignore the type error for now, its just because I'm not defining the decorator to keep the code snippet short).

Pull request:
fix(es/parser): Allow `export` after decorators when valid
**Description:**


**Related issue:**

 - Closes #5276

Patch:
diff --git a/crates/swc_ecma_parser/src/parser/class_and_fn.rs b/crates/swc_ecma_parser/src/parser/class_and_fn.rs
index fce10ad3e4..e4e178923e 100644
--- a/crates/swc_ecma_parser/src/parser/class_and_fn.rs
+++ b/crates/swc_ecma_parser/src/parser/class_and_fn.rs
@@ -263,11 +263,14 @@ impl<I: Tokens> Parser<I> {
         }
 
         if is!(self, "export") {
-            if !allow_export {
+            if !self.ctx().in_class && !self.ctx().in_function && !allow_export {
                 syntax_error!(self, self.input.cur_span(), SyntaxError::ExportNotAllowed);
             }
 
-            if !self.syntax().decorators_before_export() {
+            if !self.ctx().in_class
+                && !self.ctx().in_function
+                && !self.syntax().decorators_before_export()
+            {
                 syntax_error!(self, span!(self, start), SyntaxError::DecoratorOnExport);
             }
         } else if !is!(self, "class") {


Test patch:
diff --git a/crates/swc_ecma_parser/tests/js.rs b/crates/swc_ecma_parser/tests/js.rs
index a7de707d50..45e736ed22 100644
--- a/crates/swc_ecma_parser/tests/js.rs
+++ b/crates/swc_ecma_parser/tests/js.rs
@@ -93,6 +93,7 @@ where
             Syntax::Es(EsConfig {
                 explicit_resource_management: true,
                 import_attributes: true,
+                decorators: true,
                 ..Default::default()
             }),
             EsVersion::Es2015,
diff --git a/crates/swc_ecma_parser/tests/js/issue-5276/input.js b/crates/swc_ecma_parser/tests/js/issue-5276/input.js
new file mode 100644
index 0000000000..6e42ef33ce
--- /dev/null
+++ b/crates/swc_ecma_parser/tests/js/issue-5276/input.js
@@ -0,0 +1,4 @@
+export class MyClass {
+    @MyDecorator()
+    export = true;
+}
diff --git a/crates/swc_ecma_parser/tests/js/issue-5276/input.js.json b/crates/swc_ecma_parser/tests/js/issue-5276/input.js.json
new file mode 100644
index 0000000000..a2cb9ecd03
--- /dev/null
+++ b/crates/swc_ecma_parser/tests/js/issue-5276/input.js.json
@@ -0,0 +1,112 @@
+{
+  "type": "Module",
+  "span": {
+    "start": 1,
+    "end": 63,
+    "ctxt": 0
+  },
+  "body": [
+    {
+      "type": "ExportDeclaration",
+      "span": {
+        "start": 1,
+        "end": 63,
+        "ctxt": 0
+      },
+      "declaration": {
+        "type": "ClassDeclaration",
+        "identifier": {
+          "type": "Identifier",
+          "span": {
+            "start": 14,
+            "end": 21,
+            "ctxt": 0
+          },
+          "value": "MyClass",
+          "optional": false
+        },
+        "declare": false,
+        "span": {
+          "start": 8,
+          "end": 63,
+          "ctxt": 0
+        },
+        "decorators": [],
+        "body": [
+          {
+            "type": "ClassProperty",
+            "span": {
+              "start": 28,
+              "end": 61,
+              "ctxt": 0
+            },
+            "key": {
+              "type": "Identifier",
+              "span": {
+                "start": 47,
+                "end": 53,
+                "ctxt": 0
+              },
+              "value": "export",
+              "optional": false
+            },
+            "value": {
+              "type": "BooleanLiteral",
+              "span": {
+                "start": 56,
+                "end": 60,
+                "ctxt": 0
+              },
+              "value": true
+            },
+            "typeAnnotation": null,
+            "isStatic": false,
+            "decorators": [
+              {
+                "type": "Decorator",
+                "span": {
+                  "start": 28,
+                  "end": 42,
+                  "ctxt": 0
+                },
+                "expression": {
+                  "type": "CallExpression",
+                  "span": {
+                    "start": 29,
+                    "end": 42,
+                    "ctxt": 0
+                  },
+                  "callee": {
+                    "type": "Identifier",
+                    "span": {
+                      "start": 29,
+                      "end": 40,
+                      "ctxt": 0
+                    },
+                    "value": "MyDecorator",
+                    "optional": false
+                  },
+                  "arguments": [],
+                  "typeArguments": null
+                }
+              }
+            ],
+            "accessibility": null,
+            "isAbstract": false,
+            "isOptional": false,
+            "isOverride": false,
+            "readonly": false,
+            "declare": false,
+            "definite": false
+          }
+        ],
+        "superClass": null,
+        "isAbstract": false,
+        "typeParams": null,
+        "superTypeParams": null,
+        "implements": []
+      }
+    }
+  ],
+  "interpreter": null
+}