oxc/crates/oxc_semantic
Dunqing dc2b3c44fb refactor(semantic): add strict mode in scope flags for class definitions (#4156)
related: https://github.com/oxc-project/oxc/issues/4142#issuecomment-2219125356

Although we called `enter_node(Class)`, that doesn't mean we're in the `class` scope. It causes our must to visit decorators before `enter_node`.

Let's look at this case. It causes a syntax error if we don't visit decorators before `enter_node`
```js
// This file was procedurally generated from the following sources:
// - src/decorator/decorator-call-expr-identifier-reference-yield.case
// - src/decorator/syntax/valid/cls-expr-decorators-valid-syntax.template
/*---
description: Decorator @ DecoratorCallExpression (Valid syntax for decorator on class expression)
esid: prod-ClassExpression
features: [class, decorators]
flags: [generated, noStrict]
info: |
    ClassExpression[Yield, Await] :
      DecoratorList[?Yield, ?Await]opt class BindingIdentifier[?Yield, ?Await]opt ClassTail[?Yield, ?Await]

    DecoratorList[Yield, Await] :
      DecoratorList[?Yield, ?Await]opt Decorator[?Yield, ?Await]

    Decorator[Yield, Await] :
      @ DecoratorMemberExpression[?Yield, ?Await]
      @ DecoratorParenthesizedExpression[?Yield, ?Await]
      @ DecoratorCallExpression[?Yield, ?Await]

    ...

    DecoratorCallExpression[Yield, Await] :
      DecoratorMemberExpression[?Yield, ?Await] Arguments[?Yield, ?Await]

    DecoratorMemberExpression[Yield, Await] :
      IdentifierReference[?Yield, ?Await]
      DecoratorMemberExpression[?Yield, ?Await] . IdentifierName
      DecoratorMemberExpression[?Yield, ?Await] . PrivateIdentifier

    IdentifierReference[Yield, Await] :
      [~Yield] yield
      ...

---*/
function decorator() {
  return () => {};
}
var yield = decorator;

var C = @yield() class {};

```
Errors:
```shell
  × The keyword 'yield' is reserved
    ╭─[language/statements/class/decorator/syntax/valid/decorator-call-expr-identifier-reference-yield.js:45:2]
 44 │
 45 │ @yield() class C {}
    ·  ─────
    ╰────
```

The changed code makes more sense. Only if we call `enter_scope` for class, the flags will contain `StrictMode`. Also, we can get the exact `flags` of the `scope` in the `class` at the transformer

For example:

```
class A {
   B() {
       // Before: flags is `Function`
      //  After: flags is `Function | StrictMode`
   }
}
```

The regression tests will be fixed in follow-up PRs
2024-07-14 03:35:12 +00:00
..
examples refactor(semantic): make control flow generation optional. (#3737) 2024-06-18 15:59:38 +00:00
src refactor(semantic): add strict mode in scope flags for class definitions (#4156) 2024-07-14 03:35:12 +00:00
tests/integration refactor(semantic): correct scope in CatchClause (#4192) 2024-07-11 08:45:30 +00:00
Cargo.toml Release crates v0.20.0 (#4189) 2024-07-11 11:05:49 +08:00
CHANGELOG.md Release crates v0.20.0 (#4189) 2024-07-11 11:05:49 +08:00