# Scope analysis utilities

## findVariable

```js
const variable = utils.findVariable(initialScope, name);
```

Get the variable of a given name.

### Parameters

| Name         | Type           | Description                                                |
| :----------- | :------------- | :--------------------------------------------------------- |
| initialScope | Scope          | The scope object to start finding variables.               |
| name         | string or Node | The variable name to find. This can be an Identifier node. |

### Return value

The found variable or `null`.

### Example

```js{8}
const { findVariable } = require("eslint-utils")

module.exports = {
    meta: {},
    create(context) {
        return {
            Identifier(node) {
                const variable = findVariable(context.getScope(), node)
            },
        }
    },
}
```

## getInnermostScope

```js
const scope = utils.getInnermostScope(initialScope, node);
```

Get the innermost scope which contains a given node.

### Parameters

| Name         | Type  | Description                           |
| :----------- | :---- | :------------------------------------ |
| initialScope | Scope | The scope to start finding.           |
| node         | Node  | The node to find the innermost scope. |

### Return value

The innermost scope which contains the given node.
If such scope doesn't exist then it returns the 1st argument `initialScope`.

### Example

```js{9}
const { getInnermostScope } = require("eslint-utils")

module.exports = {
    meta: {},
    create(context) {
        return {
            "Program"(node) {
                const globalScope = context.getScope()
                const maybeNodejsScope = getInnermostScope(globalScope, node)
            },
        }
    },
}
```

## ReferenceTracker class

```js
const tracker = new utils.ReferenceTracker(globalScope, options);
```

The tracker for references.
This provides reference tracking for global variables, CommonJS modules, and ES modules.

### Parameters

| Name                      | Type                     | Description                                                                                                                                                                                                                                                                                                   |
| :------------------------ | :----------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| globalScope               | Scope                    | The global scope.                                                                                                                                                                                                                                                                                             |
| options.mode              | `"strict"` or `"legacy"` | The mode which determines how the `tracker.iterateEsmReferences()` method scans CommonJS modules. If this is `"strict"`, the method binds CommonJS modules to the default export. Otherwise, the method binds CommonJS modules to both the default export and named exports. Optional. Default is `"strict"`. |
| options.globalObjectNames | string[]                 | The name list of Global Object. Optional. Default is `["global", "globalThis", "self", "window"]`.                                                                                                                                                                                                            |

## tracker.iterateGlobalReferences

```js
const it = tracker.iterateGlobalReferences(traceMap);
```

Iterate the references that the given `traceMap` determined.
This method starts to search from global variables.

### Parameters

| Name     | Type   | Description                                                              |
| :------- | :----- | :----------------------------------------------------------------------- |
| traceMap | object | The object which determines global variables and properties it iterates. |

### Return value

The Iterator which iterates the reference of global variables.
Every reference is the object that has the following properties.

| Name  | Type     | Description                                                                                                                                                                                                                                                                              |
| :---- | :------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| node  | Node     | The node of the reference.                                                                                                                                                                                                                                                               |
| path  | string[] | The path of the reference. For example, if it's the access of `console.log` then `["console", "log"]`.                                                                                                                                                                                   |
| type  | symbol   | The reference type. If this is `ReferenceTracker.READ` then it read the variable (or property). If this is `ReferenceTracker.CALL` then it called the variable (or property). If this is `ReferenceTracker.CONSTRUCT` then it called the variable (or property) with the `new` operator. |
| entry | any      | The property value of any of `ReferenceTracker.READ`, `ReferenceTracker.CALL`, and `ReferenceTracker.CONSTRUCT`.                                                                                                                                                                         |

### Examples

```js
const { ReferenceTracker } = require("eslint-utils");

module.exports = {
  meta: {},
  create(context) {
    return {
      "Program:exit"() {
        const tracker = new ReferenceTracker(context.getScope());
        const traceMap = {
          // Find `console.log`, `console.info`, `console.warn`, and `console.error`.
          console: {
            log: { [ReferenceTracker.READ]: true },
            info: { [ReferenceTracker.READ]: true },
            warn: { [ReferenceTracker.READ]: true },
            error: { [ReferenceTracker.READ]: true },
          },
          // Find `Buffer()` and `new Buffer()`.
          Buffer: {
            [ReferenceTracker.CALL]: true,
            [ReferenceTracker.CONSTRUCT]: true,
          },
        };

        for (const { node, path } of tracker.iterateGlobalReferences(
          traceMap
        )) {
          context.report({
            node,
            message: "disallow {{name}}.",
            data: { name: path.join(".") },
          });
        }
      },
    };
  },
};
```

