code:
## 8.3.3 (2024-01-11)

### Bug fixes

Make acorn a dependency because acorn-walk uses the types from that package.

## 8.3.2 (2024-01-11)

### Bug fixes

Add missing type for `findNodeBefore`.

## 8.3.1 (2023-12-06)

### Bug fixes

Add `Function` and `Class` to the `AggregateType` type, so that they can be used in walkers without raising a type error.

Visitor functions are now called in such a way that their `this` refers to the object they are part of.

## 8.3.0 (2023-10-26)

### New features

Use a set of new, much more precise, TypeScript types.

## 8.2.0 (2021-09-06)

### New features

Add support for walking ES2022 class static blocks.

## 8.1.1 (2021-06-29)

### Bug fixes

Include `base` in the type declarations.

## 8.1.0 (2021-04-24)

### New features

Support node types for class fields and private methods.

## 8.0.2 (2021-01-25)

### Bug fixes

Adjust package.json to work with Node 12.16.0 and 13.0-13.6.

## 8.0.0 (2021-01-05)

### Bug fixes

Fix a bug where `full` and `fullAncestor` would skip nodes with overridden types.

## 8.0.0 (2020-08-12)

### New features

The package can now be loaded directly as an ECMAScript module in node 13+.

## 7.2.0 (2020-06-17)

### New features

Support optional chaining and nullish coalescing.

Support `import.meta`.

Add support for `export * as ns from "source"`.

## 7.1.1 (2020-02-13)

### Bug fixes

Clean up the type definitions to actually work well with the main parser.

## 7.1.0 (2020-02-11)

### New features

Add a TypeScript definition file for the library.

## 7.0.0 (2017-08-12)

### New features

Support walking `ImportExpression` nodes.

## 6.2.0 (2017-07-04)

### New features

Add support for `Import` nodes.

## 6.1.0 (2018-09-28)

### New features

The walker now walks `TemplateElement` nodes.

## 6.0.1 (2018-09-14)

### Bug fixes

Fix bad "main" field in package.json.

## 6.0.0 (2018-09-14)

### Breaking changes

This is now a separate package, `acorn-walk`, rather than part of the main `acorn` package.

The `ScopeBody` and `ScopeExpression` meta-node-types are no longer supported.

## 5.7.1 (2018-06-15)

### Bug fixes

