or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

analysis.mddefinition-system.mdindex.mdreference-system.mdscope-management.mdscope-types.mdvariable-system.md

scope-management.mddocs/

0

# Scope Management

1

2

The ScopeManager class is the central manager for all scopes in analyzed code. It maintains scope hierarchies, variable mappings, and provides scope navigation and querying capabilities.

3

4

## Capabilities

5

6

### ScopeManager Class

7

8

The main class that manages all scopes created during AST analysis.

9

10

```typescript { .api }

11

/**

12

* Central manager for all scopes in analyzed code

13

* @see https://eslint.org/docs/latest/developer-guide/scope-manager-interface#scopemanager-interface

14

*/

15

class ScopeManager {

16

/** Current scope being processed during analysis */

17

currentScope: Scope | null;

18

19

/** WeakMap associating AST nodes with the variables they declare */

20

readonly declaredVariables: WeakMap<TSESTree.Node, Variable[]>;

21

22

/** The root scope (global scope) */

23

globalScope: GlobalScope | null;

24

25

/** WeakMap associating AST nodes with their scopes */

26

readonly nodeToScope: WeakMap<TSESTree.Node, Scope[]>;

27

28

/** All scopes in the analysis */

29

readonly scopes: Scope[];

30

31

/** All variables across all scopes */

32

get variables(): Variable[];

33

}

34

```

35

36

### Scope Environment Queries

37

38

Methods to determine the analysis environment and configuration.

39

40

```typescript { .api }

41

/**

42

* Check if ES6 features are enabled

43

* @returns Always true in TypeScript scope manager

44

*/

45

isES6(): boolean;

46

47

/**

48

* Check if global return is enabled

49

* @returns True if globalReturn option was set during analysis

50

*/

51

isGlobalReturn(): boolean;

52

53

/**

54

* Check if implied strict mode is enabled

55

* @returns True if impliedStrict option was set during analysis

56

*/

57

isImpliedStrict(): boolean;

58

59

/**

60

* Check if source is a module

61

* @returns True if sourceType was set to 'module' during analysis

62

*/

63

isModule(): boolean;

64

65

/**

66

* Check if strict mode is supported

67

* @returns Always true in TypeScript scope manager

68

*/

69

isStrictModeSupported(): boolean;

70

```

71

72

### Variable Discovery

73

74

Methods to find variables declared by specific AST nodes.

75

76

```typescript { .api }

77

/**

78

* Get the variables that a given AST node defines. The gotten variables'

79

* def[].node/def[].parent property is the node.

80

* If the node does not define any variable, this returns an empty array.

81

* @param node - An AST node to get their variables

82

* @returns Array of variables declared by the node

83

*/

84

getDeclaredVariables(node: TSESTree.Node): Variable[];

85

```

86

87

### Scope Navigation

88

89

Methods to navigate and query the scope hierarchy.

90

91

```typescript { .api }

92

/**

93

* Get the scope of a given AST node. The gotten scope's block property is the node.

94

* This method never returns function-expression-name scope. If the node does not

95

* have their scope, this returns null.

96

*

97

* @param node - An AST node to get their scope

98

* @param inner - If the node has multiple scopes, this returns the outermost scope normally.

99

* If inner is true then this returns the innermost scope.

100

* @returns The scope associated with the node, or null if none exists

101

*/

102

acquire(node: TSESTree.Node, inner?: boolean): Scope | null;

103

```

104

105

**Usage Examples:**

106

107

```typescript

108

import { analyze } from "@typescript-eslint/scope-manager";

109

import { parse } from "@typescript-eslint/parser";

110

111

const code = `

112

function outer(x: number) {

113

const y = x * 2;

114

115

function inner(z: number) {

116

return y + z;

117

}

118

119

return inner;

120

}

121