## tracker.iterateCjsReferences

```js
const it = tracker.iterateCjsReferences(traceMap);
```

Iterate the references that the given `traceMap` determined.
This method starts to search from `require()` expression.

### Parameters

| Name     | Type   | Description                                      |
| :------- | :----- | :----------------------------------------------- |
| traceMap | object | The object which determines modules it iterates. |

### Return value

The Iterator which iterates the reference of modules.
Every reference is the object that has the following properties.

| Name  | Type     | Description                                                                                                                                                                                                                                                                              |
| :---- | :------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| node  | Node     | The node of the reference.                                                                                                                                                                                                                                                               |
| path  | string[] | The path of the reference. For example, if it's the access of `fs.exists` then `["fs", "exists"]`.                                                                                                                                                                                       |
| type  | symbol   | The reference type. If this is `ReferenceTracker.READ` then it read the variable (or property). If this is `ReferenceTracker.CALL` then it called the variable (or property). If this is `ReferenceTracker.CONSTRUCT` then it called the variable (or property) with the `new` operator. |
| entry | any      | The property value of any of `ReferenceTracker.READ`, `ReferenceTracker.CALL`, and `ReferenceTracker.CONSTRUCT`.                                                                                                                                                                         |

### Examples

```js
const { ReferenceTracker } = require("eslint-utils");

module.exports = {
  meta: {},
  create(context) {
    return {
      "Program:exit"() {
        const tracker = new ReferenceTracker(context.getScope());
        const traceMap = {
          // Find `Buffer()` and `new Buffer()` of `buffer` module.
          buffer: {
            Buffer: {
              [ReferenceTracker.CALL]: true,
              [ReferenceTracker.CONSTRUCT]: true,
            },
          },
          // Find `exists` of `fs` module.
          fs: {
            exists: {
              [ReferenceTracker.READ]: true,
            },
          },
        };

        for (const { node, path } of tracker.iterateCjsReferences(traceMap)) {
          context.report({
            node,
            message: "disallow {{name}}.",
            data: { name: path.join(".") },
          });
        }
      },
    };
  },
};
```

## tracker.iterateEsmReferences

```js
const it = tracker.iterateEsmReferences(traceMap);
```

Iterate the references that the given `traceMap` determined.
This method starts to search from `import`/`export` declarations.

### Parameters

| Name     | Type   | Description                                      |
| :------- | :----- | :----------------------------------------------- |
| traceMap | object | The object which determines modules it iterates. |

### Return value

The Iterator which iterates the reference of modules.
Every reference is the object that has the following properties.

| Name  | Type     | Description                                                                                                                                                                                                                                                                              |
| :---- | :------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| node  | Node     | The node of the reference.                                                                                                                                                                                                                                                               |
| path  | string[] | The path of the reference. For example, if it's the access of `fs.exists` then `["fs", "exists"]`.                                                                                                                                                                                       |
| type  | symbol   | The reference type. If this is `ReferenceTracker.READ` then it read the variable (or property). If this is `ReferenceTracker.CALL` then it called the variable (or property). If this is `ReferenceTracker.CONSTRUCT` then it called the variable (or property) with the `new` operator. |
| entry | any      | The property value of any of `ReferenceTracker.READ`, `ReferenceTracker.CALL`, and `ReferenceTracker.CONSTRUCT`.                                                                                                                                                                         |

### Examples

```js
const { ReferenceTracker } = require("eslint-utils");

module.exports = {
  meta: {},
  create(context) {
    return {
      "Program:exit"() {
        const tracker = new ReferenceTracker(context.getScope());
        const traceMap = {
          // Find `Buffer()` and `new Buffer()` of `buffer` module.
          buffer: {
            Buffer: {
              [ReferenceTracker.CALL]: true,
              [ReferenceTracker.CONSTRUCT]: true,
            },
          },
          // Find `exists` of `fs` module.
          fs: {
            exists: {
              [ReferenceTracker.READ]: true,
            },
          },
        };

        for (const { node, path } of tracker.iterateEsmReferences(traceMap)) {
          context.report({
            node,
            message: "disallow {{name}}.",
            data: { name: path.join(".") },
          });
        }
      },
    };
  },
};
```
