fix(traverse): create scope for function nested in class method (#3234)

Fixes a bug in #3229.

The logic to prevent a duplicate scope being created for a `Function` which is a `MethodDefinition` would also stop a scope being created for inner function in:

```rs
class X {
  foo() {
    function bar() {}
  }
}
```

or

```rs
class X {
  foo( bar = function() {} ) {}
}
```

This PR fixes that. This change also allows removing `ScopeFlags::Method` which #3229 added.
This commit is contained in:
overlookmotel 2024-05-11 12:06:59 +00:00
parent fd6a1aa1d2
commit 4e20b04acc
3 changed files with 7 additions and 8 deletions

View file

@ -2133,8 +2133,10 @@ pub struct BindingRestElement<'a> {
/// Function Definitions
#[visited_node(
scope(ScopeFlags::Function),
// Don't create a 2nd scope if `MethodDefinition` already created one
scope_if((ctx.scope() & ScopeFlags::Modifiers).is_empty()),
// Don't create scope if this is a method - `MethodDefinition` already created one.
// `ctx.ancestor(2).unwrap()` not `ctx.parent()` because this code is inserted
// into `walk_function` *after* `Function` is added to stack.
scope_if(matches!(ctx.ancestor(2).unwrap(), Ancestor::MethodDefinitionValue(_))),
strict_if(self.body.as_ref().is_some_and(|body| body.has_use_strict_directive()))
)]
#[derive(Debug, Hash)]
@ -2586,7 +2588,7 @@ impl MethodDefinitionKind {
pub fn scope_flags(self) -> ScopeFlags {
match self {
Self::Constructor => ScopeFlags::Constructor,
Self::Method => ScopeFlags::Method,
Self::Method => ScopeFlags::empty(),
Self::Get => ScopeFlags::GetAccessor,
Self::Set => ScopeFlags::SetAccessor,
}

View file

@ -23,11 +23,8 @@ bitflags! {
const Constructor = 1 << 6;
const GetAccessor = 1 << 7;
const SetAccessor = 1 << 8;
// Only used in `Traverse`
const Method = 1 << 9;
const Var = Self::Top.bits() | Self::Function.bits() | Self::ClassStaticBlock.bits() | Self::TsModuleBlock.bits();
const Modifiers = Self::Constructor.bits() | Self::GetAccessor.bits()
| Self::SetAccessor.bits() | Self::Method.bits();
const Modifiers = Self::Constructor.bits() | Self::GetAccessor.bits() | Self::SetAccessor.bits();
}
}

View file

@ -2228,7 +2228,7 @@ pub(crate) unsafe fn walk_function<'a, Tr: Traverse<'a>>(
) {
traverser.enter_function(&mut *node, ctx);
ctx.push_stack(Ancestor::FunctionId(ancestor::FunctionWithoutId(node)));
let has_scope = (ctx.scope() & ScopeFlags::Modifiers).is_empty();
let has_scope = matches!(ctx.ancestor(2).unwrap(), Ancestor::MethodDefinitionValue(_));
if has_scope {
ctx.push_scope_stack(
ScopeFlags::Function.with_strict_mode(