`;

122

123

const ast = parse(code);

124

const scopeManager = analyze(ast, { sourceType: 'module' });

125

126

// Check environment

127

console.log(scopeManager.isModule()); // true

128

console.log(scopeManager.isES6()); // true

129

130

// Get all scopes

131

console.log(`Total scopes: ${scopeManager.scopes.length}`);

132

scopeManager.scopes.forEach((scope, index) => {

133

console.log(`Scope ${index}: ${scope.type}`);

134

});

135

136

// Get variables in global scope

137

if (scopeManager.globalScope) {

138

console.log('Global variables:',

139

scopeManager.globalScope.variables.map(v => v.name)

140

);

141

}

142

143

// Find scope for a specific node

144

const functionNodes = []; // collect function nodes during AST traversal

145

functionNodes.forEach(node => {

146

const scope = scopeManager.acquire(node);

147

if (scope) {

148

console.log(`Function scope type: ${scope.type}`);

149

console.log(`Variables in scope: ${scope.variables.map(v => v.name)}`);

150

}

151

});

152

153

// Get declared variables for each node

154

const declarationNodes = []; // collect declaration nodes during AST traversal

155

declarationNodes.forEach(node => {

156

const variables = scopeManager.getDeclaredVariables(node);

157

variables.forEach(variable => {

158

console.log(`Variable ${variable.name} declared by node type ${node.type}`);

159

});

160

});

161

162

// Get all variables across all scopes

163

const allVariables = scopeManager.variables;

164

console.log(`Total variables: ${allVariables.length}`);

165

allVariables.forEach(variable => {

166

console.log(`${variable.name} in ${variable.scope.type} scope`);

167

});

168

```

169

170

### Scope Creation Methods

171

172

The ScopeManager provides methods to create different types of scopes during analysis. These are typically used internally but are part of the public API:

173

174

```typescript { .api }

175

// Block scopes

176

nestBlockScope(node: TSESTree.BlockStatement): BlockScope;

177

nestCatchScope(node: TSESTree.CatchClause): CatchScope;

178

nestForScope(node: TSESTree.ForStatement | TSESTree.ForInStatement | TSESTree.ForOfStatement): ForScope;

179

nestSwitchScope(node: TSESTree.SwitchStatement): SwitchScope;

180

nestWithScope(node: TSESTree.WithStatement): WithScope;

181

182

// Function scopes

183

nestFunctionScope(node: TSESTree.Function, isMethodDefinition: boolean): FunctionScope;

184

nestFunctionExpressionNameScope(node: TSESTree.FunctionExpression): FunctionExpressionNameScope;

185

186

// Class and type scopes

187

nestClassScope(node: TSESTree.ClassDeclaration | TSESTree.ClassExpression): ClassScope;

188

nestClassFieldInitializerScope(node: TSESTree.PropertyDefinition): ClassFieldInitializerScope;

189

nestClassStaticBlockScope(node: TSESTree.StaticBlock): ClassStaticBlockScope;

190

nestTypeScope(node: TSESTree.TSTypeAnnotation): TypeScope;

191

nestFunctionTypeScope(node: TSESTree.TSFunctionType): FunctionTypeScope;

192

nestConditionalTypeScope(node: TSESTree.TSConditionalType): ConditionalTypeScope;

193

nestMappedTypeScope(node: TSESTree.TSMappedType): MappedTypeScope;

194

195

// Module and namespace scopes

196

nestModuleScope(node: TSESTree.Program): ModuleScope;

197

nestTSModuleScope(node: TSESTree.TSModuleDeclaration): TSModuleScope;

198

nestTSEnumScope(node: TSESTree.TSEnumDeclaration): TSEnumScope;

199

200

// Global scope

201

nestGlobalScope(node: TSESTree.Program): GlobalScope;

202

```

203

204

### Scope Hierarchy Navigation

205

206

```typescript

207

// Navigate scope hierarchy

208

const currentScope = scopeManager.currentScope;

209

if (currentScope) {

210

console.log(`Current scope: ${currentScope.type}`);

211

212

// Parent scope

213

if (currentScope.upper) {

214

console.log(`Parent scope: ${currentScope.upper.type}`);

215

}

216

217

// Child scopes

218

currentScope.childScopes.forEach((child, index) => {

219

console.log(`Child ${index}: ${child.type}`);

220

});

221

222

// Variables in current scope

223

currentScope.variables.forEach(variable => {

224

console.log(`Variable: ${variable.name}`);

225

console.log(`References: ${variable.references.length}`);

226

});

227

}

228

```