Make sure the walker and bin files are rebuilt on release (the previous release didn't get the up-to-date versions).

## 5.7.0 (2018-06-15)

### Bug fixes

Fix crash in walker when walking a binding-less catch node.

## 5.6.2 (2018-06-05)

### Bug fixes

In the walker, go back to allowing the `baseVisitor` argument to be null to default to the default base everywhere.

## 5.6.1 (2018-06-01)

### Bug fixes

Fix regression when passing `null` as fourth argument to `walk.recursive`.

## 5.6.0 (2018-05-31)

### Bug fixes

Fix a bug in the walker that caused a crash when walking an object pattern spread.

## 5.5.1 (2018-03-06)

### Bug fixes

Fix regression in walker causing property values in object patterns to be walked as expressions.

## 5.5.0 (2018-02-27)

### Bug fixes

Support object spread in the AST walker.

## 5.4.1 (2018-02-02)

### Bug fixes

5.4.0 somehow accidentally included an old version of walk.js.

## 5.2.0 (2017-10-30)

### Bug fixes

The `full` and `fullAncestor` walkers no longer visit nodes multiple times.

## 5.1.0 (2017-07-05)

### New features

New walker functions `full` and `fullAncestor`.

## 3.2.0 (2016-06-07)

### New features

Make it possible to use `visit.ancestor` with a walk state.

## 3.1.0 (2016-04-18)

### New features

The walker now allows defining handlers for `CatchClause` nodes.

## 2.5.2 (2015-10-27)

### Fixes

Fix bug where the walker walked an exported `let` statement as an expression.


code:
# Acorn AST walker

An abstract syntax tree walker for the
[ESTree](https://github.com/estree/estree) format.

## Community

Acorn is open source software released under an
[MIT license](https://github.com/acornjs/acorn/blob/master/acorn-walk/LICENSE).

You are welcome to
[report bugs](https://github.com/acornjs/acorn/issues) or create pull
requests on [github](https://github.com/acornjs/acorn).

## Installation

The easiest way to install acorn is from [`npm`](https://www.npmjs.com/):

```sh
npm install acorn-walk
```

Alternately, you can download the source and build acorn yourself:

```sh
git clone https://github.com/acornjs/acorn.git
cd acorn
npm install
```

## Interface

An algorithm for recursing through a syntax tree is stored as an
object, with a property for each tree node type holding a function
that will recurse through such a node. There are several ways to run
such a walker.

**simple**`(node, visitors, base, state)` does a 'simple' walk over a
tree. `node` should be the AST node to walk, and `visitors` an object
with properties whose names correspond to node types in the [ESTree
spec](https://github.com/estree/estree). The properties should contain
functions that will be called with the node object and, if applicable
the state at that point. The last two arguments are optional. `base`
is a walker algorithm, and `state` is a start state. The default
walker will simply visit all statements and expressions and not
produce a meaningful state. (An example of a use of state is to track
scope at each point in the tree.)

```js
const acorn = require("acorn")
const walk = require("acorn-walk")

walk.simple(acorn.parse("let x = 10"), {
  Literal(node) {
    console.log(`Found a literal: ${node.value}`)
  }
})
```

**ancestor**`(node, visitors, base, state)` does a 'simple' walk over
a tree, building up an array of ancestor nodes (including the current node)
and passing the array to the callbacks as a third parameter.

```js
const acorn = require("acorn")
const walk = require("acorn-walk")

walk.ancestor(acorn.parse("foo('hi')"), {
  Literal(_node, _state, ancestors) {
    console.log("This literal's ancestors are:", ancestors.map(n => n.type))
  }
})
```

**recursive**`(node, state, functions, base)` does a 'recursive'
walk, where the walker functions are responsible for continuing the
walk on the child nodes of their target node. `state` is the start
state, and `functions` should contain an object that maps node types
to walker functions. Such functions are called with `(node, state, c)`
arguments, and can cause the walk to continue on a sub-node by calling
the `c` argument on it with `(node, state)` arguments. The optional
`base` argument provides the fallback walker functions for node types
that aren't handled in the `functions` object. If not given, the
default walkers will be used.

**make**`(functions, base)` builds a new walker object by using the
walker functions in `functions` and filling in the missing ones by
taking defaults from `base`.

**full**`(node, callback, base, state)` does a 'full' walk over a
tree, calling the callback with the arguments (node, state, type) for
each node

**fullAncestor**`(node, callback, base, state)` does a 'full' walk
over a tree, building up an array of ancestor nodes (including the
current node) and passing the array to the callbacks as a third
parameter.

```js
const acorn = require("acorn")
const walk = require("acorn-walk")

walk.full(acorn.parse("1 + 1"), node => {
  console.log(`There's a ${node.type} node at ${node.ch}`)
})
```

**findNodeAt**`(node, start, end, test, base, state)` tries to locate
a node in a tree at the given start and/or end offsets, which
satisfies the predicate `test`. `start` and `end` can be either `null`
(as wildcard) or a number. `test` may be a string (indicating a node
type) or a function that takes `(nodeType, node)` arguments and
returns a boolean indicating whether this node is interesting. `base`
and `state` are optional, and can be used to specify a custom walker.
Nodes are tested from inner to outer, so if two nodes match the
boundaries, the inner one will be preferred.

**findNodeAround**`(node, pos, test, base, state)` is a lot like
`findNodeAt`, but will match any node that exists 'around' (spanning)
the given position.

**findNodeAfter**`(node, pos, test, base, state)` is similar to
`findNodeAround`, but will match all nodes *after* the given position
(testing outer nodes before inner nodes).

license: mit


code:
import * as acorn from "acorn"

export type FullWalkerCallback<TState> = (
  node: acorn.Node,
  state: TState,
  type: string
) => void

export type FullAncestorWalkerCallback<TState> = (
  node: acorn.Node,
  state: TState,
  ancestors: acorn.Node[],
  type: string
) => void

type AggregateType = {
  Expression: acorn.Expression,
  Statement: acorn.Statement,
  Function: acorn.Function,
  Class: acorn.Class,
  Pattern: acorn.Pattern,
  ForInit: acorn.VariableDeclaration | acorn.Expression
}

export type SimpleVisitors<TState> = {
  [type in acorn.AnyNode["type"]]?: (node: Extract<acorn.AnyNode, { type: type }>, state: TState) => void
} & {
  [type in keyof AggregateType]?: (node: AggregateType[type], state: TState) => void
}

export type AncestorVisitors<TState> = {
  [type in acorn.AnyNode["type"]]?: ( node: Extract<acorn.AnyNode, { type: type }>, state: TState, ancestors: acorn.Node[]
) => void
} & {
  [type in keyof AggregateType]?: (node: AggregateType[type], state: TState, ancestors: acorn.Node[]) => void
}

export type WalkerCallback<TState> = (node: acorn.Node, state: TState) => void

export type RecursiveVisitors<TState> = {
  [type in acorn.AnyNode["type"]]?: ( node: Extract<acorn.AnyNode, { type: type }>, state: TState, callback: WalkerCallback<TState>) => void
} &  {
  [type in keyof AggregateType]?: (node: AggregateType[type], state: TState, callback: WalkerCallback<TState>) => void
}

export type FindPredicate = (type: string, node: acorn.Node) => boolean

export interface Found<TState> {
  node: acorn.Node,
  state: TState
}

/**
 * does a 'simple' walk over a tree
 * @param node the AST node to walk
 * @param visitors an object with properties whose names correspond to node types in the {@link https://github.com/estree/estree | ESTree spec}. The properties should contain functions that will be called with the node object and, if applicable the state at that point.
 * @param base a walker algorithm
 * @param state a start state. The default walker will simply visit all statements and expressions and not produce a meaningful state. (An example of a use of state is to track scope at each point in the tree.)
 */
export function simple<TState>(
  node: acorn.Node,
  visitors: SimpleVisitors<TState>,
  base?: RecursiveVisitors<TState>,
  state?: TState
): void

/**
 * does a 'simple' walk over a tree, building up an array of ancestor nodes (including the current node) and passing the array to the callbacks as a third parameter.
 * @param node
 * @param visitors
 * @param base
 * @param state
 */
export function ancestor<TState>(
    node: acorn.Node,
    visitors: AncestorVisitors<TState>,
    base?: RecursiveVisitors<TState>,
    state?: TState
  ): void

/**
 * does a 'recursive' walk, where the walker functions are responsible for continuing the walk on the child nodes of their target node.
 * @param node
 * @param state the start state
 * @param functions contain an object that maps node types to walker functions
 * @param base provides the fallback walker functions for node types that aren't handled in the {@link functions} object. If not given, the default walkers will be used.
 */
export function recursive<TState>(
  node: acorn.Node,
  state: TState,
  functions: RecursiveVisitors<TState>,
  base?: RecursiveVisitors<TState>
): void

/**
 * does a 'full' walk over a tree, calling the {@link callback} with the arguments (node, state, type) for each node
 * @param node
 * @param callback
 * @param base
 * @param state
 */
export function full<TState>(
  node: acorn.Node,
  callback: FullWalkerCallback<TState>,
  base?: RecursiveVisitors<TState>,
  state?: TState
): void

/**
 * does a 'full' walk over a tree, building up an array of ancestor nodes (including the current node) and passing the array to the callbacks as a third parameter.
 * @param node
 * @param callback
 * @param base
 * @param state
 */
export function fullAncestor<TState>(
  node: acorn.Node,
  callback: FullAncestorWalkerCallback<TState>,
  base?: RecursiveVisitors<TState>,
  state?: TState
): void

/**
 * builds a new walker object by using the walker functions in {@link functions} and filling in the missing ones by taking defaults from {@link base}.
 * @param functions
 * @param base
 */
export function make<TState>(
  functions: RecursiveVisitors<TState>,
  base?: RecursiveVisitors<TState>
): RecursiveVisitors<TState>

/**
 * tries to locate a node in a tree at the given start and/or end offsets, which satisfies the predicate test. {@link start} and {@link end} can be either `null` (as wildcard) or a `number`. {@link test} may be a string (indicating a node type) or a function that takes (nodeType, node) arguments and returns a boolean indicating whether this node is interesting. {@link base} and {@link state} are optional, and can be used to specify a custom walker. Nodes are tested from inner to outer, so if two nodes match the boundaries, the inner one will be preferred.
 * @param node
 * @param start
 * @param end
 * @param type
 * @param base
 * @param state
 */
export function findNodeAt<TState>(
  node: acorn.Node,
  start: number | undefined,
  end?: number | undefined,
  type?: FindPredicate | string,
  base?: RecursiveVisitors<TState>,
  state?: TState
): Found<TState> | undefined

/**
 * like {@link findNodeAt}, but will match any node that exists 'around' (spanning) the given position.
 * @param node
 * @param start
 * @param type
 * @param base
 * @param state
 */
export function findNodeAround<TState>(
  node: acorn.Node,
  start: number | undefined,
  type?: FindPredicate | string,
  base?: RecursiveVisitors<TState>,
  state?: TState
): Found<TState> | undefined

/**
 * Find the outermost matching node after a given position.
 */
export const findNodeAfter: typeof findNodeAround

/**
 * Find the outermost matching node before a given position.
 */
export const findNodeBefore: typeof findNodeAround

export const base: RecursiveVisitors<any>


code:
(function (global, factory) {
  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
  typeof define === 'function' && define.amd ? define(['exports'], factory) :
  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory((global.acorn = global.acorn || {}, global.acorn.walk = {})));
})(this, (function (exports) { 'use strict';

  // AST walker module for ESTree compatible trees

  // A simple walk is one where you simply specify callbacks to be
  // called on specific nodes. The last two arguments are optional. A
  // simple use would be
  //
  //     walk.simple(myTree, {
  //         Expression: function(node) { ... }
  //     });
  //
  // to do something with all expressions. All ESTree node types
  // can be used to identify node types, as well as Expression and
  // Statement, which denote categories of nodes.
  //
  // The base argument can be used to pass a custom (recursive)
  // walker, and state can be used to give this walked an initial
  // state.

  function simple(node, visitors, baseVisitor, state, override) {
    if (!baseVisitor) { baseVisitor = base
    ; }(function c(node, st, override) {
      var type = override || node.type;
      baseVisitor[type](node, st, c);
      if (visitors[type]) { visitors[type](node, st); }
    })(node, state, override);
  }

  // An ancestor walk keeps an array of ancestor nodes (including the
  // current node) and passes them to the callback as third parameter
  // (and also as state parameter when no other state is present).
  function ancestor(node, visitors, baseVisitor, state, override) {
    var ancestors = [];
    if (!baseVisitor) { baseVisitor = base
    ; }(function c(node, st, override) {
      var type = override || node.type;
      var isNew = node !== ancestors[ancestors.length - 1];
      if (isNew) { ancestors.push(node); }
      baseVisitor[type](node, st, c);
      if (visitors[type]) { visitors[type](node, st || ancestors, ancestors); }
      if (isNew) { ancestors.pop(); }
    })(node, state, override);
  }

  // A recursive walk is one where your functions override the default
  // walkers. They can modify and replace the state parameter that's
  // threaded through the walk, and can opt how and whether to walk
  // their child nodes (by calling their third argument on these
  // nodes).
  function recursive(node, state, funcs, baseVisitor, override) {
    var visitor = funcs ? make(funcs, baseVisitor || undefined) : baseVisitor
    ;(function c(node, st, override) {
      visitor[override || node.type](node, st, c);
    })(node, state, override);
  }

  function makeTest(test) {
    if (typeof test === "string")
      { return function (type) { return type === test; } }
    else if (!test)
      { return function () { return true; } }
    else
      { return test }
  }

  var Found = function Found(node, state) { this.node = node; this.state = state; };

  // A full walk triggers the callback on each node
  function full(node, callback, baseVisitor, state, override) {
    if (!baseVisitor) { baseVisitor = base; }
    var last
    ;(function c(node, st, override) {
      var type = override || node.type;
      baseVisitor[type](node, st, c);
      if (last !== node) {
        callback(node, st, type);
        last = node;
      }
    })(node, state, override);
  }

  // An fullAncestor walk is like an ancestor walk, but triggers
  // the callback on each node
  function fullAncestor(node, callback, baseVisitor, state) {
    if (!baseVisitor) { baseVisitor = base; }
    var ancestors = [], last
    ;(function c(node, st, override) {
      var type = override || node.type;
      var isNew = node !== ancestors[ancestors.length - 1];
      if (isNew) { ancestors.push(node); }
      baseVisitor[type](node, st, c);
      if (last !== node) {
        callback(node, st || ancestors, ancestors, type);
        last = node;
      }
      if (isNew) { ancestors.pop(); }
    })(node, state);
  }

  // Find a node with a given start, end, and type (all are optional,
  // null can be used as wildcard). Returns a {node, state} object, or
  // undefined when it doesn't find a matching node.
  function findNodeAt(node, start, end, test, baseVisitor, state) {
    if (!baseVisitor) { baseVisitor = base; }
    test = makeTest(test);
    try {
      (function c(node, st, override) {
        var type = override || node.type;
        if ((start == null || node.start <= start) &&
            (end == null || node.end >= end))
          { baseVisitor[type](node, st, c); }
        if ((start == null || node.start === start) &&
            (end == null || node.end === end) &&
            test(type, node))
          { throw new Found(node, st) }
      })(node, state);
    } catch (e) {
      if (e instanceof Found) { return e }
      throw e
    }
  }

  // Find the innermost node of a given type that contains the given
  // position. Interface similar to findNodeAt.
  function findNodeAround(node, pos, test, baseVisitor, state) {
    test = makeTest(test);
    if (!baseVisitor) { baseVisitor = base; }
    try {
      (function c(node, st, override) {
        var type = override || node.type;
        if (node.start > pos || node.end < pos) { return }
        baseVisitor[type](node, st, c);
        if (test(type, node)) { throw new Found(node, st) }
      })(node, state);
    } catch (e) {
      if (e instanceof Found) { return e }
      throw e
    }
  }

  // Find the outermost matching node after a given position.
  function findNodeAfter(node, pos, test, baseVisitor, state) {
    test = makeTest(test);
    if (!baseVisitor) { baseVisitor = base; }
    try {
      (function c(node, st, override) {
        if (node.end < pos) { return }
        var type = override || node.type;
        if (node.start >= pos && test(type, node)) { throw new Found(node, st) }
        baseVisitor[type](node, st, c);
      })(node, state);
    } catch (e) {
      if (e instanceof Found) { return e }
      throw e
    }
  }

  // Find the outermost matching node before a given position.
  function findNodeBefore(node, pos, test, baseVisitor, state) {
    test = makeTest(test);
    if (!baseVisitor) { baseVisitor = base; }
    var max
    ;(function c(node, st, override) {
      if (node.start > pos) { return }
      var type = override || node.type;
      if (node.end <= pos && (!max || max.node.end < node.end) && test(type, node))
        { max = new Found(node, st); }
      baseVisitor[type](node, st, c);
    })(node, state);
    return max
  }

  // Used to create a custom walker. Will fill in all missing node
  // type properties with the defaults.
  function make(funcs, baseVisitor) {
    var visitor = Object.create(baseVisitor || base);
    for (var type in funcs) { visitor[type] = funcs[type]; }
    return visitor
  }

  function skipThrough(node, st, c) { c(node, st); }
  function ignore(_node, _st, _c) {}

  // Node walkers.

  var base = {};

  base.Program = base.BlockStatement = base.StaticBlock = function (node, st, c) {
    for (var i = 0, list = node.body; i < list.length; i += 1)
      {
      var stmt = list[i];

      c(stmt, st, "Statement");
    }
  };
  base.Statement = skipThrough;
  base.EmptyStatement = ignore;
  base.ExpressionStatement = base.ParenthesizedExpression = base.ChainExpression =
    function (node, st, c) { return c(node.expression, st, "Expression"); };
  base.IfStatement = function (node, st, c) {
    c(node.test, st, "Expression");
    c(node.consequent, st, "Statement");
    if (node.alternate) { c(node.alternate, st, "Statement"); }
  };
  base.LabeledStatement = function (node, st, c) { return c(node.body, st, "Statement"); };
  base.BreakStatement = base.ContinueStatement = ignore;
  base.WithStatement = function (node, st, c) {
    c(node.object, st, "Expression");
    c(node.body, st, "Statement");
  };
  base.SwitchStatement = function (node, st, c) {
    c(node.discriminant, st, "Expression");
    for (var i$1 = 0, list$1 = node.cases; i$1 < list$1.length; i$1 += 1) {
      var cs = list$1[i$1];

      if (cs.test) { c(cs.test, st, "Expression"); }
      for (var i = 0, list = cs.consequent; i < list.length; i += 1)
        {
        var cons = list[i];

        c(cons, st, "Statement");
      }
    }
  };
  base.SwitchCase = function (node, st, c) {
    if (node.test) { c(node.test, st, "Expression"); }
    for (var i = 0, list = node.consequent; i < list.length; i += 1)
      {
      var cons = list[i];

      c(cons, st, "Statement");
    }
  };
  base.ReturnStatement = base.YieldExpression = base.AwaitExpression = function (node, st, c) {
    if (node.argument) { c(node.argument, st, "Expression"); }
  };
  base.ThrowStatement = base.SpreadElement =
    function (node, st, c) { return c(node.argument, st, "Expression"); };
  base.TryStatement = function (node, st, c) {
    c(node.block, st, "Statement");
    if (node.handler) { c(node.handler, st); }
    if (node.finalizer) { c(node.finalizer, st, "Statement"); }
  };
  base.CatchClause = function (node, st, c) {
    if (node.param) { c(node.param, st, "Pattern"); }
    c(node.body, st, "Statement");
  };
  base.WhileStatement = base.DoWhileStatement = function (node, st, c) {
    c(node.test, st, "Expression");
    c(node.body, st, "Statement");
  };
  base.ForStatement = function (node, st, c) {
    if (node.init) { c(node.init, st, "ForInit"); }
    if (node.test) { c(node.test, st, "Expression"); }
    if (node.update) { c(node.update, st, "Expression"); }
    c(node.body, st, "Statement");
  };
  base.ForInStatement = base.ForOfStatement = function (node, st, c) {
    c(node.left, st, "ForInit");
    c(node.right, st, "Expression");
    c(node.body, st, "Statement");
  };
  base.ForInit = function (node, st, c) {
    if (node.type === "VariableDeclaration") { c(node, st); }
    else { c(node, st, "Expression"); }
  };
  base.DebuggerStatement = ignore;

  base.FunctionDeclaration = function (node, st, c) { return c(node, st, "Function"); };
  base.VariableDeclaration = function (node, st, c) {
    for (var i = 0, list = node.declarations; i < list.length; i += 1)
      {
      var decl = list[i];

      c(decl, st);
    }
  };
  base.VariableDeclarator = function (node, st, c) {
    c(node.id, st, "Pattern");
    if (node.init) { c(node.init, st, "Expression"); }
  };

  base.Function = function (node, st, c) {
    if (node.id) { c(node.id, st, "Pattern"); }
    for (var i = 0, list = node.params; i < list.length; i += 1)
      {
      var param = list[i];

      c(param, st, "Pattern");
    }
    c(node.body, st, node.expression ? "Expression" : "Statement");
  };

  base.Pattern = function (node, st, c) {
    if (node.type === "Identifier")
      { c(node, st, "VariablePattern"); }
    else if (node.type === "MemberExpression")
      { c(node, st, "MemberPattern"); }
    else
      { c(node, st); }
  };
  base.VariablePattern = ignore;
  base.MemberPattern = skipThrough;
  base.RestElement = function (node, st, c) { return c(node.argument, st, "Pattern"); };
  base.ArrayPattern = function (node, st, c) {
    for (var i = 0, list = node.elements; i < list.length; i += 1) {
      var elt = list[i];

      if (elt) { c(elt, st, "Pattern"); }
    }
  };
  base.ObjectPattern = function (node, st, c) {
    for (var i = 0, list = node.properties; i < list.length; i += 1) {
      var prop = list[i];

      if (prop.type === "Property") {
        if (prop.computed) { c(prop.key, st, "Expression"); }
        c(prop.value, st, "Pattern");
      } else if (prop.type === "RestElement") {
        c(prop.argument, st, "Pattern");
      }
    }
  };

  base.Expression = skipThrough;
  base.ThisExpression = base.Super = base.MetaProperty = ignore;
  base.ArrayExpression = function (node, st, c) {
    for (var i = 0, list = node.elements; i < list.length; i += 1) {
      var elt = list[i];

      if (elt) { c(elt, st, "Expression"); }
    }
  };
  base.ObjectExpression = function (node, st, c) {
    for (var i = 0, list = node.properties; i < list.length; i += 1)
      {
      var prop = list[i];

      c(prop, st);
    }
  };
  base.FunctionExpression = base.ArrowFunctionExpression = base.FunctionDeclaration;
  base.SequenceExpression = function (node, st, c) {
    for (var i = 0, list = node.expressions; i < list.length; i += 1)
      {
      var expr = list[i];

      c(expr, st, "Expression");
    }
  };
  base.TemplateLiteral = function (node, st, c) {
    for (var i = 0, list = node.quasis; i < list.length; i += 1)
      {
      var quasi = list[i];

      c(quasi, st);
    }

    for (var i$1 = 0, list$1 = node.expressions; i$1 < list$1.length; i$1 += 1)
      {
      var expr = list$1[i$1];

      c(expr, st, "Expression");
    }
  };
  base.TemplateElement = ignore;
  base.UnaryExpression = base.UpdateExpression = function (node, st, c) {
    c(node.argument, st, "Expression");
  };
  base.BinaryExpression = base.LogicalExpression = function (node, st, c) {
    c(node.left, st, "Expression");
    c(node.right, st, "Expression");
  };
  base.AssignmentExpression = base.AssignmentPattern = function (node, st, c) {
    c(node.left, st, "Pattern");
    c(node.right, st, "Expression");
  };
  base.ConditionalExpression = function (node, st, c) {
    c(node.test, st, "Expression");
    c(node.consequent, st, "Expression");
    c(node.alternate, st, "Expression");
  };
  base.NewExpression = base.CallExpression = function (node, st, c) {
    c(node.callee, st, "Expression");
    if (node.arguments)
      { for (var i = 0, list = node.arguments; i < list.length; i += 1)
        {
          var arg = list[i];

          c(arg, st, "Expression");
        } }
  };
  base.MemberExpression = function (node, st, c) {
    c(node.object, st, "Expression");
    if (node.computed) { c(node.property, st, "Expression"); }
  };
  base.ExportNamedDeclaration = base.ExportDefaultDeclaration = function (node, st, c) {
    if (node.declaration)
      { c(node.declaration, st, node.type === "ExportNamedDeclaration" || node.declaration.id ? "Statement" : "Expression"); }
    if (node.source) { c(node.source, st, "Expression"); }
  };
  base.ExportAllDeclaration = function (node, st, c) {
    if (node.exported)
      { c(node.exported, st); }
    c(node.source, st, "Expression");
  };
  base.ImportDeclaration = function (node, st, c) {
    for (var i = 0, list = node.specifiers; i < list.length; i += 1)
      {
      var spec = list[i];

      c(spec, st);
    }
    c(node.source, st, "Expression");
  };
  base.ImportExpression = function (node, st, c) {
    c(node.source, st, "Expression");
  };
  base.ImportSpecifier = base.ImportDefaultSpecifier = base.ImportNamespaceSpecifier = base.Identifier = base.PrivateIdentifier = base.Literal = ignore;

  base.TaggedTemplateExpression = function (node, st, c) {
    c(node.tag, st, "Expression");
    c(node.quasi, st, "Expression");
  };
  base.ClassDeclaration = base.ClassExpression = function (node, st, c) { return c(node, st, "Class"); };
  base.Class = function (node, st, c) {
    if (node.id) { c(node.id, st, "Pattern"); }
    if (node.superClass) { c(node.superClass, st, "Expression"); }
    c(node.body, st);
  };
  base.ClassBody = function (node, st, c) {
    for (var i = 0, list = node.body; i < list.length; i += 1)
      {
      var elt = list[i];

      c(elt, st);
    }
  };
  base.MethodDefinition = base.PropertyDefinition = base.Property = function (node, st, c) {
    if (node.computed) { c(node.key, st, "Expression"); }
    if (node.value) { c(node.value, st, "Expression"); }
  };

  exports.ancestor = ancestor;
  exports.base = base;
  exports.findNodeAfter = findNodeAfter;
  exports.findNodeAround = findNodeAround;
  exports.findNodeAt = findNodeAt;
  exports.findNodeBefore = findNodeBefore;
  exports.full = full;
  exports.fullAncestor = fullAncestor;
  exports.make = make;
  exports.recursive = recursive;
  exports.simple = simple;

}));


code:
// AST walker module for ESTree compatible trees

// A simple walk is one where you simply specify callbacks to be
// called on specific nodes. The last two arguments are optional. A
// simple use would be
//
//     walk.simple(myTree, {
//         Expression: function(node) { ... }
//     });
//
// to do something with all expressions. All ESTree node types
// can be used to identify node types, as well as Expression and
// Statement, which denote categories of nodes.
//
// The base argument can be used to pass a custom (recursive)
// walker, and state can be used to give this walked an initial
// state.

function simple(node, visitors, baseVisitor, state, override) {
  if (!baseVisitor) { baseVisitor = base
  ; }(function c(node, st, override) {
    var type = override || node.type;
    baseVisitor[type](node, st, c);
    if (visitors[type]) { visitors[type](node, st); }
  })(node, state, override);
}

// An ancestor walk keeps an array of ancestor nodes (including the
// current node) and passes them to the callback as third parameter
// (and also as state parameter when no other state is present).
function ancestor(node, visitors, baseVisitor, state, override) {
  var ancestors = [];
  if (!baseVisitor) { baseVisitor = base
  ; }(function c(node, st, override) {
    var type = override || node.type;
    var isNew = node !== ancestors[ancestors.length - 1];
    if (isNew) { ancestors.push(node); }
    baseVisitor[type](node, st, c);
    if (visitors[type]) { visitors[type](node, st || ancestors, ancestors); }
    if (isNew) { ancestors.pop(); }
  })(node, state, override);
}

// A recursive walk is one where your functions override the default
// walkers. They can modify and replace the state parameter that's
// threaded through the walk, and can opt how and whether to walk
// their child nodes (by calling their third argument on these
// nodes).
function recursive(node, state, funcs, baseVisitor, override) {
  var visitor = funcs ? make(funcs, baseVisitor || undefined) : baseVisitor
  ;(function c(node, st, override) {
    visitor[override || node.type](node, st, c);
  })(node, state, override);
}

function makeTest(test) {
  if (typeof test === "string")
    { return function (type) { return type === test; } }
  else if (!test)
    { return function () { return true; } }
  else
    { return test }
}

var Found = function Found(node, state) { this.node = node; this.state = state; };

// A full walk triggers the callback on each node
function full(node, callback, baseVisitor, state, override) {
  if (!baseVisitor) { baseVisitor = base; }
  var last
  ;(function c(node, st, override) {
    var type = override || node.type;
    baseVisitor[type](node, st, c);
    if (last !== node) {
      callback(node, st, type);
      last = node;
    }
  })(node, state, override);
}

// An fullAncestor walk is like an ancestor walk, but triggers
// the callback on each node
function fullAncestor(node, callback, baseVisitor, state) {
  if (!baseVisitor) { baseVisitor = base; }
  var ancestors = [], last
  ;(function c(node, st, override) {
    var type = override || node.type;
    var isNew = node !== ancestors[ancestors.length - 1];
    if (isNew) { ancestors.push(node); }
    baseVisitor[type](node, st, c);
    if (last !== node) {
      callback(node, st || ancestors, ancestors, type);
      last = node;
    }
    if (isNew) { ancestors.pop(); }
  })(node, state);
}

// Find a node with a given start, end, and type (all are optional,
// null can be used as wildcard). Returns a {node, state} object, or
// undefined when it doesn't find a matching node.
function findNodeAt(node, start, end, test, baseVisitor, state) {
  if (!baseVisitor) { baseVisitor = base; }
  test = makeTest(test);
  try {
    (function c(node, st, override) {
      var type = override || node.type;
      if ((start == null || node.start <= start) &&
          (end == null || node.end >= end))
        { baseVisitor[type](node, st, c); }
      if ((start == null || node.start === start) &&
          (end == null || node.end === end) &&
          test(type, node))
        { throw new Found(node, st) }
    })(node, state);
  } catch (e) {
    if (e instanceof Found) { return e }
    throw e
  }
}

// Find the innermost node of a given type that contains the given
// position. Interface similar to findNodeAt.
function findNodeAround(node, pos, test, baseVisitor, state) {
  test = makeTest(test);
  if (!baseVisitor) { baseVisitor = base; }
  try {
    (function c(node, st, override) {
      var type = override || node.type;
      if (node.start > pos || node.end < pos) { return }
      baseVisitor[type](node, st, c);
      if (test(type, node)) { throw new Found(node, st) }
    })(node, state);
  } catch (e) {
    if (e instanceof Found) { return e }
    throw e
  }
}

// Find the outermost matching node after a given position.
function findNodeAfter(node, pos, test, baseVisitor, state) {
  test = makeTest(test);
  if (!baseVisitor) { baseVisitor = base; }
  try {
    (function c(node, st, override) {
      if (node.end < pos) { return }
      var type = override || node.type;
      if (node.start >= pos && test(type, node)) { throw new Found(node, st) }
      baseVisitor[type](node, st, c);
    })(node, state);
  } catch (e) {
    if (e instanceof Found) { return e }
    throw e
  }
}

// Find the outermost matching node before a given position.
function findNodeBefore(node, pos, test, baseVisitor, state) {
  test = makeTest(test);
  if (!baseVisitor) { baseVisitor = base; }
  var max
  ;(function c(node, st, override) {
    if (node.start > pos) { return }
    var type = override || node.type;
    if (node.end <= pos && (!max || max.node.end < node.end) && test(type, node))
      { max = new Found(node, st); }
    baseVisitor[type](node, st, c);
  })(node, state);
  return max
}

// Used to create a custom walker. Will fill in all missing node
// type properties with the defaults.
function make(funcs, baseVisitor) {
  var visitor = Object.create(baseVisitor || base);
  for (var type in funcs) { visitor[type] = funcs[type]; }
  return visitor
}

function skipThrough(node, st, c) { c(node, st); }
function ignore(_node, _st, _c) {}

// Node walkers.

var base = {};

base.Program = base.BlockStatement = base.StaticBlock = function (node, st, c) {
  for (var i = 0, list = node.body; i < list.length; i += 1)
    {
    var stmt = list[i];

    c(stmt, st, "Statement");
  }
};
base.Statement = skipThrough;
base.EmptyStatement = ignore;
base.ExpressionStatement = base.ParenthesizedExpression = base.ChainExpression =
  function (node, st, c) { return c(node.expression, st, "Expression"); };
base.IfStatement = function (node, st, c) {
  c(node.test, st, "Expression");
  c(node.consequent, st, "Statement");
  if (node.alternate) { c(node.alternate, st, "Statement"); }
};
base.LabeledStatement = function (node, st, c) { return c(node.body, st, "Statement"); };
base.BreakStatement = base.ContinueStatement = ignore;
base.WithStatement = function (node, st, c) {
  c(node.object, st, "Expression");
  c(node.body, st, "Statement");
};
base.SwitchStatement = function (node, st, c) {
  c(node.discriminant, st, "Expression");
  for (var i$1 = 0, list$1 = node.cases; i$1 < list$1.length; i$1 += 1) {
    var cs = list$1[i$1];

    if (cs.test) { c(cs.test, st, "Expression"); }
    for (var i = 0, list = cs.consequent; i < list.length; i += 1)
      {
      var cons = list[i];

      c(cons, st, "Statement");
    }
  }
};
base.SwitchCase = function (node, st, c) {
  if (node.test) { c(node.test, st, "Expression"); }
  for (var i = 0, list = node.consequent; i < list.length; i += 1)
    {
    var cons = list[i];

    c(cons, st, "Statement");
  }
};
base.ReturnStatement = base.YieldExpression = base.AwaitExpression = function (node, st, c) {
  if (node.argument) { c(node.argument, st, "Expression"); }
};
base.ThrowStatement = base.SpreadElement =
  function (node, st, c) { return c(node.argument, st, "Expression"); };
base.TryStatement = function (node, st, c) {
  c(node.block, st, "Statement");
  if (node.handler) { c(node.handler, st); }
  if (node.finalizer) { c(node.finalizer, st, "Statement"); }
};
base.CatchClause = function (node, st, c) {
  if (node.param) { c(node.param, st, "Pattern"); }
  c(node.body, st, "Statement");
};
base.WhileStatement = base.DoWhileStatement = function (node, st, c) {
  c(node.test, st, "Expression");
  c(node.body, st, "Statement");
};
base.ForStatement = function (node, st, c) {
  if (node.init) { c(node.init, st, "ForInit"); }
  if (node.test) { c(node.test, st, "Expression"); }
  if (node.update) { c(node.update, st, "Expression"); }
  c(node.body, st, "Statement");
};
base.ForInStatement = base.ForOfStatement = function (node, st, c) {
  c(node.left, st, "ForInit");
  c(node.right, st, "Expression");
  c(node.body, st, "Statement");
};
base.ForInit = function (node, st, c) {
  if (node.type === "VariableDeclaration") { c(node, st); }
  else { c(node, st, "Expression"); }
};
base.DebuggerStatement = ignore;

base.FunctionDeclaration = function (node, st, c) { return c(node, st, "Function"); };
base.VariableDeclaration = function (node, st, c) {
  for (var i = 0, list = node.declarations; i < list.length; i += 1)
    {
    var decl = list[i];

    c(decl, st);
  }
};
base.VariableDeclarator = function (node, st, c) {
  c(node.id, st, "Pattern");
  if (node.init) { c(node.init, st, "Expression"); }
};

base.Function = function (node, st, c) {
  if (node.id) { c(node.id, st, "Pattern"); }
  for (var i = 0, list = node.params; i < list.length; i += 1)
    {
    var param = list[i];

    c(param, st, "Pattern");
  }
  c(node.body, st, node.expression ? "Expression" : "Statement");
};

base.Pattern = function (node, st, c) {
  if (node.type === "Identifier")
    { c(node, st, "VariablePattern"); }
  else if (node.type === "MemberExpression")
    { c(node, st, "MemberPattern"); }
  else
    { c(node, st); }
};
base.VariablePattern = ignore;
base.MemberPattern = skipThrough;
base.RestElement = function (node, st, c) { return c(node.argument, st, "Pattern"); };
base.ArrayPattern = function (node, st, c) {
  for (var i = 0, list = node.elements; i < list.length; i += 1) {
    var elt = list[i];

    if (elt) { c(elt, st, "Pattern"); }
  }
};
base.ObjectPattern = function (node, st, c) {
  for (var i = 0, list = node.properties; i < list.length; i += 1) {
    var prop = list[i];

    if (prop.type === "Property") {
      if (prop.computed) { c(prop.key, st, "Expression"); }
      c(prop.value, st, "Pattern");
    } else if (prop.type === "RestElement") {
      c(prop.argument, st, "Pattern");
    }
  }
};

base.Expression = skipThrough;
base.ThisExpression = base.Super = base.MetaProperty = ignore;
base.ArrayExpression = function (node, st, c) {
  for (var i = 0, list = node.elements; i < list.length; i += 1) {
    var elt = list[i];

    if (elt) { c(elt, st, "Expression"); }
  }
};
base.ObjectExpression = function (node, st, c) {
  for (var i = 0, list = node.properties; i < list.length; i += 1)
    {
    var prop = list[i];

    c(prop, st);
  }
};
base.FunctionExpression = base.ArrowFunctionExpression = base.FunctionDeclaration;
base.SequenceExpression = function (node, st, c) {
  for (var i = 0, list = node.expressions; i < list.length; i += 1)
    {
    var expr = list[i];

    c(expr, st, "Expression");
  }
};
base.TemplateLiteral = function (node, st, c) {
  for (var i = 0, list = node.quasis; i < list.length; i += 1)
    {
    var quasi = list[i];

    c(quasi, st);
  }

  for (var i$1 = 0, list$1 = node.expressions; i$1 < list$1.length; i$1 += 1)
    {
    var expr = list$1[i$1];

    c(expr, st, "Expression");
  }
};
base.TemplateElement = ignore;
base.UnaryExpression = base.UpdateExpression = function (node, st, c) {
  c(node.argument, st, "Expression");
};
base.BinaryExpression = base.LogicalExpression = function (node, st, c) {
  c(node.left, st, "Expression");
  c(node.right, st, "Expression");
};
base.AssignmentExpression = base.AssignmentPattern = function (node, st, c) {
  c(node.left, st, "Pattern");
  c(node.right, st, "Expression");
};
base.ConditionalExpression = function (node, st, c) {
  c(node.test, st, "Expression");
  c(node.consequent, st, "Expression");
  c(node.alternate, st, "Expression");
};
base.NewExpression = base.CallExpression = function (node, st, c) {
  c(node.callee, st, "Expression");
  if (node.arguments)
    { for (var i = 0, list = node.arguments; i < list.length; i += 1)
      {
        var arg = list[i];

        c(arg, st, "Expression");
      } }
};
base.MemberExpression = function (node, st, c) {
  c(node.object, st, "Expression");
  if (node.computed) { c(node.property, st, "Expression"); }
};
base.ExportNamedDeclaration = base.ExportDefaultDeclaration = function (node, st, c) {
  if (node.declaration)
    { c(node.declaration, st, node.type === "ExportNamedDeclaration" || node.declaration.id ? "Statement" : "Expression"); }
  if (node.source) { c(node.source, st, "Expression"); }
};
base.ExportAllDeclaration = function (node, st, c) {
  if (node.exported)
    { c(node.exported, st); }
  c(node.source, st, "Expression");
};
base.ImportDeclaration = function (node, st, c) {
  for (var i = 0, list = node.specifiers; i < list.length; i += 1)
    {
    var spec = list[i];

    c(spec, st);
  }
  c(node.source, st, "Expression");
};
base.ImportExpression = function (node, st, c) {
  c(node.source, st, "Expression");
};
base.ImportSpecifier = base.ImportDefaultSpecifier = base.ImportNamespaceSpecifier = base.Identifier = base.PrivateIdentifier = base.Literal = ignore;

base.TaggedTemplateExpression = function (node, st, c) {
  c(node.tag, st, "Expression");
  c(node.quasi, st, "Expression");
};
base.ClassDeclaration = base.ClassExpression = function (node, st, c) { return c(node, st, "Class"); };
base.Class = function (node, st, c) {
  if (node.id) { c(node.id, st, "Pattern"); }
  if (node.superClass) { c(node.superClass, st, "Expression"); }
  c(node.body, st);
};
base.ClassBody = function (node, st, c) {
  for (var i = 0, list = node.body; i < list.length; i += 1)
    {
    var elt = list[i];

    c(elt, st);
  }
};
base.MethodDefinition = base.PropertyDefinition = base.Property = function (node, st, c) {
  if (node.computed) { c(node.key, st, "Expression"); }
  if (node.value) { c(node.value, st, "Expression"); }
};

export { ancestor, base, findNodeAfter, findNodeAround, findNodeAt, findNodeBefore, full, fullAncestor, make, recursive, simple };


acorn-walk

description: ECMAScript (ESTree) AST walker

type: git

prepare: cd ..; npm run build:walk

license: MIT


code:
## 8.12.1 (2024-07-03)

### Bug fixes

Fix a regression that caused Acorn to no longer run on Node versions <8.10.

## 8.12.0 (2024-06-14)

### New features

Support ES2025 duplicate capture group names in regular expressions.

### Bug fixes

Include `VariableDeclarator` in the `AnyNode` type so that walker objects can refer to it without getting a type error.

Properly raise a parse error for invalid `for`/`of` statements using `async` as binding name.

Properly recognize \"use strict\" when preceded by a string with an escaped newline.

Mark the `Parser` constructor as protected, not private, so plugins can extend it without type errors.

Fix a bug where some invalid `delete` expressions were let through when the operand was parenthesized and `preserveParens` was enabled.

Properly normalize line endings in raw strings of invalid template tokens.

Properly track line numbers for escaped newlines in strings.

Fix a bug that broke line number accounting after a template literal with invalid escape sequences.

## 8.11.3 (2023-12-29)

### Bug fixes

Add `Function` and `Class` to the `AggregateType` type, so that they can be used in walkers without raising a type error.

Make sure `onToken` get an `import` keyword token when parsing `import.meta`.

Fix a bug where `.loc.start` could be undefined for `new.target` `meta` nodes.

## 8.11.2 (2023-10-27)

### Bug fixes

Fix a bug that caused regular expressions after colon tokens to not be properly tokenized in some circumstances.

## 8.11.1 (2023-10-26)

### Bug fixes

Fix a regression where `onToken` would receive 'name' tokens for 'new' keyword tokens.

## 8.11.0 (2023-10-26)

### Bug fixes

Fix an issue where tokenizing (without parsing) an object literal with a property named `class` or `function` could, in some circumstance, put the tokenizer into an invalid state.

Fix an issue where a slash after a call to a propery named the same as some keywords would be tokenized as a regular expression.

### New features

Upgrade to Unicode 15.1.

Use a set of new, much more precise, TypeScript types.

## 8.10.0 (2023-07-05)

### New features

Add a `checkPrivateFields` option that disables strict checking of private property use.

## 8.9.0 (2023-06-16)

### Bug fixes

Forbid dynamic import after `new`, even when part of a member expression.

### New features

Add Unicode properties for ES2023.

Add support for the `v` flag to regular expressions.

## 8.8.2 (2023-01-23)

### Bug fixes

Fix a bug that caused `allowHashBang` to be set to false when not provided, even with `ecmaVersion >= 14`.

Fix an exception when passing no option object to `parse` or `new Parser`.

Fix incorrect parse error on `if (0) let\n[astral identifier char]`.

## 8.8.1 (2022-10-24)

### Bug fixes

Make type for `Comment` compatible with estree types.

## 8.8.0 (2022-07-21)

### Bug fixes

Allow parentheses around spread args in destructuring object assignment.

Fix an issue where the tree contained `directive` properties in when parsing with a language version that doesn't support them.

### New features

Support hashbang comments by default in ECMAScript 2023 and later.

## 8.7.1 (2021-04-26)

### Bug fixes

Stop handling `"use strict"` directives in ECMAScript versions before 5.

Fix an issue where duplicate quoted export names in `export *` syntax were incorrectly checked.

Add missing type for `tokTypes`.

## 8.7.0 (2021-12-27)

### New features

Support quoted export names.

Upgrade to Unicode 14.

Add support for Unicode 13 properties in regular expressions.

### Bug fixes

Use a loop to find line breaks, because the existing regexp search would overrun the end of the searched range and waste a lot of time in minified code.

## 8.6.0 (2021-11-18)

### Bug fixes

Fix a bug where an object literal with multiple `__proto__` properties would incorrectly be accepted if a later property value held an assigment.

### New features

Support class private fields with the `in` operator.

## 8.5.0 (2021-09-06)

### Bug fixes

Improve context-dependent tokenization in a number of corner cases.

Fix location tracking after a 0x2028 or 0x2029 character in a string literal (which before did not increase the line number).

Fix an issue where arrow function bodies in for loop context would inappropriately consume `in` operators.

Fix wrong end locations stored on SequenceExpression nodes.

Implement restriction that `for`/`of` loop LHS can't start with `let`.

### New features

Add support for ES2022 class static blocks.

Allow multiple input files to be passed to the CLI tool.

## 8.4.1 (2021-06-24)

### Bug fixes

Fix a bug where `allowAwaitOutsideFunction` would allow `await` in class field initializers, and setting `ecmaVersion` to 13 or higher would allow top-level await in non-module sources.

## 8.4.0 (2021-06-11)

### New features

A new option, `allowSuperOutsideMethod`, can be used to suppress the error when `super` is used in the wrong context.

## 8.3.0 (2021-05-31)

### New features

Default `allowAwaitOutsideFunction` to true for ECMAScript 2022 an higher.

Add support for the `d` ([indices](https://github.com/tc39/proposal-regexp-match-indices)) regexp flag.

## 8.2.4 (2021-05-04)

### Bug fixes

Fix spec conformity in corner case 'for await (async of ...)'.

## 8.2.3 (2021-05-04)

### Bug fixes

Fix an issue where the library couldn't parse 'for (async of ...)'.

Fix a bug in UTF-16 decoding that would read characters incorrectly in some circumstances.

## 8.2.2 (2021-04-29)

### Bug fixes

Fix a bug where a class field initialized to an async arrow function wouldn't allow await inside it. Same issue existed for generator arrow functions with yield.

## 8.2.1 (2021-04-24)

### Bug fixes

Fix a regression introduced in 8.2.0 where static or async class methods with keyword names fail to parse.

## 8.2.0 (2021-04-24)

### New features

Add support for ES2022 class fields and private methods.

## 8.1.1 (2021-04-12)

### Various

Stop shipping source maps in the NPM package.

## 8.1.0 (2021-03-09)

### Bug fixes

Fix a spurious error in nested destructuring arrays.

### New features

Expose `allowAwaitOutsideFunction` in CLI interface.

Make `allowImportExportAnywhere` also apply to `import.meta`.

## 8.0.5 (2021-01-25)

### Bug fixes

Adjust package.json to work with Node 12.16.0 and 13.0-13.6.

## 8.0.4 (2020-10-05)

### Bug fixes

Make `await x ** y` an error, following the spec.

Fix potentially exponential regular expression.

## 8.0.3 (2020-10-02)

### Bug fixes

Fix a wasteful loop during `Parser` creation when setting `ecmaVersion` to `"latest"`.

## 8.0.2 (2020-09-30)

### Bug fixes

Make the TypeScript types reflect the current allowed values for `ecmaVersion`.

Fix another regexp/division tokenizer issue.

## 8.0.1 (2020-08-12)

### Bug fixes

Provide the correct value in the `version` export.

## 8.0.0 (2020-08-12)

### Bug fixes

Disallow expressions like `(a = b) = c`.

Make non-octal escape sequences a syntax error in strict mode.

### New features

The package can now be loaded directly as an ECMAScript module in node 13+.

Update to the set of Unicode properties from ES2021.

### Breaking changes

The `ecmaVersion` option is now required. For the moment, omitting it will still work with a warning, but that will change in a future release.

Some changes to method signatures that may be used by plugins.

## 7.4.0 (2020-08-03)

### New features

Add support for logical assignment operators.

Add support for numeric separators.

## 7.3.1 (2020-06-11)

### Bug fixes

Make the string in the `version` export match the actual library version.

## 7.3.0 (2020-06-11)

### Bug fixes

Fix a bug that caused parsing of object patterns with a property named `set` that had a default value to fail.

### New features

Add support for optional chaining (`?.`).

## 7.2.0 (2020-05-09)

### Bug fixes

Fix precedence issue in parsing of async arrow functions.

### New features

Add support for nullish coalescing.

Add support for `import.meta`.

Support `export * as ...` syntax.

Upgrade to Unicode 13.

## 6.4.1 (2020-03-09)

### Bug fixes

More carefully check for valid UTF16 surrogate pairs in regexp validator.

## 7.1.1 (2020-03-01)

### Bug fixes

Treat `\8` and `\9` as invalid escapes in template strings.

Allow unicode escapes in property names that are keywords.

Don't error on an exponential operator expression as argument to `await`.

More carefully check for valid UTF16 surrogate pairs in regexp validator.

## 7.1.0 (2019-09-24)

### Bug fixes

Disallow trailing object literal commas when ecmaVersion is less than 5.

### New features

Add a static `acorn` property to the `Parser` class that contains the entire module interface, to allow plugins to access the instance of the library that they are acting on.

## 7.0.0 (2019-08-13)

### Breaking changes

Changes the node format for dynamic imports to use the `ImportExpression` node type, as defined in [ESTree](https://github.com/estree/estree/blob/master/es2020.md#importexpression).

Makes 10 (ES2019) the default value for the `ecmaVersion` option.

## 6.3.0 (2019-08-12)

### New features

`sourceType: "module"` can now be used even when `ecmaVersion` is less than 6, to parse module-style code that otherwise conforms to an older standard.

## 6.2.1 (2019-07-21)

### Bug fixes

Fix bug causing Acorn to treat some characters as identifier characters that shouldn't be treated as such.

Fix issue where setting the `allowReserved` option to `"never"` allowed reserved words in some circumstances.

## 6.2.0 (2019-07-04)

### Bug fixes

Improve valid assignment checking in `for`/`in` and `for`/`of` loops.

Disallow binding `let` in patterns.

### New features

Support bigint syntax with `ecmaVersion` >= 11.

Support dynamic `import` syntax with `ecmaVersion` >= 11.

Upgrade to Unicode version 12.

## 6.1.1 (2019-02-27)

### Bug fixes

Fix bug that caused parsing default exports of with names to fail.

## 6.1.0 (2019-02-08)

### Bug fixes

Fix scope checking when redefining a `var` as a lexical binding.

### New features

Split up `parseSubscripts` to use an internal `parseSubscript` method to make it easier to extend with plugins.

## 6.0.7 (2019-02-04)

### Bug fixes

Check that exported bindings are defined.

Don't treat `\u180e` as a whitespace character.

Check for duplicate parameter names in methods.

Don't allow shorthand properties when they are generators or async methods.

Forbid binding `await` in async arrow function's parameter list.

## 6.0.6 (2019-01-30)

### Bug fixes

The content of class declarations and expressions is now always parsed in strict mode.

Don't allow `let` or `const` to bind the variable name `let`.

Treat class declarations as lexical.

Don't allow a generator function declaration as the sole body of an `if` or `else`.

Ignore `"use strict"` when after an empty statement.

Allow string line continuations with special line terminator characters.

Treat `for` bodies as part of the `for` scope when checking for conflicting bindings.

Fix bug with parsing `yield` in a `for` loop initializer.

Implement special cases around scope checking for functions.

## 6.0.5 (2019-01-02)

### Bug fixes

Fix TypeScript type for `Parser.extend` and add `allowAwaitOutsideFunction` to options type.

Don't treat `let` as a keyword when the next token is `{` on the next line.

Fix bug that broke checking for parentheses around an object pattern in a destructuring assignment when `preserveParens` was on.

## 6.0.4 (2018-11-05)

### Bug fixes

Further improvements to tokenizing regular expressions in corner cases.

## 6.0.3 (2018-11-04)

### Bug fixes

Fix bug in tokenizing an expression-less return followed by a function followed by a regular expression.

Remove stray symlink in the package tarball.

## 6.0.2 (2018-09-26)

### Bug fixes

Fix bug where default expressions could fail to parse inside an object destructuring assignment expression.

## 6.0.1 (2018-09-14)

### Bug fixes

Fix wrong value in `version` export.

## 6.0.0 (2018-09-14)

### Bug fixes

Better handle variable-redefinition checks for catch bindings and functions directly under if statements.

Forbid `new.target` in top-level arrow functions.

Fix issue with parsing a regexp after `yield` in some contexts.

### New features

The package now comes with TypeScript definitions.

### Breaking changes

The default value of the `ecmaVersion` option is now 9 (2018).

Plugins work differently, and will have to be rewritten to work with this version.

The loose parser and walker have been moved into separate packages (`acorn-loose` and `acorn-walk`).

## 5.7.3 (2018-09-10)

### Bug fixes

Fix failure to tokenize regexps after expressions like `x.of`.

Better error message for unterminated template literals.

## 5.7.2 (2018-08-24)

### Bug fixes

Properly handle `allowAwaitOutsideFunction` in for statements.

Treat function declarations at the top level of modules like let bindings.

Don't allow async function declarations as the only statement under a label.

## 5.7.0 (2018-06-15)

### New features

Upgraded to Unicode 11.

## 5.6.0 (2018-05-31)

### New features

Allow U+2028 and U+2029 in string when ECMAVersion >= 10.

Allow binding-less catch statements when ECMAVersion >= 10.

Add `allowAwaitOutsideFunction` option for parsing top-level `await`.

## 5.5.3 (2018-03-08)

### Bug fixes

A _second_ republish of the code in 5.5.1, this time with yarn, to hopefully get valid timestamps.

## 5.5.2 (2018-03-08)

### Bug fixes

A republish of the code in 5.5.1 in an attempt to solve an issue with the file timestamps in the npm package being 0.

## 5.5.1 (2018-03-06)

### Bug fixes

Fix misleading error message for octal escapes in template strings.

## 5.5.0 (2018-02-27)

### New features

The identifier character categorization is now based on Unicode version 10.

Acorn will now validate the content of regular expressions, including new ES9 features.

## 5.4.0 (2018-02-01)

### Bug fixes

Disallow duplicate or escaped flags on regular expressions.

Disallow octal escapes in strings in strict mode.

### New features

Add support for async iteration.

Add support for object spread and rest.

## 5.3.0 (2017-12-28)

### Bug fixes

Fix parsing of floating point literals with leading zeroes in loose mode.

Allow duplicate property names in object patterns.

Don't allow static class methods named `prototype`.

Disallow async functions directly under `if` or `else`.

Parse right-hand-side of `for`/`of` as an assignment expression.

Stricter parsing of `for`/`in`.

Don't allow unicode escapes in contextual keywords.

### New features

Parsing class members was factored into smaller methods to allow plugins to hook into it.

## 5.2.1 (2017-10-30)

### Bug fixes

Fix a token context corruption bug.

## 5.2.0 (2017-10-30)

### Bug fixes

Fix token context tracking for `class` and `function` in property-name position.

Make sure `%*` isn't parsed as a valid operator.

Allow shorthand properties `get` and `set` to be followed by default values.

Disallow `super` when not in callee or object position.

### New features

Support [`directive` property](https://github.com/estree/estree/compare/b3de58c9997504d6fba04b72f76e6dd1619ee4eb...1da8e603237144f44710360f8feb7a9977e905e0) on directive expression statements.

## 5.1.2 (2017-09-04)

### Bug fixes

Disable parsing of legacy HTML-style comments in modules.

Fix parsing of async methods whose names are keywords.

## 5.1.1 (2017-07-06)

### Bug fixes

Fix problem with disambiguating regexp and division after a class.

## 5.1.0 (2017-07-05)

### Bug fixes

Fix tokenizing of regexps in an object-desctructuring `for`/`of` loop and after `yield`.

Parse zero-prefixed numbers with non-octal digits as decimal.

Allow object/array patterns in rest parameters.

Don't error when `yield` is used as a property name.

Allow `async` as a shorthand object property.

### New features

Implement the [template literal revision proposal](https://github.com/tc39/proposal-template-literal-revision) for ES9.

## 5.0.3 (2017-04-01)

### Bug fixes

Fix spurious duplicate variable definition errors for named functions.

## 5.0.2 (2017-03-30)

### Bug fixes

A binary operator after a parenthesized arrow expression is no longer incorrectly treated as an error.

## 5.0.0 (2017-03-28)

### Bug fixes

Raise an error for duplicated lexical bindings.

Fix spurious error when an assignement expression occurred after a spread expression.

Accept regular expressions after `of` (in `for`/`of`), `yield` (in a generator), and braced arrow functions.

Allow labels in front or `var` declarations, even in strict mode.

### Breaking changes

Parse declarations following `export default` as declaration nodes, not expressions. This means that class and function declarations nodes can now have `null` as their `id`.

## 4.0.11 (2017-02-07)

### Bug fixes

Allow all forms of member expressions to be parenthesized as lvalue.

## 4.0.10 (2017-02-07)

### Bug fixes

Don't expect semicolons after default-exported functions or classes, even when they are expressions.

Check for use of `'use strict'` directives in non-simple parameter functions, even when already in strict mode.

## 4.0.9 (2017-02-06)

### Bug fixes

Fix incorrect error raised for parenthesized simple assignment targets, so that `(x) = 1` parses again.

## 4.0.8 (2017-02-03)

### Bug fixes

Solve spurious parenthesized pattern errors by temporarily erring on the side of accepting programs that our delayed errors don't handle correctly yet.

## 4.0.7 (2017-02-02)

### Bug fixes

Accept invalidly rejected code like `(x).y = 2` again.

Don't raise an error when a function _inside_ strict code has a non-simple parameter list.

## 4.0.6 (2017-02-02)

### Bug fixes

Fix exponential behavior (manifesting itself as a complete hang for even relatively small source files) introduced by the new 'use strict' check.

## 4.0.5 (2017-02-02)

### Bug fixes

Disallow parenthesized pattern expressions.

Allow keywords as export names.

Don't allow the `async` keyword to be parenthesized.

Properly raise an error when a keyword contains a character escape.

Allow `"use strict"` to appear after other string literal expressions.

Disallow labeled declarations.

## 4.0.4 (2016-12-19)

### Bug fixes

Fix crash when `export` was followed by a keyword that can't be
exported.

## 4.0.3 (2016-08-16)

### Bug fixes

Allow regular function declarations inside single-statement `if` branches in loose mode. Forbid them entirely in strict mode.

Properly parse properties named `async` in ES2017 mode.

Fix bug where reserved words were broken in ES2017 mode.

## 4.0.2 (2016-08-11)

### Bug fixes

Don't ignore period or 'e' characters after octal numbers.

Fix broken parsing for call expressions in default parameter values of arrow functions.

## 4.0.1 (2016-08-08)

### Bug fixes

Fix false positives in duplicated export name errors.

## 4.0.0 (2016-08-07)

### Breaking changes

The default `ecmaVersion` option value is now 7.

A number of internal method signatures changed, so plugins might need to be updated.

### Bug fixes

The parser now raises errors on duplicated export names.

`arguments` and `eval` can now be used in shorthand properties.

Duplicate parameter names in non-simple argument lists now always produce an error.

### New features

The `ecmaVersion` option now also accepts year-style version numbers
(2015, etc).

Support for `async`/`await` syntax when `ecmaVersion` is >= 8.

Support for trailing commas in call expressions when `ecmaVersion` is >= 8.

## 3.3.0 (2016-07-25)

### Bug fixes

Fix bug in tokenizing of regexp operator after a function declaration.

Fix parser crash when parsing an array pattern with a hole.

### New features

Implement check against complex argument lists in functions that enable strict mode in ES7.

## 3.2.0 (2016-06-07)

### Bug fixes

Improve handling of lack of unicode regexp support in host
environment.

Properly reject shorthand properties whose name is a keyword.

### New features

Visitors created with `visit.make` now have their base as _prototype_, rather than copying properties into a fresh object.

## 3.1.0 (2016-04-18)

### Bug fixes

Properly tokenize the division operator directly after a function expression.

Allow trailing comma in destructuring arrays.

## 3.0.4 (2016-02-25)

### Fixes

Allow update expressions as left-hand-side of the ES7 exponential operator.

## 3.0.2 (2016-02-10)

### Fixes

Fix bug that accidentally made `undefined` a reserved word when parsing ES7.

## 3.0.0 (2016-02-10)

### Breaking changes

The default value of the `ecmaVersion` option is now 6 (used to be 5).

Support for comprehension syntax (which was dropped from the draft spec) has been removed.

### Fixes

`let` and `yield` are now “contextual keywords”, meaning you can mostly use them as identifiers in ES5 non-strict code.

A parenthesized class or function expression after `export default` is now parsed correctly.

### New features

When `ecmaVersion` is set to 7, Acorn will parse the exponentiation operator (`**`).

The identifier character ranges are now based on Unicode 8.0.0.

Plugins can now override the `raiseRecoverable` method to override the way non-critical errors are handled.

## 2.7.0 (2016-01-04)

### Fixes

Stop allowing rest parameters in setters.

Disallow `y` rexexp flag in ES5.

Disallow `\00` and `\000` escapes in strict mode.

Raise an error when an import name is a reserved word.

## 2.6.2 (2015-11-10)

### Fixes

Don't crash when no options object is passed.

## 2.6.0 (2015-11-09)

### Fixes

Add `await` as a reserved word in module sources.

Disallow `yield` in a parameter default value for a generator.

Forbid using a comma after a rest pattern in an array destructuring.

### New features

Support parsing stdin in command-line tool.

## 2.5.0 (2015-10-27)

### Fixes

Fix tokenizer support in the command-line tool.

Stop allowing `new.target` outside of functions.

Remove legacy `guard` and `guardedHandler` properties from try nodes.

Stop allowing multiple `__proto__` properties on an object literal in strict mode.

Don't allow rest parameters to be non-identifier patterns.

Check for duplicate paramter names in arrow functions.


code:
# Acorn

A tiny, fast JavaScript parser written in JavaScript.

## Community

Acorn is open source software released under an
[MIT license](https://github.com/acornjs/acorn/blob/master/acorn/LICENSE).

You are welcome to
[report bugs](https://github.com/acornjs/acorn/issues) or create pull
requests on [github](https://github.com/acornjs/acorn).

## Installation

The easiest way to install acorn is from [`npm`](https://www.npmjs.com/):

```sh
npm install acorn
```

Alternately, you can download the source and build acorn yourself:

```sh
git clone https://github.com/acornjs/acorn.git
cd acorn
npm install
```

## Interface

**parse**`(input, options)` is the main interface to the library. The
`input` parameter is a string, `options` must be an object setting
some of the options listed below. The return value will be an abstract
syntax tree object as specified by the [ESTree
spec](https://github.com/estree/estree).

```javascript
let acorn = require("acorn");
console.log(acorn.parse("1 + 1", {ecmaVersion: 2020}));
```

When encountering a syntax error, the parser will raise a
`SyntaxError` object with a meaningful message. The error object will
have a `pos` property that indicates the string offset at which the
error occurred, and a `loc` object that contains a `{line, column}`
object referring to that same position.

Options are provided by in a second argument, which should be an
object containing any of these fields (only `ecmaVersion` is
required):

- **ecmaVersion**: Indicates the ECMAScript version to parse. Can be a
  number, either in year (`2022`) or plain version number (`6`) form,
  or `"latest"` (the latest the library supports). This influences
  support for strict mode, the set of reserved words, and support for
  new syntax features.

  **NOTE**: Only 'stage 4' (finalized) ECMAScript features are being
  implemented by Acorn. Other proposed new features must be
  implemented through plugins.

- **sourceType**: Indicate the mode the code should be parsed in. Can be
  either `"script"` or `"module"`. This influences global strict mode
  and parsing of `import` and `export` declarations.

  **NOTE**: If set to `"module"`, then static `import` / `export` syntax
  will be valid, even if `ecmaVersion` is less than 6.

- **onInsertedSemicolon**: If given a callback, that callback will be
  called whenever a missing semicolon is inserted by the parser. The
  callback will be given the character offset of the point where the
  semicolon is inserted as argument, and if `locations` is on, also a
  `{line, column}` object representing this position.

- **onTrailingComma**: Like `onInsertedSemicolon`, but for trailing
  commas.

- **allowReserved**: If `false`, using a reserved word will generate
  an error. Defaults to `true` for `ecmaVersion` 3, `false` for higher
  versions. When given the value `"never"`, reserved words and
  keywords can also not be used as property names (as in Internet
  Explorer's old parser).

- **allowReturnOutsideFunction**: By default, a return statement at
  the top level raises an error. Set this to `true` to accept such
  code.

- **allowImportExportEverywhere**: By default, `import` and `export`
  declarations can only appear at a program's top level. Setting this
  option to `true` allows them anywhere where a statement is allowed,
  and also allows `import.meta` expressions to appear in scripts
  (when `sourceType` is not `"module"`).

- **allowAwaitOutsideFunction**: If `false`, `await` expressions can
  only appear inside `async` functions. Defaults to `true` in modules
  for `ecmaVersion` 2022 and later, `false` for lower versions.
  Setting this option to `true` allows to have top-level `await`
  expressions. They are still not allowed in non-`async` functions,
  though.

- **allowSuperOutsideMethod**: By default, `super` outside a method
  raises an error. Set this to `true` to accept such code.

- **allowHashBang**: When this is enabled, if the code starts with the
  characters `#!` (as in a shellscript), the first line will be
  treated as a comment. Defaults to true when `ecmaVersion` >= 2023.

- **checkPrivateFields**: By default, the parser will verify that
  private properties are only used in places where they are valid and
  have been declared. Set this to false to turn such checks off.

- **locations**: When `true`, each node has a `loc` object attached
  with `start` and `end` subobjects, each of which contains the
  one-based line and zero-based column numbers in `{line, column}`
  form. Default is `false`.

- **onToken**: If a function is passed for this option, each found
  token will be passed in same format as tokens returned from
  `tokenizer().getToken()`.

  If array is passed, each found token is pushed to it.

  Note that you are not allowed to call the parser from the
  callback—that will corrupt its internal state.

- **onComment**: If a function is passed for this option, whenever a
  comment is encountered the function will be called with the
  following parameters:

  - `block`: `true` if the comment is a block comment, false if it
    is a line comment.
  - `text`: The content of the comment.
  - `start`: Character offset of the start of the comment.
  - `end`: Character offset of the end of the comment.

  When the `locations` options is on, the `{line, column}` locations
  of the comment’s start and end are passed as two additional
  parameters.

  If array is passed for this option, each found comment is pushed
  to it as object in Esprima format:

  ```javascript
  {
    "type": "Line" | "Block",
    "value": "comment text",
    "start": Number,
    "end": Number,
    // If `locations` option is on:
    "loc": {
      "start": {line: Number, column: Number}
      "end": {line: Number, column: Number}
    },
    // If `ranges` option is on:
    "range": [Number, Number]
  }
  ```

  Note that you are not allowed to call the parser from the
  callback—that will corrupt its internal state.

- **ranges**: Nodes have their start and end characters offsets
  recorded in `start` and `end` properties (directly on the node,
  rather than the `loc` object, which holds line/column data. To also
  add a
  [semi-standardized](https://bugzilla.mozilla.org/show_bug.cgi?id=745678)
  `range` property holding a `[start, end]` array with the same
  numbers, set the `ranges` option to `true`.

- **program**: It is possible to parse multiple files into a single
  AST by passing the tree produced by parsing the first file as the
  `program` option in subsequent parses. This will add the toplevel
  forms of the parsed file to the "Program" (top) node of an existing
  parse tree.

- **sourceFile**: When the `locations` option is `true`, you can pass
  this option to add a `source` attribute in every node’s `loc`
  object. Note that the contents of this option are not examined or
  processed in any way; you are free to use whatever format you
  choose.

- **directSourceFile**: Like `sourceFile`, but a `sourceFile` property
  will be added (regardless of the `location` option) directly to the
  nodes, rather than the `loc` object.

- **preserveParens**: If this option is `true`, parenthesized expressions
  are represented by (non-standard) `ParenthesizedExpression` nodes
  that have a single `expression` property containing the expression
  inside parentheses.

**parseExpressionAt**`(input, offset, options)` will parse a single
expression in a string, and return its AST. It will not complain if
there is more of the string left after the expression.

**tokenizer**`(input, options)` returns an object with a `getToken`
method that can be called repeatedly to get the next token, a `{start,
end, type, value}` object (with added `loc` property when the
`locations` option is enabled and `range` property when the `ranges`
option is enabled). When the token's type is `tokTypes.eof`, you
should stop calling the method, since it will keep returning that same
token forever.

Note that tokenizing JavaScript without parsing it is, in modern
versions of the language, not really possible due to the way syntax is
overloaded in ways that can only be disambiguated by the parse
context. This package applies a bunch of heuristics to try and do a
reasonable job, but you are advised to use `parse` with the `onToken`
option instead of this.

In ES6 environment, returned result can be used as any other
protocol-compliant iterable:

```javascript
for (let token of acorn.tokenizer(str)) {
  // iterate over the tokens
}

// transform code to array of tokens:
var tokens = [...acorn.tokenizer(str)];
```

**tokTypes** holds an object mapping names to the token type objects
that end up in the `type` properties of tokens.

**getLineInfo**`(input, offset)` can be used to get a `{line,
column}` object for a given program string and offset.

### The `Parser` class

Instances of the **`Parser`** class contain all the state and logic
that drives a parse. It has static methods `parse`,
`parseExpressionAt`, and `tokenizer` that match the top-level
functions by the same name.

When extending the parser with plugins, you need to call these methods
on the extended version of the class. To extend a parser with plugins,
you can use its static `extend` method.

```javascript
var acorn = require("acorn");
var jsx = require("acorn-jsx");
var JSXParser = acorn.Parser.extend(jsx());
JSXParser.parse("foo(<bar/>)", {ecmaVersion: 2020});
```

The `extend` method takes any number of plugin values, and returns a
new `Parser` class that includes the extra parser logic provided by
the plugins.

## Command line interface

The `bin/acorn` utility can be used to parse a file from the command
line. It accepts as arguments its input file and the following
options:

- `--ecma3|--ecma5|--ecma6|--ecma7|--ecma8|--ecma9|--ecma10`: Sets the ECMAScript version
  to parse. Default is version 9.

- `--module`: Sets the parsing mode to `"module"`. Is set to `"script"` otherwise.

- `--locations`: Attaches a "loc" object to each node with "start" and
  "end" subobjects, each of which contains the one-based line and
  zero-based column numbers in `{line, column}` form.

- `--allow-hash-bang`: If the code starts with the characters #! (as
  in a shellscript), the first line will be treated as a comment.

- `--allow-await-outside-function`: Allows top-level `await` expressions.
  See the `allowAwaitOutsideFunction` option for more information.

- `--compact`: No whitespace is used in the AST output.

- `--silent`: Do not output the AST, just return the exit status.

- `--help`: Print the usage information and quit.

The utility spits out the syntax tree as JSON data.

## Existing plugins

 - [`acorn-jsx`](https://github.com/RReverser/acorn-jsx): Parse [Facebook JSX syntax extensions](https://github.com/facebook/jsx)


code:
#!/usr/bin/env node
"use strict"

require("../dist/bin.js")


code:
export interface Node {
  start: number
  end: number
  type: string
  range?: [number, number]
  loc?: SourceLocation | null
}

export interface SourceLocation {
  source?: string | null
  start: Position
  end: Position
}

export interface Position {
  /** 1-based */
  line: number
  /** 0-based */
  column: number
}

export interface Identifier extends Node {
  type: "Identifier"
  name: string
}

export interface Literal extends Node {
  type: "Literal"
  value?: string | boolean | null | number | RegExp | bigint
  raw?: string
  regex?: {
    pattern: string
    flags: string
  }
  bigint?: string
}

export interface Program extends Node {
  type: "Program"
  body: Array<Statement | ModuleDeclaration>
  sourceType: "script" | "module"
}

export interface Function extends Node {
  id?: Identifier | null
  params: Array<Pattern>
  body: BlockStatement | Expression
  generator: boolean
  expression: boolean
  async: boolean
}

export interface ExpressionStatement extends Node {
  type: "ExpressionStatement"
  expression: Expression | Literal
  directive?: string
}

export interface BlockStatement extends Node {
  type: "BlockStatement"
  body: Array<Statement>
}

export interface EmptyStatement extends Node {
  type: "EmptyStatement"
}

export interface DebuggerStatement extends Node {
  type: "DebuggerStatement"
}

export interface WithStatement extends Node {
  type: "WithStatement"
  object: Expression
  body: Statement
}

export interface ReturnStatement extends Node {
  type: "ReturnStatement"
  argument?: Expression | null
}

export interface LabeledStatement extends Node {
  type: "LabeledStatement"
  label: Identifier
  body: Statement
}

export interface BreakStatement extends Node {
  type: "BreakStatement"
  label?: Identifier | null
}

export interface ContinueStatement extends Node {
  type: "ContinueStatement"
  label?: Identifier | null
}

export interface IfStatement extends Node {
  type: "IfStatement"
  test: Expression
  consequent: Statement
  alternate?: Statement | null
}

export interface SwitchStatement extends Node {
  type: "SwitchStatement"
  discriminant: Expression
  cases: Array<SwitchCase>
}

export interface SwitchCase extends Node {
  type: "SwitchCase"
  test?: Expression | null
  consequent: Array<Statement>
}

export interface ThrowStatement extends Node {
  type: "ThrowStatement"
  argument: Expression
}

export interface TryStatement extends Node {
  type: "TryStatement"
  block: BlockStatement
  handler?: CatchClause | null
  finalizer?: BlockStatement | null
}

export interface CatchClause extends Node {
  type: "CatchClause"
  param?: Pattern | null
  body: BlockStatement
}

export interface WhileStatement extends Node {
  type: "WhileStatement"
  test: Expression
  body: Statement
}

export interface DoWhileStatement extends Node {
  type: "DoWhileStatement"
  body: Statement
  test: Expression
}

export interface ForStatement extends Node {
  type: "ForStatement"
  init?: VariableDeclaration | Expression | null
  test?: Expression | null
  update?: Expression | null
  body: Statement
}

export interface ForInStatement extends Node {
  type: "ForInStatement"
  left: VariableDeclaration | Pattern
  right: Expression
  body: Statement
}

export interface FunctionDeclaration extends Function {
  type: "FunctionDeclaration"
  id: Identifier
  body: BlockStatement
}

export interface VariableDeclaration extends Node {
  type: "VariableDeclaration"
  declarations: Array<VariableDeclarator>
  kind: "var" | "let" | "const"
}

export interface VariableDeclarator extends Node {
  type: "VariableDeclarator"
  id: Pattern
  init?: Expression | null
}

export interface ThisExpression extends Node {
  type: "ThisExpression"
}

export interface ArrayExpression extends Node {
  type: "ArrayExpression"
  elements: Array<Expression | SpreadElement | null>
}

export interface ObjectExpression extends Node {
  type: "ObjectExpression"
  properties: Array<Property | SpreadElement>
}

export interface Property extends Node {
  type: "Property"
  key: Expression
  value: Expression
  kind: "init" | "get" | "set"
  method: boolean
  shorthand: boolean
  computed: boolean
}

export interface FunctionExpression extends Function {
  type: "FunctionExpression"
  body: BlockStatement
}

export interface UnaryExpression extends Node {
  type: "UnaryExpression"
  operator: UnaryOperator
  prefix: boolean
  argument: Expression
}

export type UnaryOperator = "-" | "+" | "!" | "~" | "typeof" | "void" | "delete"

export interface UpdateExpression extends Node {
  type: "UpdateExpression"
  operator: UpdateOperator
  argument: Expression
  prefix: boolean
}

export type UpdateOperator = "++" | "--"

export interface BinaryExpression extends Node {
  type: "BinaryExpression"
  operator: BinaryOperator
  left: Expression | PrivateIdentifier
  right: Expression
}

export type BinaryOperator = "==" | "!=" | "===" | "!==" | "<" | "<=" | ">" | ">=" | "<<" | ">>" | ">>>" | "+" | "-" | "*" | "/" | "%" | "|" | "^" | "&" | "in" | "instanceof" | "**"

export interface AssignmentExpression extends Node {
  type: "AssignmentExpression"
  operator: AssignmentOperator
  left: Pattern
  right: Expression
}

export type AssignmentOperator = "=" | "+=" | "-=" | "*=" | "/=" | "%=" | "<<=" | ">>=" | ">>>=" | "|=" | "^=" | "&=" | "**=" | "||=" | "&&=" | "??="

export interface LogicalExpression extends Node {
  type: "LogicalExpression"
  operator: LogicalOperator
  left: Expression
  right: Expression
}

export type LogicalOperator = "||" | "&&" | "??"

export interface MemberExpression extends Node {
  type: "MemberExpression"
  object: Expression | Super
  property: Expression | PrivateIdentifier
  computed: boolean
  optional: boolean
}

export interface ConditionalExpression extends Node {
  type: "ConditionalExpression"
  test: Expression
  alternate: Expression
  consequent: Expression
}

export interface CallExpression extends Node {
  type: "CallExpression"
  callee: Expression | Super
  arguments: Array<Expression | SpreadElement>
  optional: boolean
}

export interface NewExpression extends Node {
  type: "NewExpression"
  callee: Expression
  arguments: Array<Expression | SpreadElement>
}

export interface SequenceExpression extends Node {
  type: "SequenceExpression"
  expressions: Array<Expression>
}

export interface ForOfStatement extends Node {
  type: "ForOfStatement"
  left: VariableDeclaration | Pattern
  right: Expression
  body: Statement
  await: boolean
}

export interface Super extends Node {
  type: "Super"
}

export interface SpreadElement extends Node {
  type: "SpreadElement"
  argument: Expression
}

export interface ArrowFunctionExpression extends Function {
  type: "ArrowFunctionExpression"
}

export interface YieldExpression extends Node {
  type: "YieldExpression"
  argument?: Expression | null
  delegate: boolean
}

export interface TemplateLiteral extends Node {
  type: "TemplateLiteral"
  quasis: Array<TemplateElement>
  expressions: Array<Expression>
}

export interface TaggedTemplateExpression extends Node {
  type: "TaggedTemplateExpression"
  tag: Expression
  quasi: TemplateLiteral
}

export interface TemplateElement extends Node {
  type: "TemplateElement"
  tail: boolean
  value: {
    cooked?: string | null
    raw: string
  }
}

export interface AssignmentProperty extends Node {
  type: "Property"
  key: Expression
  value: Pattern
  kind: "init"
  method: false
  shorthand: boolean
  computed: boolean
}

export interface ObjectPattern extends Node {
  type: "ObjectPattern"
  properties: Array<AssignmentProperty | RestElement>
}

export interface ArrayPattern extends Node {
  type: "ArrayPattern"
  elements: Array<Pattern | null>
}

export interface RestElement extends Node {
  type: "RestElement"
  argument: Pattern
}

export interface AssignmentPattern extends Node {
  type: "AssignmentPattern"
  left: Pattern
  right: Expression
}

export interface Class extends Node {
  id?: Identifier | null
  superClass?: Expression | null
  body: ClassBody
}

export interface ClassBody extends Node {
  type: "ClassBody"
  body: Array<MethodDefinition | PropertyDefinition | StaticBlock>
}

export interface MethodDefinition extends Node {
  type: "MethodDefinition"
  key: Expression | PrivateIdentifier
  value: FunctionExpression
  kind: "constructor" | "method" | "get" | "set"
  computed: boolean
  static: boolean
}

export interface ClassDeclaration extends Class {
  type: "ClassDeclaration"
  id: Identifier
}

export interface ClassExpression extends Class {
  type: "ClassExpression"
}

export interface MetaProperty extends Node {
  type: "MetaProperty"
  meta: Identifier
  property: Identifier
}

export interface ImportDeclaration extends Node {
  type: "ImportDeclaration"
  specifiers: Array<ImportSpecifier | ImportDefaultSpecifier | ImportNamespaceSpecifier>
  source: Literal
}

export interface ImportSpecifier extends Node {
  type: "ImportSpecifier"
  imported: Identifier | Literal
  local: Identifier
}

export interface ImportDefaultSpecifier extends Node {
  type: "ImportDefaultSpecifier"
  local: Identifier
}

export interface ImportNamespaceSpecifier extends Node {
  type: "ImportNamespaceSpecifier"
  local: Identifier
}

export interface ExportNamedDeclaration extends Node {
  type: "ExportNamedDeclaration"
  declaration?: Declaration | null
  specifiers: Array<ExportSpecifier>
  source?: Literal | null
}

export interface ExportSpecifier extends Node {
  type: "ExportSpecifier"
  exported: Identifier | Literal
  local: Identifier | Literal
}

export interface AnonymousFunctionDeclaration extends Function {
  type: "FunctionDeclaration"
  id: null
  body: BlockStatement
}

export interface AnonymousClassDeclaration extends Class {
  type: "ClassDeclaration"
  id: null
}

export interface ExportDefaultDeclaration extends Node {
  type: "ExportDefaultDeclaration"
  declaration: AnonymousFunctionDeclaration | FunctionDeclaration | AnonymousClassDeclaration | ClassDeclaration | Expression
}

export interface ExportAllDeclaration extends Node {
  type: "ExportAllDeclaration"
  source: Literal
  exported?: Identifier | Literal | null
}

export interface AwaitExpression extends Node {
  type: "AwaitExpression"
  argument: Expression
}

export interface ChainExpression extends Node {
  type: "ChainExpression"
  expression: MemberExpression | CallExpression
}

export interface ImportExpression extends Node {
  type: "ImportExpression"
  source: Expression
}

export interface ParenthesizedExpression extends Node {
  type: "ParenthesizedExpression"
  expression: Expression
}

export interface PropertyDefinition extends Node {
  type: "PropertyDefinition"
  key: Expression | PrivateIdentifier
  value?: Expression | null
  computed: boolean
  static: boolean
}

export interface PrivateIdentifier extends Node {
  type: "PrivateIdentifier"
  name: string
}

export interface StaticBlock extends Node {
  type: "StaticBlock"
  body: Array<Statement>
}

export type Statement =
| ExpressionStatement
| BlockStatement
| EmptyStatement
| DebuggerStatement
| WithStatement
| ReturnStatement
| LabeledStatement
| BreakStatement
| ContinueStatement
| IfStatement
| SwitchStatement
| ThrowStatement
| TryStatement
| WhileStatement
| DoWhileStatement
| ForStatement
| ForInStatement
| ForOfStatement
| Declaration

export type Declaration =
| FunctionDeclaration
| VariableDeclaration
| ClassDeclaration

export type Expression =
| Identifier
| Literal
| ThisExpression
| ArrayExpression
| ObjectExpression
| FunctionExpression
| UnaryExpression
| UpdateExpression
| BinaryExpression
| AssignmentExpression
| LogicalExpression
| MemberExpression
| ConditionalExpression
| CallExpression
| NewExpression
| SequenceExpression
| ArrowFunctionExpression
| YieldExpression
| TemplateLiteral
| TaggedTemplateExpression
| ClassExpression
| MetaProperty
| AwaitExpression
| ChainExpression
| ImportExpression
| ParenthesizedExpression

export type Pattern =
| Identifier
| MemberExpression
| ObjectPattern
| ArrayPattern
| RestElement
| AssignmentPattern

export type ModuleDeclaration =
| ImportDeclaration
| ExportNamedDeclaration
| ExportDefaultDeclaration
| ExportAllDeclaration

export type AnyNode = Statement | Expression | Declaration | ModuleDeclaration | Literal | Program | SwitchCase | CatchClause | Property | Super | SpreadElement | TemplateElement | AssignmentProperty | ObjectPattern | ArrayPattern | RestElement | AssignmentPattern | ClassBody | MethodDefinition | MetaProperty | ImportSpecifier | ImportDefaultSpecifier | ImportNamespaceSpecifier | ExportSpecifier | AnonymousFunctionDeclaration | AnonymousClassDeclaration | PropertyDefinition | PrivateIdentifier | StaticBlock | VariableDeclarator

export function parse(input: string, options: Options): Program

export function parseExpressionAt(input: string, pos: number, options: Options): Expression

export function tokenizer(input: string, options: Options): {
  getToken(): Token
  [Symbol.iterator](): Iterator<Token>
}

export type ecmaVersion = 3 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 2015 | 2016 | 2017 | 2018 | 2019 | 2020 | 2021 | 2022 | 2023 | 2024 | 2025 | "latest"

export interface Options {
  /**
   * `ecmaVersion` indicates the ECMAScript version to parse. Can be a
   * number, either in year (`2022`) or plain version number (`6`) form,
   * or `"latest"` (the latest the library supports). This influences
   * support for strict mode, the set of reserved words, and support for
   * new syntax features.
   */
  ecmaVersion: ecmaVersion

  /**
   * `sourceType` indicates the mode the code should be parsed in.
   * Can be either `"script"` or `"module"`. This influences global
   * strict mode and parsing of `import` and `export` declarations.
   */
  sourceType?: "script" | "module"

  /**
   * a callback that will be called when a semicolon is automatically inserted.
   * @param lastTokEnd the position of the comma as an offset
   * @param lastTokEndLoc location if {@link locations} is enabled
   */
  onInsertedSemicolon?: (lastTokEnd: number, lastTokEndLoc?: Position) => void

  /**
   * similar to `onInsertedSemicolon`, but for trailing commas
   * @param lastTokEnd the position of the comma as an offset
   * @param lastTokEndLoc location if `locations` is enabled
   */
  onTrailingComma?: (lastTokEnd: number, lastTokEndLoc?: Position) => void

  /**
   * By default, reserved words are only enforced if ecmaVersion >= 5.
   * Set `allowReserved` to a boolean value to explicitly turn this on
   * an off. When this option has the value "never", reserved words
   * and keywords can also not be used as property names.
   */
  allowReserved?: boolean | "never"

  /**
   * When enabled, a return at the top level is not considered an error.
   */
  allowReturnOutsideFunction?: boolean

  /**
   * When enabled, import/export statements are not constrained to
   * appearing at the top of the program, and an import.meta expression
   * in a script isn't considered an error.
   */
  allowImportExportEverywhere?: boolean

  /**
   * By default, `await` identifiers are allowed to appear at the top-level scope only if {@link ecmaVersion} >= 2022.
   * When enabled, await identifiers are allowed to appear at the top-level scope,
   * but they are still not allowed in non-async functions.
   */
  allowAwaitOutsideFunction?: boolean

  /**
   * When enabled, super identifiers are not constrained to
   * appearing in methods and do not raise an error when they appear elsewhere.
   */
  allowSuperOutsideMethod?: boolean

  /**
   * When enabled, hashbang directive in the beginning of file is
   * allowed and treated as a line comment. Enabled by default when
   * {@link ecmaVersion} >= 2023.
   */
  allowHashBang?: boolean

  /**
   * By default, the parser will verify that private properties are
   * only used in places where they are valid and have been declared.
   * Set this to false to turn such checks off.
   */
  checkPrivateFields?: boolean

  /**
   * When `locations` is on, `loc` properties holding objects with
   * `start` and `end` properties as {@link Position} objects will be attached to the
   * nodes.
   */
  locations?: boolean

  /**
   * a callback that will cause Acorn to call that export function with object in the same
   * format as tokens returned from `tokenizer().getToken()`. Note
   * that you are not allowed to call the parser from the
   * callback—that will corrupt its internal state.
   */
  onToken?: ((token: Token) => void) | Token[]

  /**
   * This takes a export function or an array.
   *
   * When a export function is passed, Acorn will call that export function with `(block, text, start,
   * end)` parameters whenever a comment is skipped. `block` is a
   * boolean indicating whether this is a block (`/* *\/`) comment,
   * `text` is the content of the comment, and `start` and `end` are
   * character offsets that denote the start and end of the comment.
   * When the {@link locations} option is on, two more parameters are
   * passed, the full locations of {@link Position} export type of the start and
   * end of the comments.
   *
   * When a array is passed, each found comment of {@link Comment} export type is pushed to the array.
   *
   * Note that you are not allowed to call the
   * parser from the callback—that will corrupt its internal state.
   */
  onComment?: ((
    isBlock: boolean, text: string, start: number, end: number, startLoc?: Position,
    endLoc?: Position
  ) => void) | Comment[]

  /**
   * Nodes have their start and end characters offsets recorded in
   * `start` and `end` properties (directly on the node, rather than
   * the `loc` object, which holds line/column data. To also add a
   * [semi-standardized][range] `range` property holding a `[start,
   * end]` array with the same numbers, set the `ranges` option to
   * `true`.
   */
  ranges?: boolean

  /**
   * It is possible to parse multiple files into a single AST by
   * passing the tree produced by parsing the first file as
   * `program` option in subsequent parses. This will add the
   * toplevel forms of the parsed file to the `Program` (top) node
   * of an existing parse tree.
   */
  program?: Node

  /**
   * When {@link locations} is on, you can pass this to record the source
   * file in every node's `loc` object.
   */
  sourceFile?: string

  /**
   * This value, if given, is stored in every node, whether {@link locations} is on or off.
   */
  directSourceFile?: string

  /**
   * When enabled, parenthesized expressions are represented by
   * (non-standard) ParenthesizedExpression nodes
   */
  preserveParens?: boolean
}

export class Parser {
  options: Options
  input: string

  protected constructor(options: Options, input: string, startPos?: number)
  parse(): Program

  static parse(input: string, options: Options): Program
  static parseExpressionAt(input: string, pos: number, options: Options): Expression
  static tokenizer(input: string, options: Options): {
    getToken(): Token
    [Symbol.iterator](): Iterator<Token>
  }
  static extend(...plugins: ((BaseParser: typeof Parser) => typeof Parser)[]): typeof Parser
}

export const defaultOptions: Options

export function getLineInfo(input: string, offset: number): Position

export class TokenType {
  label: string
  keyword: string | undefined
}

export const tokTypes: {
  num: TokenType
  regexp: TokenType
  string: TokenType
  name: TokenType
  privateId: TokenType
  eof: TokenType

  bracketL: TokenType
  bracketR: TokenType
  braceL: TokenType
  braceR: TokenType
  parenL: TokenType
  parenR: TokenType
  comma: TokenType
  semi: TokenType
  colon: TokenType
  dot: TokenType
  question: TokenType
  questionDot: TokenType
  arrow: TokenType
  template: TokenType
  invalidTemplate: TokenType
  ellipsis: TokenType
  backQuote: TokenType
  dollarBraceL: TokenType

  eq: TokenType
  assign: TokenType
  incDec: TokenType
  prefix: TokenType
  logicalOR: TokenType
  logicalAND: TokenType
  bitwiseOR: TokenType
  bitwiseXOR: TokenType
  bitwiseAND: TokenType
  equality: TokenType
  relational: TokenType
  bitShift: TokenType
  plusMin: TokenType
  modulo: TokenType
  star: TokenType
  slash: TokenType
  starstar: TokenType
  coalesce: TokenType

  _break: TokenType
  _case: TokenType
  _catch: TokenType
  _continue: TokenType
  _debugger: TokenType
  _default: TokenType
  _do: TokenType
  _else: TokenType
  _finally: TokenType
  _for: TokenType
  _function: TokenType
  _if: TokenType
  _return: TokenType
  _switch: TokenType
  _throw: TokenType
  _try: TokenType
  _var: TokenType
  _const: TokenType
  _while: TokenType
  _with: TokenType
  _new: TokenType
  _this: TokenType
  _super: TokenType
  _class: TokenType
  _extends: TokenType
  _export: TokenType
  _import: TokenType
  _null: TokenType
  _true: TokenType
  _false: TokenType
  _in: TokenType
  _instanceof: TokenType
  _typeof: TokenType
  _void: TokenType
  _delete: TokenType
}

export interface Comment {
  type: "Line" | "Block"
  value: string
  start: number
  end: number
  loc?: SourceLocation
  range?: [number, number]
}

export class Token {
  type: TokenType
  start: number
  end: number
  loc?: SourceLocation
  range?: [number, number]
}

export const version: string