diff --git a/packages/pluginutils/src/attachScopes.ts b/packages/pluginutils/src/attachScopes.ts index b8a33a8ea..1ff2764a0 100755 --- a/packages/pluginutils/src/attachScopes.ts +++ b/packages/pluginutils/src/attachScopes.ts @@ -97,6 +97,14 @@ const attachScopes: AttachScopes = function attachScopes(ast, propertyName = 'sc } } + // static clause has its own function scope + if (node.type === 'StaticBlock') { + newScope = new Scope({ + parent: scope, + block: false + }); + } + // create new for scope if (/For(?:In|Of)?Statement/.test(node.type)) { newScope = new Scope({ diff --git a/packages/pluginutils/test/attachScopes.ts b/packages/pluginutils/test/attachScopes.ts index 49f9d07c0..24c5b7c7d 100755 --- a/packages/pluginutils/test/attachScopes.ts +++ b/packages/pluginutils/test/attachScopes.ts @@ -73,6 +73,28 @@ test('supports catch without a parameter', () => { }).not.toThrow(); }); +test('supports static block', () => { + const ast = parse( + ` + class Foo { + static { + let a = 10; + } + } + `, + { ecmaVersion: 2022, sourceType: 'module' } + ) as unknown as estree.Program; + + const scope = attachScopes(ast, 'scope'); + expect(scope.contains('a')).toBeFalsy(); + + const classDeclaration = ast.body[0] as estree.ClassDeclaration; + const classBody = classDeclaration.body; + const staticBlock = classBody.body[0] as estree.StaticBlock & { scope: AttachedScope }; + + expect(staticBlock.scope.contains('a')).toBeTruthy(); +}); + test('supports ForStatement', () => { const ast = parse( `