├── .nvmrc
├── dist
└── .keep
├── src
├── tests
│ ├── fixtures
│ │ ├── deprecated.js
│ │ ├── simple.js
│ │ ├── documented.js
│ │ ├── commented.js
│ │ └── everything.js
│ ├── snapshots
│ │ ├── attachComments.js.snap
│ │ ├── defaultTraveler.js.snap
│ │ ├── attachComments.js.md
│ │ └── defaultTraveler.js.md
│ ├── helpers
│ │ ├── parseFixture.js
│ │ └── parse.js
│ ├── attachComments.js
│ └── defaultTraveler.js
├── astravel.js
├── attachComments.js
└── defaultTraveler.js
├── .eslintignore
├── .travis.yml
├── .gitignore
├── .npmignore
├── .eslintrc.json
├── babel.config.js
├── astravel.sublime-project
├── CHANGELOG.md
├── LICENSE
├── examples
└── localVariables.js
├── package.json
└── README.md
/.nvmrc:
--------------------------------------------------------------------------------
1 | 16
--------------------------------------------------------------------------------
/dist/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/tests/fixtures/deprecated.js:
--------------------------------------------------------------------------------
1 | with (object) {
2 | }
3 |
--------------------------------------------------------------------------------
/src/tests/fixtures/simple.js:
--------------------------------------------------------------------------------
1 | function f() {
2 | return 1
3 | }
4 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | node_modules/*
2 | local/*
3 | vendor/*
4 | dist/*
5 | src/tests/fixtures/*
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - 12
4 | - 14
5 |
6 | after_success:
7 | - npx codecov --file=./coverage/lcov.info
8 |
--------------------------------------------------------------------------------
/src/tests/snapshots/attachComments.js.snap:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidbonnet/astravel/HEAD/src/tests/snapshots/attachComments.js.snap
--------------------------------------------------------------------------------
/src/tests/snapshots/defaultTraveler.js.snap:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidbonnet/astravel/HEAD/src/tests/snapshots/defaultTraveler.js.snap
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.DS_Store
2 | *.sublime-workspace
3 | test/_*.js
4 | .nyc_output
5 | coverage
6 | dist
7 | local
8 | node_modules
9 | npm-debug.log
10 | .nova
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | *.sublime-project
2 | *.sublime-workspace
3 | .babelrc
4 | .eslintignore
5 | .eslintrc.js
6 | .gitignore
7 | .travis.yml
8 | coverage/
9 | dist/.keep
10 | local/
11 | node_modules/
12 | package-lock.json
13 | src/tests/
--------------------------------------------------------------------------------
/src/tests/helpers/parseFixture.js:
--------------------------------------------------------------------------------
1 | import { join } from 'path'
2 |
3 | import { parse } from './parse'
4 |
5 | const DIRNAME = join(__dirname, '../fixtures')
6 |
7 | export async function parseFixture(fileName, options) {
8 | return await parse(join(DIRNAME, fileName), options)
9 | }
10 |
--------------------------------------------------------------------------------
/src/tests/attachComments.js:
--------------------------------------------------------------------------------
1 | import test from 'ava'
2 |
3 | import { parseFixture } from './helpers/parseFixture'
4 | import { attachComments } from '../attachComments'
5 |
6 | test('Comments attachment', async (assert) => {
7 | const comments = []
8 | const ast = await parseFixture('commented.js', {
9 | ranges: true,
10 | onComment: comments,
11 | })
12 | assert.snapshot(comments)
13 | attachComments(ast, comments)
14 | assert.snapshot(ast)
15 | })
16 |
--------------------------------------------------------------------------------
/src/tests/fixtures/documented.js:
--------------------------------------------------------------------------------
1 | export function f(a, b) {
2 | /*
3 | Documentation for function `f` with params `a` and `b`.
4 | */
5 | return a + b
6 | }
7 |
8 | export function privateFunction() {}
9 |
10 | export function g() {
11 | /*
12 | Documentation for function `g`.
13 | */
14 | }
15 |
16 | export class A {
17 | /*
18 | Documentation for class A.
19 | */
20 |
21 | m(x, y = true) {
22 | /*
23 | Document for method `m` with params `x` and `y`.
24 | */
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/tests/fixtures/commented.js:
--------------------------------------------------------------------------------
1 | /*
2 | Module documentation.
3 | */
4 |
5 | /*
6 | Documentation for variable `point`.
7 | */
8 | const point = {
9 | /* This is a block comment inside an object expression */
10 | // This comment is for the x property
11 | x: 0,
12 | // …and this one is for the y property
13 | y: 1,
14 | // Trailing comment
15 | }
16 |
17 | class A {
18 | /*
19 | Documentation for class A.
20 | */
21 |
22 | m(x, y = true) {
23 | /*
24 | Document for method `m` with params `x` and `y`.
25 | */
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/tests/helpers/parse.js:
--------------------------------------------------------------------------------
1 | import normalizeNewline from 'normalize-newline'
2 | import { parse as baseParse } from 'meriyah'
3 | import { readFile } from 'fs'
4 | import { promisify } from 'util'
5 |
6 | const readFileAsync = promisify(readFile)
7 |
8 | export async function parse(fileName, parserOptions = null) {
9 | const code = await readFileAsync(fileName, 'utf8')
10 | return baseParse(normalizeNewline(code), {
11 | module: true,
12 | jsx: true,
13 | specDeviation: true,
14 | next: true,
15 | ...parserOptions,
16 | })
17 | }
18 |
--------------------------------------------------------------------------------
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "plugins": ["import"],
3 | "extends": ["eslint:recommended", "plugin:import/errors", "prettier"],
4 | "env": {
5 | "es6": true
6 | },
7 | "parserOptions": {
8 | "ecmaVersion": 9,
9 | "sourceType": "module"
10 | },
11 | "globals": {
12 | "__dirname": true,
13 | "__filename": true,
14 | "clearInterval": true,
15 | "clearTimeout": true,
16 | "console": true,
17 | "document": true,
18 | "global": true,
19 | "module": true,
20 | "process": true,
21 | "require": true,
22 | "window": true
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/astravel.js:
--------------------------------------------------------------------------------
1 | // Astravel is tiny and fast ESTree-compliant AST walker and modifier.
2 | //
3 | // Astravel was written by David Bonnet and released under an MIT license.
4 | //
5 | // The Git repository for Astravel is available at:
6 | // https://github.com/davidbonnet/astravel.git
7 | //
8 | // Please use the GitHub bug tracker to report issues:
9 | // https://github.com/davidbonnet/astravel/issues
10 |
11 | import { defaultTraveler } from './defaultTraveler'
12 | export { attachComments } from './attachComments'
13 |
14 | export function makeTraveler(properties) {
15 | /*
16 | Returns a custom AST traveler that inherits from the `defaultTraveler` with its own provided `properties` and the property `super` that points to the parent traveler object.
17 | */
18 | return defaultTraveler.makeChild(properties)
19 | }
20 |
21 | export { defaultTraveler }
22 |
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = (api) => {
2 | api.cache.never()
3 | switch (process.env.BABEL_MODE) {
4 | case 'module':
5 | return {
6 | plugins: [
7 | [
8 | 'module-extension-resolver',
9 | {
10 | extensionsToKeep: ['.js', '.json'],
11 | },
12 | ],
13 | ],
14 | }
15 | default:
16 | return {
17 | plugins: [
18 | [
19 | '@babel/plugin-transform-runtime',
20 | {
21 | absoluteRuntime: false,
22 | corejs: false,
23 | helpers: true,
24 | regenerator: true,
25 | useESModules: false,
26 | },
27 | ],
28 | ],
29 | presets: [
30 | [
31 | '@babel/preset-env',
32 | {
33 | forceAllTransforms: true,
34 | },
35 | ],
36 | ],
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/astravel.sublime-project:
--------------------------------------------------------------------------------
1 | {
2 | "folders": [
3 | {
4 | "path": ".",
5 | "folder_exclude_patterns": ["node_modules", "coverage", ".nyc_output"]
6 | }
7 | ],
8 | "settings": {
9 | "folder_exclude_patterns": [".git", "node_modules", "dist"],
10 | "tab_size": 2,
11 | "js_prettier": {
12 | "auto_format_on_save": true,
13 | "auto_format_on_save_excludes": [
14 | "*/package.json",
15 | "*/dist/*",
16 | "*/node_modules/*",
17 | "*/.git/*"
18 | ],
19 | "allow_inline_formatting": true,
20 | "custom_file_extensions": ["sublime-project"],
21 | "additional_cli_args": {
22 | "--config": "package.json",
23 | "--config-precedence": "prefer-file"
24 | }
25 | }
26 | },
27 | "SublimeLinter": {
28 | "linters": {
29 | "eslint": {
30 | "disable": false
31 | },
32 | "flow": {
33 | "disable": true
34 | }
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Change Log
2 |
3 | All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4 |
5 |
6 | ## [0.6.1](https://github.com/davidbonnet/astravel/compare/v0.6.0...v0.6.1) (2021-11-21)
7 |
8 |
9 | ### Bug Fixes
10 |
11 | * package and exports ([97028b6](https://github.com/davidbonnet/astravel/commit/97028b6))
12 |
13 |
14 |
15 |
16 | # [0.6.0](https://github.com/davidbonnet/astravel/compare/v0.5.0...v0.6.0) (2021-11-21)
17 |
18 |
19 | ### Features
20 |
21 | * support es2022 ([#33](https://github.com/davidbonnet/astravel/issues/33)) ([3d5bea5](https://github.com/davidbonnet/astravel/commit/3d5bea5))
22 |
23 |
24 |
25 |
26 | # [0.5.0](https://github.com/davidbonnet/astravel/compare/v0.4.1...v0.5.0) (2018-06-23)
27 |
28 |
29 | ### Features
30 |
31 | * **ecmascript:** add support for 2019 version ([00a2cd7](https://github.com/davidbonnet/astravel/commit/00a2cd7))
32 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2015, David Bonnet
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in
11 | all copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | THE SOFTWARE.
--------------------------------------------------------------------------------
/src/tests/defaultTraveler.js:
--------------------------------------------------------------------------------
1 | import test from 'ava'
2 |
3 | import { parseFixture } from './helpers/parseFixture'
4 | import { defaultTraveler } from '../defaultTraveler'
5 |
6 | test('Default traveler', async (assert) => {
7 | const state = {
8 | tree: ['Root', []],
9 | }
10 | const ast = await parseFixture('everything.js')
11 | const customTraveler = defaultTraveler.makeChild({
12 | go(node, state) {
13 | const { tree } = state
14 | const child = [node.type, []]
15 | tree[1].push(child)
16 | state.tree = child
17 | this[node.type](node, state)
18 | state.tree = tree
19 | },
20 | })
21 | customTraveler.go(ast, state)
22 | assert.snapshot(state.tree)
23 | })
24 |
25 | test('Deprecated', async (assert) => {
26 | const ast = await parseFixture('deprecated.js', {
27 | module: false,
28 | impliedStrict: false,
29 | })
30 | defaultTraveler.go(ast)
31 | assert.pass()
32 | })
33 |
34 | test('Find node', async (assert) => {
35 | const ast = await parseFixture('simple.js')
36 | const type = 'ReturnStatement'
37 | const result = defaultTraveler.find((node) => node.type === type, ast)
38 | assert.truthy(result)
39 | assert.truthy(result.node)
40 | assert.is(result.node.type, type)
41 | })
42 |
43 | test('Find node throws error', (assert) => {
44 | assert.throws(() => defaultTraveler.find(), { instanceOf: TypeError })
45 | })
46 |
--------------------------------------------------------------------------------
/examples/localVariables.js:
--------------------------------------------------------------------------------
1 | /*
2 | This example shows how to retrieve a list of local variable names.
3 | */
4 |
5 | var acorn = require( 'acorn' )
6 | var astravel = require( '../dist/astravel.debug' )
7 |
8 | var ignore = Function.prototype
9 |
10 | var traveler = astravel.makeTraveler( {
11 | FunctionDeclaration: function( node, state ) {
12 | state.names.push( node.id.name )
13 | },
14 | BlockStatement: function( node, state ) {
15 | if ( !state.inBlock ) {
16 | state.inBlock = true
17 | this.super.BlockStatement.call( this, node, state )
18 | state.inBlock = false
19 | } else {
20 | this.super.BlockStatement.call( this, node, state )
21 | }
22 | },
23 | VariableDeclaration: function( node, state ) {
24 | if ( ( state.inBlock && node.kind === 'var' ) || !state.inBlock ) {
25 | state.inDeclaration = true
26 | this.super.VariableDeclaration.call( this, node, state )
27 | state.inDeclaration = false
28 | }
29 | },
30 | VariableDeclarator: function( node, state ) {
31 | this.go( node.id, state )
32 | },
33 | ObjectPattern: function( node, state ) {
34 | if ( state.inDeclaration ) this.super.ObjectPattern.call( this, node, state )
35 | },
36 | ArrayPattern: function( node, state ) {
37 | if ( state.inDeclaration ) this.super.ArrayPattern.call( this, node, state )
38 | },
39 | Property: function( node, state ) {
40 | if ( state.inDeclaration ) this.go( node.value, state )
41 | },
42 | Identifier: function( node, state ) {
43 | if ( state.inDeclaration ) state.names.push( node.name )
44 | },
45 | FunctionExpression: ignore,
46 | ArrowFunctionExpression: ignore
47 | })
48 |
49 | function getLocalVariableNames( ast ) {
50 | var state = {
51 | inBlock: false,
52 | inDeclaration: false,
53 | names: []
54 | }
55 | traveler.go( ast, state )
56 | // Filter duplicate names
57 | return state.names.filter( function( value, index, list ) {
58 | return list.indexOf( value ) === index
59 | } )
60 | }
61 |
62 | var code = [
63 | "var a = 1, b = 2;",
64 | "var a = 1;",
65 | "let {x, y} = {x: 0, y: 0};",
66 | "const Y = 4",
67 | "function add(a, b) {return a + b;}",
68 | "if (a > b) {",
69 | " let c = 5;",
70 | " var [d] = someArray, {e: f} = someObject;",
71 | "}",
72 | "g = a + b;"
73 | ].join( "\n" ) + "\n"
74 |
75 | var ast = acorn.parse( code, { ecmaVersion: 6 } )
76 |
77 | console.log( code )
78 | console.log( 'Local variables:', getLocalVariableNames( ast ).join( ', ' ) )
79 |
80 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "astravel",
3 | "version": "0.6.1",
4 | "description": "ESTree-compliant AST walker and modifier.",
5 | "main": "./dist/require/astravel.js",
6 | "module": "./dist/module/astravel.js",
7 | "exports": {
8 | "import": "./dist/module/astravel.js",
9 | "require": "./dist/require/astravel.js"
10 | },
11 | "scripts": {
12 | "prepare": "rm -rf dist/*; babel --config-file ./babel.config.js --no-comments --source-maps --out-dir dist/require --ignore \"**/tests/**/*.js\" src; cross-env BABEL_MODE=module babel --config-file ./babel.config.js --no-comments --source-maps --out-dir dist/module --ignore \"**/tests/**/*.js\" src",
13 | "dev": "ava --watch",
14 | "dev:update": "ava --watch --update-snapshots",
15 | "test": "npm run eslint && npm run prettier:check && npm run test:coverage",
16 | "test:coverage": "c8 --reporter=html --reporter=text --reporter=lcov --include='src/*.js' --exclude='src/tests/**/*.js' ava",
17 | "eslint": "eslint src/",
18 | "prettier": "prettier --write \"src/*.js\" \"src/tests/*.js\" \"src/tests/helpers/*.js\"",
19 | "prettier:check": "prettier --list-different \"src/*.js\" \"src/tests/*.js\" \"src/tests/helpers/*.js\"",
20 | "prepush": "npm test",
21 | "release": "standard-version",
22 | "deploy": "git push --follow-tags origin master && npm publish",
23 | "release:deploy": "npm run release && npm run deploy"
24 | },
25 | "keywords": [
26 | "ast",
27 | "ast walker",
28 | "ast traveler",
29 | "ast modifier",
30 | "estree",
31 | "astring"
32 | ],
33 | "repository": {
34 | "type": "git",
35 | "url": "https://github.com/davidbonnet/astravel.git"
36 | },
37 | "author": "David Bonnet ",
38 | "license": "MIT",
39 | "devDependencies": {
40 | "@babel/cli": "^7.11.6",
41 | "@babel/core": "^7.11.6",
42 | "@babel/plugin-transform-runtime": "^7.11.5",
43 | "@babel/preset-env": "^7.11.5",
44 | "@babel/runtime": "^7.11.2",
45 | "astring": "^1.4.3",
46 | "ava": "^3.12.1",
47 | "babel-plugin-module-extension-resolver": "^1.0.0-rc.2",
48 | "c8": "^7.3.0",
49 | "codecov": "^3.7.2",
50 | "cross-env": "^7.0.2",
51 | "eslint": "^7.9.0",
52 | "eslint-config-prettier": "^6.11.0",
53 | "eslint-plugin-import": "^2.22.0",
54 | "esm": "^3.2.25",
55 | "exorcist": "^1.0.1",
56 | "husky": "^4.3.0",
57 | "meriyah": "^2.1.1",
58 | "normalize-newline": "^3.0.0",
59 | "prettier": "^2.1.2",
60 | "standard-version": "^4.4.0"
61 | },
62 | "prettier": {
63 | "arrowParens": "always",
64 | "bracketSpacing": true,
65 | "printWidth": 80,
66 | "semi": false,
67 | "singleQuote": true,
68 | "tabWidth": 2,
69 | "trailingComma": "all",
70 | "useTabs": false
71 | },
72 | "ava": {
73 | "files": [
74 | "src/**/tests/*.js"
75 | ],
76 | "require": [
77 | "esm"
78 | ]
79 | },
80 | "esm": "auto"
81 | }
82 |
--------------------------------------------------------------------------------
/src/tests/fixtures/everything.js:
--------------------------------------------------------------------------------
1 | import a from 'a'
2 | import b, { c } from 'b'
3 | import { d as e } from 'c'
4 | import * as f from 'd'
5 |
6 | export { g } from 'd'
7 | export const h = a
8 | export * from 'e'
9 |
10 | export default class Class {
11 | constructor() {
12 | this.bound = () => {}
13 | this.otherBound = a => ({})
14 | }
15 | static s() {}
16 | m() {
17 | new.target
18 | this.isEverything = 42
19 | }
20 | }
21 |
22 | const ClassExpression = class extends Class {}
23 |
24 | function callable(a, b, c = 42) {
25 | let d = a
26 | var e = b
27 | const f = c
28 | const { g, h, i } = e
29 | const [j, k, l] = array
30 | return c === 42 ? a : b
31 | }
32 |
33 | function* generator() {
34 | yield
35 | yield 42
36 | }
37 |
38 | async function asyncFunction() {
39 | return await answer()
40 | }
41 |
42 | async function asyncLoop() {
43 | for await (const x of generator) {
44 | }
45 | }
46 |
47 | function branches() {
48 | if (a > 0) {
49 | callable(...a)
50 | } else if (a < 0) {
51 | callable(1)
52 | } else {
53 | callable(2)
54 | }
55 | if (a == 0) {
56 | }
57 | label: switch (a) {
58 | case 1:
59 | break label
60 | default:
61 | break
62 | }
63 | return
64 | }
65 |
66 | function loops() {
67 | otherLabel: for (let i = 0; i < a.length; i++) {
68 | if (i < 10) {
69 | continue otherLabel
70 | } else {
71 | continue
72 | }
73 | }
74 | for (;;) {}
75 | for (let name in object) {
76 | }
77 | for (let name of array) {
78 | }
79 | while (i < 0) {}
80 | do {} while (i < 0)
81 | }
82 |
83 | function exceptions() {
84 | try {
85 | throw new Error()
86 | } catch (error) {
87 | callable(error)
88 | } finally {
89 | callable(42)
90 | }
91 | try {
92 | } catch (error) {}
93 | try {
94 | } catch {}
95 | }
96 |
97 | function patterns() {
98 | const { a, [b]: c, ...rest } = object
99 | const [d, e] = array
100 | }
101 |
102 | const instance = new Class()
103 |
104 | const data = {
105 | a,
106 | b: c,
107 | m() {},
108 | ...d,
109 | }
110 |
111 | const object = {
112 | a: 42,
113 | b: '42',
114 | c: 1 + 1,
115 | d: 2 * 2,
116 | f: 2 / 2,
117 | g: 3 - 2,
118 | h: 2 % 2,
119 | i: 1.5 | 0,
120 | j: 1 ^ 2,
121 | k: 1 & 2,
122 | l: 'test' in data,
123 | m: 1 == 2,
124 | n: 1 != 2,
125 | o: 1 === 2,
126 | p: 1 !== 2,
127 | q: 1 instanceof Number,
128 | r: 1 || 2,
129 | s: 1 && 2,
130 | t: (1, 2),
131 | u: 1 > 2,
132 | v: 1 < 2,
133 | w: 1 >= 2,
134 | x: 1 <= 2,
135 | y: 42 ** 2,
136 | }
137 |
138 | object.a = 42
139 | object.a += 42
140 | object.a -= 42
141 | object.a *= 42
142 | object.a /= 42
143 | object.a %= 1
144 | object.a++
145 | ++object.a
146 | object.a--
147 | --object.a
148 | object.a = -object.a
149 | object.a **= 2
150 |
151 | const array = [1, 2, 3, , 4, ...a]
152 |
153 | const template = `Answer is ${42}`
154 |
155 | const formattedTemplate = format`Answer is ${a}`
156 |
--------------------------------------------------------------------------------
/src/attachComments.js:
--------------------------------------------------------------------------------
1 | import { defaultTraveler } from './defaultTraveler'
2 |
3 | function attachCommentsToNode(
4 | traveler,
5 | state,
6 | parent,
7 | children,
8 | findHeadingComments,
9 | ) {
10 | let { index } = state
11 | const { comments } = state
12 | let comment = comments[index]
13 | // Hack to tackle https://github.com/babel/minify/issues/866
14 | let boundComments, trailingComments
15 | if (comment == null) {
16 | return
17 | }
18 | if (children == null || children.length === 0) {
19 | // No children, attach comments to parent
20 | boundComments = parent.comments != null ? parent.comments : []
21 | while (comment != null && comment.end <= parent.end) {
22 | boundComments.push(comment)
23 | comment = comments[++index]
24 | }
25 | state.index = index
26 | if (boundComments.length !== 0 && parent.comments == null) {
27 | parent.comments = boundComments
28 | }
29 | return
30 | }
31 | // Look for heading block comments not immediately followed by a child
32 | if (findHeadingComments) {
33 | boundComments = parent.comments != null ? parent.comments : []
34 | const { start } = children[0]
35 | while (
36 | comment != null &&
37 | (comment.type[0] === 'B' || comment.type[0] === 'M') &&
38 | comment.end <= start
39 | ) {
40 | boundComments.push(comment)
41 | comment = comments[++index]
42 | }
43 | if (boundComments.length !== 0 && parent.comments == null)
44 | parent.comments = boundComments
45 | }
46 | // Attach comments to children
47 | for (let i = 0, { length } = children; comment != null && i < length; i++) {
48 | const child = children[i]
49 | boundComments = []
50 | while (comment != null && comment.end <= child.start) {
51 | boundComments.push(comment)
52 | comment = comments[++index]
53 | }
54 | // Check if next comment is line comment and on the same line if location is provided
55 | if (
56 | comment != null &&
57 | comment.loc != null &&
58 | (comment.type[0] === 'L' || comment.type[0] === 'S')
59 | ) {
60 | if (comment.loc.start.line === child.loc.end.line) {
61 | boundComments.push(comment)
62 | comment = comments[++index]
63 | }
64 | }
65 | if (boundComments.length !== 0) {
66 | child.comments = boundComments
67 | }
68 | // Travel through child
69 | state.index = index
70 | traveler[child.type](child, state)
71 | index = state.index
72 | comment = comments[index]
73 | }
74 | // Look for remaining comments
75 | trailingComments = []
76 | while (comment != null && comment.end <= parent.end) {
77 | trailingComments.push(comment)
78 | comment = comments[++index]
79 | }
80 | if (trailingComments.length !== 0) {
81 | parent.trailingComments = trailingComments
82 | }
83 | state.index = index
84 | }
85 |
86 | function Block(node, state) {
87 | attachCommentsToNode(this, state, node, node.body, true)
88 | }
89 |
90 | let traveler = defaultTraveler.makeChild({
91 | Program: Block,
92 | BlockStatement: Block,
93 | ClassBody: Block,
94 | ObjectExpression(node, state) {
95 | attachCommentsToNode(this, state, node, node.properties, true)
96 | },
97 | ArrayExpression(node, state) {
98 | attachCommentsToNode(this, state, node, node.elements, true)
99 | },
100 | SwitchStatement(node, state) {
101 | attachCommentsToNode(this, state, node, node.cases, false)
102 | },
103 | SwitchCase(node, state) {
104 | attachCommentsToNode(this, state, node, node.consequent, false)
105 | },
106 | // TODO: Consider ArrayExpression ?
107 | })
108 |
109 | export function attachComments(node, comments) {
110 | /*
111 | Modifies in-place the AST starting at `node` by attaching the provided `comments` and returns that AST.
112 | */
113 | traveler[node.type](node, {
114 | comments,
115 | index: 0,
116 | })
117 | return node
118 | }
119 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Astravel
2 |
3 | [](https://www.npmjs.org/package/astravel)
4 | [](https://travis-ci.org/davidbonnet/astravel)
5 | [](https://codecov.io/gh/davidbonnet/astravel)
6 | [](https://david-dm.org/davidbonnet/astravel#info=devDependencies)
7 | [](https://greenkeeper.io/)
8 |
9 | 👟 A tiny and fast [ESTree](https://github.com/estree/estree)-compliant AST walker and modifier.
10 |
11 | ### Key features
12 |
13 | - Works on [ESTree](https://github.com/estree/estree)-compliant ASTs (JavaScript [version 13 (2022)](https://tc39.github.io/ecma262/)), such as the ones produced by [Meriyah](https://github.com/meriyah/meriyah).
14 | - Out-of-the-box functions such as source code comments insertion for [Astring](https://github.com/davidbonnet/astring).
15 | - Extensible with custom nodes.
16 | - No dependencies and small footprint.
17 |
18 | ## Installation
19 |
20 | Install with the [Node Package Manager](https://www.npmjs.com/package/astravel):
21 |
22 | ```bash
23 | npm install astravel
24 | ```
25 |
26 | Alternatively, checkout this repository and install the development dependencies to build the module file:
27 |
28 | ```bash
29 | git clone https://github.com/davidbonnet/astravel.git
30 | cd astravel
31 | npm install
32 | ```
33 |
34 | ## Usage
35 |
36 | The `astravel` module exports the following items:
37 |
38 |
39 |
40 | - [`defaultTraveler`](#defaulttraveler)
41 | - [`makeTraveler()`](#maketraveler)
42 | - [`attachComments()`](#attachcomments)
43 |
44 |
45 |
46 | #### `defaultTraveler`
47 |
48 | > ⬅️ `traveler`
49 |
50 | > ⚠️ Deprecated in favor of ES6 class notation.
51 |
52 | This object describes a basic AST traveler. It contains the following methods:
53 |
54 | - `go(node, state)`: Travels through the provided AST `node` with a given `state` (an object that can be of any type) by recursively calling this method.
55 | - `find(predicate, node, state) ➞ { node, state }?`: Returns `{ node, state }` for which `predicate(node, state)` returns truthy, starting at the specified AST `node` and with the provided `state`. Otherwise, returns `undefined`.
56 | - `[NodeType](node, state)`: Method handler for a specific `NodeType`.
57 | - `makeChild(properties) ➞ traveler`: Returns a custom AST traveler that inherits from `this` traveler with its own provided `properties` and the property `super` that points to `this` traveler.
58 |
59 | #### `makeTraveler()`
60 |
61 | > ➡️ `(properties)`
62 | > ⬅️ `traveler`
63 |
64 | > ⚠️ Deprecated in favor of ES6 class notation.
65 |
66 | This function is similar to `astravel.defaultTraveler.makeChild`: it returns a traveler that inherits from the `defaultTraveler` with its own provided `properties` and the property `super` that points to the `defaultTraveler` object. These properties should redefine the traveler's behavior by implementing the `go(node, state)` method and/or any node handler.
67 |
68 | When redefining the `go` method, make sure its basic functionality is kept by calling the parent's `go` method to keep traveling through the AST:
69 |
70 | ```javascript
71 | const customTraveler = makeTraveler({
72 | go: function (node, state) {
73 | // Code before entering the node
74 | console.log('Entering ' + node.type)
75 | // Call the parent's `go` method
76 | this.super.go.call(this, node, state)
77 | // Code after leaving the node
78 | console.log('Leaving ' + node.type)
79 | },
80 | })
81 | ```
82 |
83 | To skip specific node types, the most effective way is to replace the corresponding node handlers with a function that does nothing:
84 |
85 | ```javascript
86 | import { makeTraveler } from 'astravel'
87 |
88 | const ignore = Function.prototype
89 | const customTraveler = makeTraveler({
90 | FunctionDeclaration: ignore,
91 | FunctionExpression: ignore,
92 | ArrowFunctionExpression: ignore,
93 | })
94 | ```
95 |
96 | #### `attachComments()`
97 |
98 | > ➡️ `(ast, comments)`
99 | > ⬅️ `ast`
100 |
101 | This function attaches a list of `comments` to the corresponding nodes of a provided `ast` and returns that same `ast`. The `ast` is modified in-place and only the nodes getting comments are augmented with a `comments` and/or a `trailingComments` array property.
102 |
103 | Each comment should be an object with the following properties:
104 |
105 | - `type`: `"Line"` or `"Block"`
106 | - `value`: Comment string value
107 | - `start`: Comment starting character offset number
108 | - `end`: Comment ending character offset number
109 | - `loc`: Location object with `start` and `end` properties containing one-based `line` number and zero-based `column` number properties.
110 |
111 | The following examples show how to obtain a proper list of `comments` of a given source `code` and how to attach them on the generated `ast`:
112 |
113 | ##### Usage with [Meriyah](https://github.com/meriyah/meriyah)
114 |
115 | ```javascript
116 | import { parse } from 'meriyah'
117 | import { attachComments } from 'astravel'
118 |
119 | const comments = []
120 | const ast = parse(code, {
121 | // Comments are stored in this array
122 | onComment: comments,
123 | })
124 | // Attach comments on the AST
125 | attachComments(ast, comments)
126 | ```
127 |
128 | ##### Usage with [Acorn](https://github.com/acornjs/acorn)
129 |
130 | ```javascript
131 | import { parse } from 'acorn'
132 | import { attachComments } from 'astravel'
133 |
134 | const comments = []
135 | const ast = parse(code, {
136 | // This ensures that the `loc` property is present on comment objects
137 | locations: true,
138 | onComment: comments,
139 | })
140 | attachComments(ast, comments)
141 | ```
142 |
143 | The algorithm assumes that comments are not put in exotic places, such as in-between function arguments, and proceeds as follows:
144 |
145 | - For a given statement, it stores all comments right above it and on the same line to it's right side in a `comments` property.
146 | - If a comment block is at the beginning of a code block, it is attached to that code block.
147 | - Comments not followed by any statement in a code block are attached as `trailingComments` to that code block.
148 |
149 | In this example, the comments tell to which statement they are attached:
150 |
151 | ```javascript
152 | // Attached to the variable declaration just below
153 | const point = {
154 | // Attached to the property definition just below
155 | x: 0,
156 | y: 0, // Attached to the property definition on its left
157 | }
158 | /*
159 | Attached to the function declaration just below.
160 | */
161 | function add(a, b) {
162 | /*
163 | Attached to the function body because it is the first comment block.
164 | */
165 | return a + b // Attached to the return statement on its left
166 | // Trailing comment attached as such to the function body
167 | }
168 | // Trailing comment attached as such to the program body
169 | ```
170 |
--------------------------------------------------------------------------------
/src/defaultTraveler.js:
--------------------------------------------------------------------------------
1 | let ForInStatement,
2 | FunctionDeclaration,
3 | RestElement,
4 | BinaryExpression,
5 | ArrayExpression,
6 | Block,
7 | MethodDefinition
8 |
9 | const ignore = Function.prototype
10 |
11 | class Found {
12 | constructor(node, state) {
13 | this.node = node
14 | this.state = state
15 | }
16 | }
17 |
18 | export const defaultTraveler = {
19 | go(node, state) {
20 | /*
21 | Starts travelling through the specified AST `node` with the provided `state`.
22 | This method is recursively called by each node handler.
23 | */
24 | if (this[node.type]) {
25 | this[node.type](node, state)
26 | }
27 | },
28 | find(predicate, node, state) {
29 | /*
30 | Returns { node, state } for which `predicate(node, state)` returns truthy,
31 | starting at the specified AST `node` and with the provided `state`.
32 | Otherwise, returns `undefined`.
33 | */
34 | const finder = Object.create(this)
35 | finder.go = function (node, state) {
36 | if (predicate(node, state)) {
37 | throw new Found(node, state)
38 | }
39 | this[node.type](node, state)
40 | }
41 | try {
42 | finder.go(node, state)
43 | } catch (error) {
44 | if (error instanceof Found) {
45 | return error
46 | } else {
47 | throw error
48 | }
49 | }
50 | },
51 | makeChild(properties = {}) {
52 | /*
53 | Returns a custom AST traveler that inherits from `this` traveler with its own provided `properties` and the property `super` that points to the parent traveler object.
54 | */
55 | const traveler = Object.create(this)
56 | traveler.super = this
57 | for (let key in properties) {
58 | traveler[key] = properties[key]
59 | }
60 | return traveler
61 | },
62 | Program: (Block = function (node, state) {
63 | const { body } = node
64 | if (body != null) {
65 | const { length } = body
66 | for (let i = 0; i < length; i++) {
67 | this.go(body[i], state)
68 | }
69 | }
70 | }),
71 | BlockStatement: Block,
72 | StaticBlock: Block,
73 | EmptyStatement: ignore,
74 | ExpressionStatement(node, state) {
75 | this.go(node.expression, state)
76 | },
77 | IfStatement(node, state) {
78 | this.go(node.test, state)
79 | this.go(node.consequent, state)
80 | if (node.alternate != null) {
81 | this.go(node.alternate, state)
82 | }
83 | },
84 | LabeledStatement(node, state) {
85 | this.go(node.label, state)
86 | this.go(node.body, state)
87 | },
88 | BreakStatement(node, state) {
89 | if (node.label) {
90 | this.go(node.label, state)
91 | }
92 | },
93 | ContinueStatement(node, state) {
94 | if (node.label) {
95 | this.go(node.label, state)
96 | }
97 | },
98 | WithStatement(node, state) {
99 | this.go(node.object, state)
100 | this.go(node.body, state)
101 | },
102 | SwitchStatement(node, state) {
103 | this.go(node.discriminant, state)
104 | const { cases } = node,
105 | { length } = cases
106 | for (let i = 0; i < length; i++) {
107 | this.go(cases[i], state)
108 | }
109 | },
110 | SwitchCase(node, state) {
111 | if (node.test != null) {
112 | this.go(node.test, state)
113 | }
114 | const statements = node.consequent,
115 | { length } = statements
116 | for (let i = 0; i < length; i++) {
117 | this.go(statements[i], state)
118 | }
119 | },
120 | ReturnStatement(node, state) {
121 | if (node.argument) {
122 | this.go(node.argument, state)
123 | }
124 | },
125 | ThrowStatement(node, state) {
126 | this.go(node.argument, state)
127 | },
128 | TryStatement(node, state) {
129 | this.go(node.block, state)
130 | if (node.handler != null) {
131 | this.go(node.handler, state)
132 | }
133 | if (node.finalizer != null) {
134 | this.go(node.finalizer, state)
135 | }
136 | },
137 | CatchClause(node, state) {
138 | if (node.param != null) {
139 | this.go(node.param, state)
140 | }
141 | this.go(node.body, state)
142 | },
143 | WhileStatement(node, state) {
144 | this.go(node.test, state)
145 | this.go(node.body, state)
146 | },
147 | DoWhileStatement(node, state) {
148 | this.go(node.body, state)
149 | this.go(node.test, state)
150 | },
151 | ForStatement(node, state) {
152 | if (node.init != null) {
153 | this.go(node.init, state)
154 | }
155 | if (node.test != null) {
156 | this.go(node.test, state)
157 | }
158 | if (node.update != null) {
159 | this.go(node.update, state)
160 | }
161 | this.go(node.body, state)
162 | },
163 | ForInStatement: (ForInStatement = function (node, state) {
164 | this.go(node.left, state)
165 | this.go(node.right, state)
166 | this.go(node.body, state)
167 | }),
168 | DebuggerStatement: ignore,
169 | FunctionDeclaration: (FunctionDeclaration = function (node, state) {
170 | if (node.id != null) {
171 | this.go(node.id, state)
172 | }
173 | const { params } = node
174 | if (params != null) {
175 | for (let i = 0, { length } = params; i < length; i++) {
176 | this.go(params[i], state)
177 | }
178 | }
179 | this.go(node.body, state)
180 | }),
181 | VariableDeclaration(node, state) {
182 | const { declarations } = node,
183 | { length } = declarations
184 | for (let i = 0; i < length; i++) {
185 | this.go(declarations[i], state)
186 | }
187 | },
188 | VariableDeclarator(node, state) {
189 | this.go(node.id, state)
190 | if (node.init != null) {
191 | this.go(node.init, state)
192 | }
193 | },
194 | ArrowFunctionExpression(node, state) {
195 | const { params } = node
196 | if (params != null) {
197 | for (let i = 0, { length } = params; i < length; i++) {
198 | this.go(params[i], state)
199 | }
200 | }
201 | this.go(node.body, state)
202 | },
203 | ThisExpression: ignore,
204 | ArrayExpression: (ArrayExpression = function (node, state) {
205 | const { elements } = node,
206 | { length } = elements
207 | for (let i = 0; i < length; i++) {
208 | let element = elements[i]
209 | if (element != null) {
210 | this.go(elements[i], state)
211 | }
212 | }
213 | }),
214 | ObjectExpression(node, state) {
215 | const { properties } = node,
216 | { length } = properties
217 | for (let i = 0; i < length; i++) {
218 | this.go(properties[i], state)
219 | }
220 | },
221 | Property(node, state) {
222 | this.go(node.key, state)
223 | if (node.value != null) {
224 | this.go(node.value, state)
225 | }
226 | },
227 | FunctionExpression: FunctionDeclaration,
228 | SequenceExpression(node, state) {
229 | const { expressions } = node,
230 | { length } = expressions
231 | for (let i = 0; i < length; i++) {
232 | this.go(expressions[i], state)
233 | }
234 | },
235 | UnaryExpression(node, state) {
236 | this.go(node.argument, state)
237 | },
238 | UpdateExpression(node, state) {
239 | this.go(node.argument, state)
240 | },
241 | AssignmentExpression(node, state) {
242 | this.go(node.left, state)
243 | this.go(node.right, state)
244 | },
245 | BinaryExpression: (BinaryExpression = function (node, state) {
246 | this.go(node.left, state)
247 | this.go(node.right, state)
248 | }),
249 | LogicalExpression: BinaryExpression,
250 | ConditionalExpression(node, state) {
251 | this.go(node.test, state)
252 | this.go(node.consequent, state)
253 | this.go(node.alternate, state)
254 | },
255 | NewExpression(node, state) {
256 | this.CallExpression(node, state)
257 | },
258 | CallExpression(node, state) {
259 | this.go(node.callee, state)
260 | const args = node['arguments'],
261 | { length } = args
262 | for (let i = 0; i < length; i++) {
263 | this.go(args[i], state)
264 | }
265 | },
266 | MemberExpression(node, state) {
267 | this.go(node.object, state)
268 | this.go(node.property, state)
269 | },
270 | Identifier: ignore,
271 | PrivateIdentifier: ignore,
272 | Literal: ignore,
273 | ForOfStatement: ForInStatement,
274 | ClassDeclaration(node, state) {
275 | if (node.id) {
276 | this.go(node.id, state)
277 | }
278 | if (node.superClass) {
279 | this.go(node.superClass, state)
280 | }
281 | this.go(node.body, state)
282 | },
283 | ClassBody: Block,
284 | ImportDeclaration(node, state) {
285 | const { specifiers } = node,
286 | { length } = specifiers
287 | for (let i = 0; i < length; i++) {
288 | this.go(specifiers[i], state)
289 | }
290 | this.go(node.source, state)
291 | },
292 | ImportNamespaceSpecifier(node, state) {
293 | this.go(node.local, state)
294 | },
295 | ImportDefaultSpecifier(node, state) {
296 | this.go(node.local, state)
297 | },
298 | ImportSpecifier(node, state) {
299 | this.go(node.imported, state)
300 | this.go(node.local, state)
301 | },
302 | ExportDefaultDeclaration(node, state) {
303 | this.go(node.declaration, state)
304 | },
305 | ExportNamedDeclaration(node, state) {
306 | if (node.declaration) {
307 | this.go(node.declaration, state)
308 | }
309 | const { specifiers } = node,
310 | { length } = specifiers
311 | for (let i = 0; i < length; i++) {
312 | this.go(specifiers[i], state)
313 | }
314 | if (node.source) {
315 | this.go(node.source, state)
316 | }
317 | },
318 | ExportSpecifier(node, state) {
319 | this.go(node.local, state)
320 | this.go(node.exported, state)
321 | },
322 | ExportAllDeclaration(node, state) {
323 | this.go(node.source, state)
324 | },
325 | MethodDefinition: (MethodDefinition = function (node, state) {
326 | this.go(node.key, state)
327 | this.go(node.value, state)
328 | }),
329 | PropertyDefinition: MethodDefinition,
330 | ClassExpression(node, state) {
331 | this.ClassDeclaration(node, state)
332 | },
333 | Super: ignore,
334 | RestElement: (RestElement = function (node, state) {
335 | this.go(node.argument, state)
336 | }),
337 | SpreadElement: RestElement,
338 | YieldExpression(node, state) {
339 | if (node.argument) {
340 | this.go(node.argument, state)
341 | }
342 | },
343 | TaggedTemplateExpression(node, state) {
344 | this.go(node.tag, state)
345 | this.go(node.quasi, state)
346 | },
347 | TemplateLiteral(node, state) {
348 | const { quasis, expressions } = node
349 | for (let i = 0, { length } = expressions; i < length; i++) {
350 | this.go(expressions[i], state)
351 | }
352 | for (let i = 0, { length } = quasis; i < length; i++) {
353 | this.go(quasis[i], state)
354 | }
355 | },
356 | TemplateElement: ignore,
357 | ObjectPattern(node, state) {
358 | const { properties } = node,
359 | { length } = properties
360 | for (let i = 0; i < length; i++) {
361 | this.go(properties[i], state)
362 | }
363 | },
364 | ArrayPattern: ArrayExpression,
365 | AssignmentPattern(node, state) {
366 | this.go(node.left, state)
367 | this.go(node.right, state)
368 | },
369 | MetaProperty(node, state) {
370 | this.go(node.meta, state)
371 | this.go(node.property, state)
372 | },
373 | AwaitExpression(node, state) {
374 | this.go(node.argument, state)
375 | },
376 | }
377 |
--------------------------------------------------------------------------------
/src/tests/snapshots/attachComments.js.md:
--------------------------------------------------------------------------------
1 | # Snapshot report for `src/tests/attachComments.js`
2 |
3 | The actual snapshot is saved in `attachComments.js.snap`.
4 |
5 | Generated by [AVA](https://avajs.dev).
6 |
7 | ## Comments attachment
8 |
9 | > Snapshot 1
10 |
11 | [
12 | {
13 | end: 27,
14 | range: [
15 | 2,
16 | 27,
17 | ],
18 | start: 2,
19 | type: 'MultiLine',
20 | value: `␊
21 | Module documentation.␊
22 | `,
23 | },
24 | {
25 | end: 70,
26 | range: [
27 | 31,
28 | 70,
29 | ],
30 | start: 31,
31 | type: 'MultiLine',
32 | value: `␊
33 | Documentation for variable `point`.␊
34 | `,
35 | },
36 | {
37 | end: 146,
38 | range: [
39 | 91,
40 | 146,
41 | ],
42 | start: 91,
43 | type: 'MultiLine',
44 | value: ' This is a block comment inside an object expression ',
45 | },
46 | {
47 | end: 187,
48 | range: [
49 | 151,
50 | 187,
51 | ],
52 | start: 151,
53 | type: 'SingleLine',
54 | value: ` This comment is for the x property␊
55 | `,
56 | },
57 | {
58 | end: 236,
59 | range: [
60 | 199,
61 | 236,
62 | ],
63 | start: 199,
64 | type: 'SingleLine',
65 | value: ` …and this one is for the y property␊
66 | `,
67 | },
68 | {
69 | end: 266,
70 | range: [
71 | 248,
72 | 266,
73 | ],
74 | start: 248,
75 | type: 'SingleLine',
76 | value: ` Trailing comment␊
77 | `,
78 | },
79 | {
80 | end: 315,
81 | range: [
82 | 283,
83 | 315,
84 | ],
85 | start: 283,
86 | type: 'MultiLine',
87 | value: `␊
88 | Documentation for class A.␊
89 | `,
90 | },
91 | {
92 | end: 398,
93 | range: [
94 | 342,
95 | 398,
96 | ],
97 | start: 342,
98 | type: 'MultiLine',
99 | value: `␊
100 | Document for method `m` with params `x` and `y`.␊
101 | `,
102 | },
103 | ]
104 |
105 | > Snapshot 2
106 |
107 | {
108 | body: [
109 | {
110 | declarations: [
111 | {
112 | end: 267,
113 | id: {
114 | end: 82,
115 | name: 'point',
116 | range: [
117 | 77,
118 | 82,
119 | ],
120 | start: 77,
121 | type: 'Identifier',
122 | },
123 | init: {
124 | comments: [
125 | {
126 | end: 146,
127 | range: [
128 | 91,
129 | 146,
130 | ],
131 | start: 91,
132 | type: 'MultiLine',
133 | value: ' This is a block comment inside an object expression ',
134 | },
135 | ],
136 | end: 267,
137 | properties: [
138 | {
139 | comments: [
140 | {
141 | end: 187,
142 | range: [
143 | 151,
144 | 187,
145 | ],
146 | start: 151,
147 | type: 'SingleLine',
148 | value: ` This comment is for the x property␊
149 | `,
150 | },
151 | ],
152 | computed: false,
153 | end: 193,
154 | key: {
155 | end: 190,
156 | name: 'x',
157 | range: [
158 | 189,
159 | 190,
160 | ],
161 | start: 189,
162 | type: 'Identifier',
163 | },
164 | kind: 'init',
165 | method: false,
166 | range: [
167 | 189,
168 | 193,
169 | ],
170 | shorthand: false,
171 | start: 189,
172 | type: 'Property',
173 | value: {
174 | end: 193,
175 | range: [
176 | 192,
177 | 193,
178 | ],
179 | start: 192,
180 | type: 'Literal',
181 | value: 0,
182 | },
183 | },
184 | {
185 | comments: [
186 | {
187 | end: 236,
188 | range: [
189 | 199,
190 | 236,
191 | ],
192 | start: 199,
193 | type: 'SingleLine',
194 | value: ` …and this one is for the y property␊
195 | `,
196 | },
197 | ],
198 | computed: false,
199 | end: 242,
200 | key: {
201 | end: 239,
202 | name: 'y',
203 | range: [
204 | 238,
205 | 239,
206 | ],
207 | start: 238,
208 | type: 'Identifier',
209 | },
210 | kind: 'init',
211 | method: false,
212 | range: [
213 | 238,
214 | 242,
215 | ],
216 | shorthand: false,
217 | start: 238,
218 | type: 'Property',
219 | value: {
220 | end: 242,
221 | range: [
222 | 241,
223 | 242,
224 | ],
225 | start: 241,
226 | type: 'Literal',
227 | value: 1,
228 | },
229 | },
230 | ],
231 | range: [
232 | 85,
233 | 267,
234 | ],
235 | start: 85,
236 | trailingComments: [
237 | {
238 | end: 266,
239 | range: [
240 | 248,
241 | 266,
242 | ],
243 | start: 248,
244 | type: 'SingleLine',
245 | value: ` Trailing comment␊
246 | `,
247 | },
248 | ],
249 | type: 'ObjectExpression',
250 | },
251 | range: [
252 | 77,
253 | 267,
254 | ],
255 | start: 77,
256 | type: 'VariableDeclarator',
257 | },
258 | ],
259 | end: 267,
260 | kind: 'const',
261 | range: [
262 | 71,
263 | 267,
264 | ],
265 | start: 71,
266 | type: 'VariableDeclaration',
267 | },
268 | {
269 | body: {
270 | body: [
271 | {
272 | computed: false,
273 | decorators: [],
274 | end: 402,
275 | key: {
276 | end: 320,
277 | name: 'm',
278 | range: [
279 | 319,
280 | 320,
281 | ],
282 | start: 319,
283 | type: 'Identifier',
284 | },
285 | kind: 'method',
286 | range: [
287 | 319,
288 | 402,
289 | ],
290 | start: 319,
291 | static: false,
292 | type: 'MethodDefinition',
293 | value: {
294 | async: false,
295 | body: {
296 | body: [],
297 | comments: [
298 | {
299 | end: 398,
300 | range: [
301 | 342,
302 | 398,
303 | ],
304 | start: 342,
305 | type: 'MultiLine',
306 | value: `␊
307 | Document for method `m` with params `x` and `y`.␊
308 | `,
309 | },
310 | ],
311 | end: 402,
312 | range: [
313 | 334,
314 | 402,
315 | ],
316 | start: 334,
317 | type: 'BlockStatement',
318 | },
319 | end: 402,
320 | generator: false,
321 | id: null,
322 | params: [
323 | {
324 | end: 322,
325 | name: 'x',
326 | range: [
327 | 321,
328 | 322,
329 | ],
330 | start: 321,
331 | type: 'Identifier',
332 | },
333 | {
334 | end: 332,
335 | left: {
336 | end: 325,
337 | name: 'y',
338 | range: [
339 | 324,
340 | 325,
341 | ],
342 | start: 324,
343 | type: 'Identifier',
344 | },
345 | range: [
346 | 324,
347 | 332,
348 | ],
349 | right: {
350 | end: 332,
351 | range: [
352 | 328,
353 | 332,
354 | ],
355 | start: 328,
356 | type: 'Literal',
357 | value: true,
358 | },
359 | start: 324,
360 | type: 'AssignmentPattern',
361 | },
362 | ],
363 | range: [
364 | 320,
365 | 402,
366 | ],
367 | start: 320,
368 | type: 'FunctionExpression',
369 | },
370 | },
371 | ],
372 | comments: [
373 | {
374 | end: 315,
375 | range: [
376 | 283,
377 | 315,
378 | ],
379 | start: 283,
380 | type: 'MultiLine',
381 | value: `␊
382 | Documentation for class A.␊
383 | `,
384 | },
385 | ],
386 | end: 404,
387 | range: [
388 | 277,
389 | 404,
390 | ],
391 | start: 277,
392 | type: 'ClassBody',
393 | },
394 | decorators: [],
395 | end: 404,
396 | id: {
397 | end: 276,
398 | name: 'A',
399 | range: [
400 | 275,
401 | 276,
402 | ],
403 | start: 275,
404 | type: 'Identifier',
405 | },
406 | range: [
407 | 269,
408 | 404,
409 | ],
410 | start: 269,
411 | superClass: null,
412 | type: 'ClassDeclaration',
413 | },
414 | ],
415 | comments: [
416 | {
417 | end: 27,
418 | range: [
419 | 2,
420 | 27,
421 | ],
422 | start: 2,
423 | type: 'MultiLine',
424 | value: `␊
425 | Module documentation.␊
426 | `,
427 | },
428 | {
429 | end: 70,
430 | range: [
431 | 31,
432 | 70,
433 | ],
434 | start: 31,
435 | type: 'MultiLine',
436 | value: `␊
437 | Documentation for variable `point`.␊
438 | `,
439 | },
440 | ],
441 | end: 405,
442 | range: [
443 | 0,
444 | 405,
445 | ],
446 | sourceType: 'module',
447 | start: 0,
448 | type: 'Program',
449 | }
450 |
--------------------------------------------------------------------------------
/src/tests/snapshots/defaultTraveler.js.md:
--------------------------------------------------------------------------------
1 | # Snapshot report for `src/tests/defaultTraveler.js`
2 |
3 | The actual snapshot is saved in `defaultTraveler.js.snap`.
4 |
5 | Generated by [AVA](https://avajs.dev).
6 |
7 | ## Default traveler
8 |
9 | > Snapshot 1
10 |
11 | [
12 | 'Root',
13 | [
14 | [
15 | 'Program',
16 | [
17 | [
18 | 'ImportDeclaration',
19 | [
20 | [
21 | 'ImportDefaultSpecifier',
22 | [
23 | [
24 | 'Identifier',
25 | [],
26 | ],
27 | ],
28 | ],
29 | [
30 | 'Literal',
31 | [],
32 | ],
33 | ],
34 | ],
35 | [
36 | 'ImportDeclaration',
37 | [
38 | [
39 | 'ImportDefaultSpecifier',
40 | [
41 | [
42 | 'Identifier',
43 | [],
44 | ],
45 | ],
46 | ],
47 | [
48 | 'ImportSpecifier',
49 | [
50 | [
51 | 'Identifier',
52 | [],
53 | ],
54 | [
55 | 'Identifier',
56 | [],
57 | ],
58 | ],
59 | ],
60 | [
61 | 'Literal',
62 | [],
63 | ],
64 | ],
65 | ],
66 | [
67 | 'ImportDeclaration',
68 | [
69 | [
70 | 'ImportSpecifier',
71 | [
72 | [
73 | 'Identifier',
74 | [],
75 | ],
76 | [
77 | 'Identifier',
78 | [],
79 | ],
80 | ],
81 | ],
82 | [
83 | 'Literal',
84 | [],
85 | ],
86 | ],
87 | ],
88 | [
89 | 'ImportDeclaration',
90 | [
91 | [
92 | 'ImportNamespaceSpecifier',
93 | [
94 | [
95 | 'Identifier',
96 | [],
97 | ],
98 | ],
99 | ],
100 | [
101 | 'Literal',
102 | [],
103 | ],
104 | ],
105 | ],
106 | [
107 | 'ExportNamedDeclaration',
108 | [
109 | [
110 | 'ExportSpecifier',
111 | [
112 | [
113 | 'Identifier',
114 | [],
115 | ],
116 | [
117 | 'Identifier',
118 | [],
119 | ],
120 | ],
121 | ],
122 | [
123 | 'Literal',
124 | [],
125 | ],
126 | ],
127 | ],
128 | [
129 | 'ExportNamedDeclaration',
130 | [
131 | [
132 | 'VariableDeclaration',
133 | [
134 | [
135 | 'VariableDeclarator',
136 | [
137 | [
138 | 'Identifier',
139 | [],
140 | ],
141 | [
142 | 'Identifier',
143 | [],
144 | ],
145 | ],
146 | ],
147 | ],
148 | ],
149 | ],
150 | ],
151 | [
152 | 'ExportAllDeclaration',
153 | [
154 | [
155 | 'Literal',
156 | [],
157 | ],
158 | ],
159 | ],
160 | [
161 | 'ExportDefaultDeclaration',
162 | [
163 | [
164 | 'ClassDeclaration',
165 | [
166 | [
167 | 'Identifier',
168 | [],
169 | ],
170 | [
171 | 'ClassBody',
172 | [
173 | [
174 | 'MethodDefinition',
175 | [
176 | [
177 | 'Identifier',
178 | [],
179 | ],
180 | [
181 | 'FunctionExpression',
182 | [
183 | [
184 | 'BlockStatement',
185 | [
186 | [
187 | 'ExpressionStatement',
188 | [
189 | [
190 | 'AssignmentExpression',
191 | [
192 | [
193 | 'MemberExpression',
194 | [
195 | [
196 | 'ThisExpression',
197 | [],
198 | ],
199 | [
200 | 'Identifier',
201 | [],
202 | ],
203 | ],
204 | ],
205 | [
206 | 'ArrowFunctionExpression',
207 | [
208 | [
209 | 'BlockStatement',
210 | [],
211 | ],
212 | ],
213 | ],
214 | ],
215 | ],
216 | ],
217 | ],
218 | [
219 | 'ExpressionStatement',
220 | [
221 | [
222 | 'AssignmentExpression',
223 | [
224 | [
225 | 'MemberExpression',
226 | [
227 | [
228 | 'ThisExpression',
229 | [],
230 | ],
231 | [
232 | 'Identifier',
233 | [],
234 | ],
235 | ],
236 | ],
237 | [
238 | 'ArrowFunctionExpression',
239 | [
240 | [
241 | 'Identifier',
242 | [],
243 | ],
244 | [
245 | 'ObjectExpression',
246 | [],
247 | ],
248 | ],
249 | ],
250 | ],
251 | ],
252 | ],
253 | ],
254 | ],
255 | ],
256 | ],
257 | ],
258 | ],
259 | ],
260 | [
261 | 'MethodDefinition',
262 | [
263 | [
264 | 'Identifier',
265 | [],
266 | ],
267 | [
268 | 'FunctionExpression',
269 | [
270 | [
271 | 'BlockStatement',
272 | [],
273 | ],
274 | ],
275 | ],
276 | ],
277 | ],
278 | [
279 | 'MethodDefinition',
280 | [
281 | [
282 | 'Identifier',
283 | [],
284 | ],
285 | [
286 | 'FunctionExpression',
287 | [
288 | [
289 | 'BlockStatement',
290 | [
291 | [
292 | 'ExpressionStatement',
293 | [
294 | [
295 | 'MetaProperty',
296 | [
297 | [
298 | 'Identifier',
299 | [],
300 | ],
301 | [
302 | 'Identifier',
303 | [],
304 | ],
305 | ],
306 | ],
307 | ],
308 | ],
309 | [
310 | 'ExpressionStatement',
311 | [
312 | [
313 | 'AssignmentExpression',
314 | [
315 | [
316 | 'MemberExpression',
317 | [
318 | [
319 | 'ThisExpression',
320 | [],
321 | ],
322 | [
323 | 'Identifier',
324 | [],
325 | ],
326 | ],
327 | ],
328 | [
329 | 'Literal',
330 | [],
331 | ],
332 | ],
333 | ],
334 | ],
335 | ],
336 | ],
337 | ],
338 | ],
339 | ],
340 | ],
341 | ],
342 | ],
343 | ],
344 | ],
345 | ],
346 | ],
347 | ],
348 | [
349 | 'VariableDeclaration',
350 | [
351 | [
352 | 'VariableDeclarator',
353 | [
354 | [
355 | 'Identifier',
356 | [],
357 | ],
358 | [
359 | 'ClassExpression',
360 | [
361 | [
362 | 'Identifier',
363 | [],
364 | ],
365 | [
366 | 'ClassBody',
367 | [],
368 | ],
369 | ],
370 | ],
371 | ],
372 | ],
373 | ],
374 | ],
375 | [
376 | 'FunctionDeclaration',
377 | [
378 | [
379 | 'Identifier',
380 | [],
381 | ],
382 | [
383 | 'Identifier',
384 | [],
385 | ],
386 | [
387 | 'Identifier',
388 | [],
389 | ],
390 | [
391 | 'AssignmentPattern',
392 | [
393 | [
394 | 'Identifier',
395 | [],
396 | ],
397 | [
398 | 'Literal',
399 | [],
400 | ],
401 | ],
402 | ],
403 | [
404 | 'BlockStatement',
405 | [
406 | [
407 | 'VariableDeclaration',
408 | [
409 | [
410 | 'VariableDeclarator',
411 | [
412 | [
413 | 'Identifier',
414 | [],
415 | ],
416 | [
417 | 'Identifier',
418 | [],
419 | ],
420 | ],
421 | ],
422 | ],
423 | ],
424 | [
425 | 'VariableDeclaration',
426 | [
427 | [
428 | 'VariableDeclarator',
429 | [
430 | [
431 | 'Identifier',
432 | [],
433 | ],
434 | [
435 | 'Identifier',
436 | [],
437 | ],
438 | ],
439 | ],
440 | ],
441 | ],
442 | [
443 | 'VariableDeclaration',
444 | [
445 | [
446 | 'VariableDeclarator',
447 | [
448 | [
449 | 'Identifier',
450 | [],
451 | ],
452 | [
453 | 'Identifier',
454 | [],
455 | ],
456 | ],
457 | ],
458 | ],
459 | ],
460 | [
461 | 'VariableDeclaration',
462 | [
463 | [
464 | 'VariableDeclarator',
465 | [
466 | [
467 | 'ObjectPattern',
468 | [
469 | [
470 | 'Property',
471 | [
472 | [
473 | 'Identifier',
474 | [],
475 | ],
476 | [
477 | 'Identifier',
478 | [],
479 | ],
480 | ],
481 | ],
482 | [
483 | 'Property',
484 | [
485 | [
486 | 'Identifier',
487 | [],
488 | ],
489 | [
490 | 'Identifier',
491 | [],
492 | ],
493 | ],
494 | ],
495 | [
496 | 'Property',
497 | [
498 | [
499 | 'Identifier',
500 | [],
501 | ],
502 | [
503 | 'Identifier',
504 | [],
505 | ],
506 | ],
507 | ],
508 | ],
509 | ],
510 | [
511 | 'Identifier',
512 | [],
513 | ],
514 | ],
515 | ],
516 | ],
517 | ],
518 | [
519 | 'VariableDeclaration',
520 | [
521 | [
522 | 'VariableDeclarator',
523 | [
524 | [
525 | 'ArrayPattern',
526 | [
527 | [
528 | 'Identifier',
529 | [],
530 | ],
531 | [
532 | 'Identifier',
533 | [],
534 | ],
535 | [
536 | 'Identifier',
537 | [],
538 | ],
539 | ],
540 | ],
541 | [
542 | 'Identifier',
543 | [],
544 | ],
545 | ],
546 | ],
547 | ],
548 | ],
549 | [
550 | 'ReturnStatement',
551 | [
552 | [
553 | 'ConditionalExpression',
554 | [
555 | [
556 | 'BinaryExpression',
557 | [
558 | [
559 | 'Identifier',
560 | [],
561 | ],
562 | [
563 | 'Literal',
564 | [],
565 | ],
566 | ],
567 | ],
568 | [
569 | 'Identifier',
570 | [],
571 | ],
572 | [
573 | 'Identifier',
574 | [],
575 | ],
576 | ],
577 | ],
578 | ],
579 | ],
580 | ],
581 | ],
582 | ],
583 | ],
584 | [
585 | 'FunctionDeclaration',
586 | [
587 | [
588 | 'Identifier',
589 | [],
590 | ],
591 | [
592 | 'BlockStatement',
593 | [
594 | [
595 | 'ExpressionStatement',
596 | [
597 | [
598 | 'YieldExpression',
599 | [],
600 | ],
601 | ],
602 | ],
603 | [
604 | 'ExpressionStatement',
605 | [
606 | [
607 | 'YieldExpression',
608 | [
609 | [
610 | 'Literal',
611 | [],
612 | ],
613 | ],
614 | ],
615 | ],
616 | ],
617 | ],
618 | ],
619 | ],
620 | ],
621 | [
622 | 'FunctionDeclaration',
623 | [
624 | [
625 | 'Identifier',
626 | [],
627 | ],
628 | [
629 | 'BlockStatement',
630 | [
631 | [
632 | 'ReturnStatement',
633 | [
634 | [
635 | 'AwaitExpression',
636 | [
637 | [
638 | 'CallExpression',
639 | [
640 | [
641 | 'Identifier',
642 | [],
643 | ],
644 | ],
645 | ],
646 | ],
647 | ],
648 | ],
649 | ],
650 | ],
651 | ],
652 | ],
653 | ],
654 | [
655 | 'FunctionDeclaration',
656 | [
657 | [
658 | 'Identifier',
659 | [],
660 | ],
661 | [
662 | 'BlockStatement',
663 | [
664 | [
665 | 'ForOfStatement',
666 | [
667 | [
668 | 'VariableDeclaration',
669 | [
670 | [
671 | 'VariableDeclarator',
672 | [
673 | [
674 | 'Identifier',
675 | [],
676 | ],
677 | ],
678 | ],
679 | ],
680 | ],
681 | [
682 | 'Identifier',
683 | [],
684 | ],
685 | [
686 | 'BlockStatement',
687 | [],
688 | ],
689 | ],
690 | ],
691 | ],
692 | ],
693 | ],
694 | ],
695 | [
696 | 'FunctionDeclaration',
697 | [
698 | [
699 | 'Identifier',
700 | [],
701 | ],
702 | [
703 | 'BlockStatement',
704 | [
705 | [
706 | 'IfStatement',
707 | [
708 | [
709 | 'BinaryExpression',
710 | [
711 | [
712 | 'Identifier',
713 | [],
714 | ],
715 | [
716 | 'Literal',
717 | [],
718 | ],
719 | ],
720 | ],
721 | [
722 | 'BlockStatement',
723 | [
724 | [
725 | 'ExpressionStatement',
726 | [
727 | [
728 | 'CallExpression',
729 | [
730 | [
731 | 'Identifier',
732 | [],
733 | ],
734 | [
735 | 'SpreadElement',
736 | [
737 | [
738 | 'Identifier',
739 | [],
740 | ],
741 | ],
742 | ],
743 | ],
744 | ],
745 | ],
746 | ],
747 | ],
748 | ],
749 | [
750 | 'IfStatement',
751 | [
752 | [
753 | 'BinaryExpression',
754 | [
755 | [
756 | 'Identifier',
757 | [],
758 | ],
759 | [
760 | 'Literal',
761 | [],
762 | ],
763 | ],
764 | ],
765 | [
766 | 'BlockStatement',
767 | [
768 | [
769 | 'ExpressionStatement',
770 | [
771 | [
772 | 'CallExpression',
773 | [
774 | [
775 | 'Identifier',
776 | [],
777 | ],
778 | [
779 | 'Literal',
780 | [],
781 | ],
782 | ],
783 | ],
784 | ],
785 | ],
786 | ],
787 | ],
788 | [
789 | 'BlockStatement',
790 | [
791 | [
792 | 'ExpressionStatement',
793 | [
794 | [
795 | 'CallExpression',
796 | [
797 | [
798 | 'Identifier',
799 | [],
800 | ],
801 | [
802 | 'Literal',
803 | [],
804 | ],
805 | ],
806 | ],
807 | ],
808 | ],
809 | ],
810 | ],
811 | ],
812 | ],
813 | ],
814 | ],
815 | [
816 | 'IfStatement',
817 | [
818 | [
819 | 'BinaryExpression',
820 | [
821 | [
822 | 'Identifier',
823 | [],
824 | ],
825 | [
826 | 'Literal',
827 | [],
828 | ],
829 | ],
830 | ],
831 | [
832 | 'BlockStatement',
833 | [],
834 | ],
835 | ],
836 | ],
837 | [
838 | 'LabeledStatement',
839 | [
840 | [
841 | 'Identifier',
842 | [],
843 | ],
844 | [
845 | 'SwitchStatement',
846 | [
847 | [
848 | 'Identifier',
849 | [],
850 | ],
851 | [
852 | 'SwitchCase',
853 | [
854 | [
855 | 'Literal',
856 | [],
857 | ],
858 | [
859 | 'BreakStatement',
860 | [
861 | [
862 | 'Identifier',
863 | [],
864 | ],
865 | ],
866 | ],
867 | ],
868 | ],
869 | [
870 | 'SwitchCase',
871 | [
872 | [
873 | 'BreakStatement',
874 | [],
875 | ],
876 | ],
877 | ],
878 | ],
879 | ],
880 | ],
881 | ],
882 | [
883 | 'ReturnStatement',
884 | [],
885 | ],
886 | ],
887 | ],
888 | ],
889 | ],
890 | [
891 | 'FunctionDeclaration',
892 | [
893 | [
894 | 'Identifier',
895 | [],
896 | ],
897 | [
898 | 'BlockStatement',
899 | [
900 | [
901 | 'LabeledStatement',
902 | [
903 | [
904 | 'Identifier',
905 | [],
906 | ],
907 | [
908 | 'ForStatement',
909 | [
910 | [
911 | 'VariableDeclaration',
912 | [
913 | [
914 | 'VariableDeclarator',
915 | [
916 | [
917 | 'Identifier',
918 | [],
919 | ],
920 | [
921 | 'Literal',
922 | [],
923 | ],
924 | ],
925 | ],
926 | ],
927 | ],
928 | [
929 | 'BinaryExpression',
930 | [
931 | [
932 | 'Identifier',
933 | [],
934 | ],
935 | [
936 | 'MemberExpression',
937 | [
938 | [
939 | 'Identifier',
940 | [],
941 | ],
942 | [
943 | 'Identifier',
944 | [],
945 | ],
946 | ],
947 | ],
948 | ],
949 | ],
950 | [
951 | 'UpdateExpression',
952 | [
953 | [
954 | 'Identifier',
955 | [],
956 | ],
957 | ],
958 | ],
959 | [
960 | 'BlockStatement',
961 | [
962 | [
963 | 'IfStatement',
964 | [
965 | [
966 | 'BinaryExpression',
967 | [
968 | [
969 | 'Identifier',
970 | [],
971 | ],
972 | [
973 | 'Literal',
974 | [],
975 | ],
976 | ],
977 | ],
978 | [
979 | 'BlockStatement',
980 | [
981 | [
982 | 'ContinueStatement',
983 | [
984 | [
985 | 'Identifier',
986 | [],
987 | ],
988 | ],
989 | ],
990 | ],
991 | ],
992 | [
993 | 'BlockStatement',
994 | [
995 | [
996 | 'ContinueStatement',
997 | [],
998 | ],
999 | ],
1000 | ],
1001 | ],
1002 | ],
1003 | ],
1004 | ],
1005 | ],
1006 | ],
1007 | ],
1008 | ],
1009 | [
1010 | 'ForStatement',
1011 | [
1012 | [
1013 | 'BlockStatement',
1014 | [],
1015 | ],
1016 | ],
1017 | ],
1018 | [
1019 | 'ForInStatement',
1020 | [
1021 | [
1022 | 'VariableDeclaration',
1023 | [
1024 | [
1025 | 'VariableDeclarator',
1026 | [
1027 | [
1028 | 'Identifier',
1029 | [],
1030 | ],
1031 | ],
1032 | ],
1033 | ],
1034 | ],
1035 | [
1036 | 'Identifier',
1037 | [],
1038 | ],
1039 | [
1040 | 'BlockStatement',
1041 | [],
1042 | ],
1043 | ],
1044 | ],
1045 | [
1046 | 'ForOfStatement',
1047 | [
1048 | [
1049 | 'VariableDeclaration',
1050 | [
1051 | [
1052 | 'VariableDeclarator',
1053 | [
1054 | [
1055 | 'Identifier',
1056 | [],
1057 | ],
1058 | ],
1059 | ],
1060 | ],
1061 | ],
1062 | [
1063 | 'Identifier',
1064 | [],
1065 | ],
1066 | [
1067 | 'BlockStatement',
1068 | [],
1069 | ],
1070 | ],
1071 | ],
1072 | [
1073 | 'WhileStatement',
1074 | [
1075 | [
1076 | 'BinaryExpression',
1077 | [
1078 | [
1079 | 'Identifier',
1080 | [],
1081 | ],
1082 | [
1083 | 'Literal',
1084 | [],
1085 | ],
1086 | ],
1087 | ],
1088 | [
1089 | 'BlockStatement',
1090 | [],
1091 | ],
1092 | ],
1093 | ],
1094 | [
1095 | 'DoWhileStatement',
1096 | [
1097 | [
1098 | 'BlockStatement',
1099 | [],
1100 | ],
1101 | [
1102 | 'BinaryExpression',
1103 | [
1104 | [
1105 | 'Identifier',
1106 | [],
1107 | ],
1108 | [
1109 | 'Literal',
1110 | [],
1111 | ],
1112 | ],
1113 | ],
1114 | ],
1115 | ],
1116 | ],
1117 | ],
1118 | ],
1119 | ],
1120 | [
1121 | 'FunctionDeclaration',
1122 | [
1123 | [
1124 | 'Identifier',
1125 | [],
1126 | ],
1127 | [
1128 | 'BlockStatement',
1129 | [
1130 | [
1131 | 'TryStatement',
1132 | [
1133 | [
1134 | 'BlockStatement',
1135 | [
1136 | [
1137 | 'ThrowStatement',
1138 | [
1139 | [
1140 | 'NewExpression',
1141 | [
1142 | [
1143 | 'Identifier',
1144 | [],
1145 | ],
1146 | ],
1147 | ],
1148 | ],
1149 | ],
1150 | ],
1151 | ],
1152 | [
1153 | 'CatchClause',
1154 | [
1155 | [
1156 | 'Identifier',
1157 | [],
1158 | ],
1159 | [
1160 | 'BlockStatement',
1161 | [
1162 | [
1163 | 'ExpressionStatement',
1164 | [
1165 | [
1166 | 'CallExpression',
1167 | [
1168 | [
1169 | 'Identifier',
1170 | [],
1171 | ],
1172 | [
1173 | 'Identifier',
1174 | [],
1175 | ],
1176 | ],
1177 | ],
1178 | ],
1179 | ],
1180 | ],
1181 | ],
1182 | ],
1183 | ],
1184 | [
1185 | 'BlockStatement',
1186 | [
1187 | [
1188 | 'ExpressionStatement',
1189 | [
1190 | [
1191 | 'CallExpression',
1192 | [
1193 | [
1194 | 'Identifier',
1195 | [],
1196 | ],
1197 | [
1198 | 'Literal',
1199 | [],
1200 | ],
1201 | ],
1202 | ],
1203 | ],
1204 | ],
1205 | ],
1206 | ],
1207 | ],
1208 | ],
1209 | [
1210 | 'TryStatement',
1211 | [
1212 | [
1213 | 'BlockStatement',
1214 | [],
1215 | ],
1216 | [
1217 | 'CatchClause',
1218 | [
1219 | [
1220 | 'Identifier',
1221 | [],
1222 | ],
1223 | [
1224 | 'BlockStatement',
1225 | [],
1226 | ],
1227 | ],
1228 | ],
1229 | ],
1230 | ],
1231 | [
1232 | 'TryStatement',
1233 | [
1234 | [
1235 | 'BlockStatement',
1236 | [],
1237 | ],
1238 | [
1239 | 'CatchClause',
1240 | [
1241 | [
1242 | 'BlockStatement',
1243 | [],
1244 | ],
1245 | ],
1246 | ],
1247 | ],
1248 | ],
1249 | ],
1250 | ],
1251 | ],
1252 | ],
1253 | [
1254 | 'FunctionDeclaration',
1255 | [
1256 | [
1257 | 'Identifier',
1258 | [],
1259 | ],
1260 | [
1261 | 'BlockStatement',
1262 | [
1263 | [
1264 | 'VariableDeclaration',
1265 | [
1266 | [
1267 | 'VariableDeclarator',
1268 | [
1269 | [
1270 | 'ObjectPattern',
1271 | [
1272 | [
1273 | 'Property',
1274 | [
1275 | [
1276 | 'Identifier',
1277 | [],
1278 | ],
1279 | [
1280 | 'Identifier',
1281 | [],
1282 | ],
1283 | ],
1284 | ],
1285 | [
1286 | 'Property',
1287 | [
1288 | [
1289 | 'Identifier',
1290 | [],
1291 | ],
1292 | [
1293 | 'Identifier',
1294 | [],
1295 | ],
1296 | ],
1297 | ],
1298 | [
1299 | 'RestElement',
1300 | [
1301 | [
1302 | 'Identifier',
1303 | [],
1304 | ],
1305 | ],
1306 | ],
1307 | ],
1308 | ],
1309 | [
1310 | 'Identifier',
1311 | [],
1312 | ],
1313 | ],
1314 | ],
1315 | ],
1316 | ],
1317 | [
1318 | 'VariableDeclaration',
1319 | [
1320 | [
1321 | 'VariableDeclarator',
1322 | [
1323 | [
1324 | 'ArrayPattern',
1325 | [
1326 | [
1327 | 'Identifier',
1328 | [],
1329 | ],
1330 | [
1331 | 'Identifier',
1332 | [],
1333 | ],
1334 | ],
1335 | ],
1336 | [
1337 | 'Identifier',
1338 | [],
1339 | ],
1340 | ],
1341 | ],
1342 | ],
1343 | ],
1344 | ],
1345 | ],
1346 | ],
1347 | ],
1348 | [
1349 | 'VariableDeclaration',
1350 | [
1351 | [
1352 | 'VariableDeclarator',
1353 | [
1354 | [
1355 | 'Identifier',
1356 | [],
1357 | ],
1358 | [
1359 | 'NewExpression',
1360 | [
1361 | [
1362 | 'Identifier',
1363 | [],
1364 | ],
1365 | ],
1366 | ],
1367 | ],
1368 | ],
1369 | ],
1370 | ],
1371 | [
1372 | 'VariableDeclaration',
1373 | [
1374 | [
1375 | 'VariableDeclarator',
1376 | [
1377 | [
1378 | 'Identifier',
1379 | [],
1380 | ],
1381 | [
1382 | 'ObjectExpression',
1383 | [
1384 | [
1385 | 'Property',
1386 | [
1387 | [
1388 | 'Identifier',
1389 | [],
1390 | ],
1391 | [
1392 | 'Identifier',
1393 | [],
1394 | ],
1395 | ],
1396 | ],
1397 | [
1398 | 'Property',
1399 | [
1400 | [
1401 | 'Identifier',
1402 | [],
1403 | ],
1404 | [
1405 | 'Identifier',
1406 | [],
1407 | ],
1408 | ],
1409 | ],
1410 | [
1411 | 'Property',
1412 | [
1413 | [
1414 | 'Identifier',
1415 | [],
1416 | ],
1417 | [
1418 | 'FunctionExpression',
1419 | [
1420 | [
1421 | 'BlockStatement',
1422 | [],
1423 | ],
1424 | ],
1425 | ],
1426 | ],
1427 | ],
1428 | [
1429 | 'SpreadElement',
1430 | [
1431 | [
1432 | 'Identifier',
1433 | [],
1434 | ],
1435 | ],
1436 | ],
1437 | ],
1438 | ],
1439 | ],
1440 | ],
1441 | ],
1442 | ],
1443 | [
1444 | 'VariableDeclaration',
1445 | [
1446 | [
1447 | 'VariableDeclarator',
1448 | [
1449 | [
1450 | 'Identifier',
1451 | [],
1452 | ],
1453 | [
1454 | 'ObjectExpression',
1455 | [
1456 | [
1457 | 'Property',
1458 | [
1459 | [
1460 | 'Identifier',
1461 | [],
1462 | ],
1463 | [
1464 | 'Literal',
1465 | [],
1466 | ],
1467 | ],
1468 | ],
1469 | [
1470 | 'Property',
1471 | [
1472 | [
1473 | 'Identifier',
1474 | [],
1475 | ],
1476 | [
1477 | 'Literal',
1478 | [],
1479 | ],
1480 | ],
1481 | ],
1482 | [
1483 | 'Property',
1484 | [
1485 | [
1486 | 'Identifier',
1487 | [],
1488 | ],
1489 | [
1490 | 'BinaryExpression',
1491 | [
1492 | [
1493 | 'Literal',
1494 | [],
1495 | ],
1496 | [
1497 | 'Literal',
1498 | [],
1499 | ],
1500 | ],
1501 | ],
1502 | ],
1503 | ],
1504 | [
1505 | 'Property',
1506 | [
1507 | [
1508 | 'Identifier',
1509 | [],
1510 | ],
1511 | [
1512 | 'BinaryExpression',
1513 | [
1514 | [
1515 | 'Literal',
1516 | [],
1517 | ],
1518 | [
1519 | 'Literal',
1520 | [],
1521 | ],
1522 | ],
1523 | ],
1524 | ],
1525 | ],
1526 | [
1527 | 'Property',
1528 | [
1529 | [
1530 | 'Identifier',
1531 | [],
1532 | ],
1533 | [
1534 | 'BinaryExpression',
1535 | [
1536 | [
1537 | 'Literal',
1538 | [],
1539 | ],
1540 | [
1541 | 'Literal',
1542 | [],
1543 | ],
1544 | ],
1545 | ],
1546 | ],
1547 | ],
1548 | [
1549 | 'Property',
1550 | [
1551 | [
1552 | 'Identifier',
1553 | [],
1554 | ],
1555 | [
1556 | 'BinaryExpression',
1557 | [
1558 | [
1559 | 'Literal',
1560 | [],
1561 | ],
1562 | [
1563 | 'Literal',
1564 | [],
1565 | ],
1566 | ],
1567 | ],
1568 | ],
1569 | ],
1570 | [
1571 | 'Property',
1572 | [
1573 | [
1574 | 'Identifier',
1575 | [],
1576 | ],
1577 | [
1578 | 'BinaryExpression',
1579 | [
1580 | [
1581 | 'Literal',
1582 | [],
1583 | ],
1584 | [
1585 | 'Literal',
1586 | [],
1587 | ],
1588 | ],
1589 | ],
1590 | ],
1591 | ],
1592 | [
1593 | 'Property',
1594 | [
1595 | [
1596 | 'Identifier',
1597 | [],
1598 | ],
1599 | [
1600 | 'BinaryExpression',
1601 | [
1602 | [
1603 | 'Literal',
1604 | [],
1605 | ],
1606 | [
1607 | 'Literal',
1608 | [],
1609 | ],
1610 | ],
1611 | ],
1612 | ],
1613 | ],
1614 | [
1615 | 'Property',
1616 | [
1617 | [
1618 | 'Identifier',
1619 | [],
1620 | ],
1621 | [
1622 | 'BinaryExpression',
1623 | [
1624 | [
1625 | 'Literal',
1626 | [],
1627 | ],
1628 | [
1629 | 'Literal',
1630 | [],
1631 | ],
1632 | ],
1633 | ],
1634 | ],
1635 | ],
1636 | [
1637 | 'Property',
1638 | [
1639 | [
1640 | 'Identifier',
1641 | [],
1642 | ],
1643 | [
1644 | 'BinaryExpression',
1645 | [
1646 | [
1647 | 'Literal',
1648 | [],
1649 | ],
1650 | [
1651 | 'Literal',
1652 | [],
1653 | ],
1654 | ],
1655 | ],
1656 | ],
1657 | ],
1658 | [
1659 | 'Property',
1660 | [
1661 | [
1662 | 'Identifier',
1663 | [],
1664 | ],
1665 | [
1666 | 'BinaryExpression',
1667 | [
1668 | [
1669 | 'Literal',
1670 | [],
1671 | ],
1672 | [
1673 | 'Identifier',
1674 | [],
1675 | ],
1676 | ],
1677 | ],
1678 | ],
1679 | ],
1680 | [
1681 | 'Property',
1682 | [
1683 | [
1684 | 'Identifier',
1685 | [],
1686 | ],
1687 | [
1688 | 'BinaryExpression',
1689 | [
1690 | [
1691 | 'Literal',
1692 | [],
1693 | ],
1694 | [
1695 | 'Literal',
1696 | [],
1697 | ],
1698 | ],
1699 | ],
1700 | ],
1701 | ],
1702 | [
1703 | 'Property',
1704 | [
1705 | [
1706 | 'Identifier',
1707 | [],
1708 | ],
1709 | [
1710 | 'BinaryExpression',
1711 | [
1712 | [
1713 | 'Literal',
1714 | [],
1715 | ],
1716 | [
1717 | 'Literal',
1718 | [],
1719 | ],
1720 | ],
1721 | ],
1722 | ],
1723 | ],
1724 | [
1725 | 'Property',
1726 | [
1727 | [
1728 | 'Identifier',
1729 | [],
1730 | ],
1731 | [
1732 | 'BinaryExpression',
1733 | [
1734 | [
1735 | 'Literal',
1736 | [],
1737 | ],
1738 | [
1739 | 'Literal',
1740 | [],
1741 | ],
1742 | ],
1743 | ],
1744 | ],
1745 | ],
1746 | [
1747 | 'Property',
1748 | [
1749 | [
1750 | 'Identifier',
1751 | [],
1752 | ],
1753 | [
1754 | 'BinaryExpression',
1755 | [
1756 | [
1757 | 'Literal',
1758 | [],
1759 | ],
1760 | [
1761 | 'Literal',
1762 | [],
1763 | ],
1764 | ],
1765 | ],
1766 | ],
1767 | ],
1768 | [
1769 | 'Property',
1770 | [
1771 | [
1772 | 'Identifier',
1773 | [],
1774 | ],
1775 | [
1776 | 'BinaryExpression',
1777 | [
1778 | [
1779 | 'Literal',
1780 | [],
1781 | ],
1782 | [
1783 | 'Identifier',
1784 | [],
1785 | ],
1786 | ],
1787 | ],
1788 | ],
1789 | ],
1790 | [
1791 | 'Property',
1792 | [
1793 | [
1794 | 'Identifier',
1795 | [],
1796 | ],
1797 | [
1798 | 'LogicalExpression',
1799 | [
1800 | [
1801 | 'Literal',
1802 | [],
1803 | ],
1804 | [
1805 | 'Literal',
1806 | [],
1807 | ],
1808 | ],
1809 | ],
1810 | ],
1811 | ],
1812 | [
1813 | 'Property',
1814 | [
1815 | [
1816 | 'Identifier',
1817 | [],
1818 | ],
1819 | [
1820 | 'LogicalExpression',
1821 | [
1822 | [
1823 | 'Literal',
1824 | [],
1825 | ],
1826 | [
1827 | 'Literal',
1828 | [],
1829 | ],
1830 | ],
1831 | ],
1832 | ],
1833 | ],
1834 | [
1835 | 'Property',
1836 | [
1837 | [
1838 | 'Identifier',
1839 | [],
1840 | ],
1841 | [
1842 | 'SequenceExpression',
1843 | [
1844 | [
1845 | 'Literal',
1846 | [],
1847 | ],
1848 | [
1849 | 'Literal',
1850 | [],
1851 | ],
1852 | ],
1853 | ],
1854 | ],
1855 | ],
1856 | [
1857 | 'Property',
1858 | [
1859 | [
1860 | 'Identifier',
1861 | [],
1862 | ],
1863 | [
1864 | 'BinaryExpression',
1865 | [
1866 | [
1867 | 'Literal',
1868 | [],
1869 | ],
1870 | [
1871 | 'Literal',
1872 | [],
1873 | ],
1874 | ],
1875 | ],
1876 | ],
1877 | ],
1878 | [
1879 | 'Property',
1880 | [
1881 | [
1882 | 'Identifier',
1883 | [],
1884 | ],
1885 | [
1886 | 'BinaryExpression',
1887 | [
1888 | [
1889 | 'Literal',
1890 | [],
1891 | ],
1892 | [
1893 | 'Literal',
1894 | [],
1895 | ],
1896 | ],
1897 | ],
1898 | ],
1899 | ],
1900 | [
1901 | 'Property',
1902 | [
1903 | [
1904 | 'Identifier',
1905 | [],
1906 | ],
1907 | [
1908 | 'BinaryExpression',
1909 | [
1910 | [
1911 | 'Literal',
1912 | [],
1913 | ],
1914 | [
1915 | 'Literal',
1916 | [],
1917 | ],
1918 | ],
1919 | ],
1920 | ],
1921 | ],
1922 | [
1923 | 'Property',
1924 | [
1925 | [
1926 | 'Identifier',
1927 | [],
1928 | ],
1929 | [
1930 | 'BinaryExpression',
1931 | [
1932 | [
1933 | 'Literal',
1934 | [],
1935 | ],
1936 | [
1937 | 'Literal',
1938 | [],
1939 | ],
1940 | ],
1941 | ],
1942 | ],
1943 | ],
1944 | [
1945 | 'Property',
1946 | [
1947 | [
1948 | 'Identifier',
1949 | [],
1950 | ],
1951 | [
1952 | 'BinaryExpression',
1953 | [
1954 | [
1955 | 'Literal',
1956 | [],
1957 | ],
1958 | [
1959 | 'Literal',
1960 | [],
1961 | ],
1962 | ],
1963 | ],
1964 | ],
1965 | ],
1966 | ],
1967 | ],
1968 | ],
1969 | ],
1970 | ],
1971 | ],
1972 | [
1973 | 'ExpressionStatement',
1974 | [
1975 | [
1976 | 'AssignmentExpression',
1977 | [
1978 | [
1979 | 'MemberExpression',
1980 | [
1981 | [
1982 | 'Identifier',
1983 | [],
1984 | ],
1985 | [
1986 | 'Identifier',
1987 | [],
1988 | ],
1989 | ],
1990 | ],
1991 | [
1992 | 'Literal',
1993 | [],
1994 | ],
1995 | ],
1996 | ],
1997 | ],
1998 | ],
1999 | [
2000 | 'ExpressionStatement',
2001 | [
2002 | [
2003 | 'AssignmentExpression',
2004 | [
2005 | [
2006 | 'MemberExpression',
2007 | [
2008 | [
2009 | 'Identifier',
2010 | [],
2011 | ],
2012 | [
2013 | 'Identifier',
2014 | [],
2015 | ],
2016 | ],
2017 | ],
2018 | [
2019 | 'Literal',
2020 | [],
2021 | ],
2022 | ],
2023 | ],
2024 | ],
2025 | ],
2026 | [
2027 | 'ExpressionStatement',
2028 | [
2029 | [
2030 | 'AssignmentExpression',
2031 | [
2032 | [
2033 | 'MemberExpression',
2034 | [
2035 | [
2036 | 'Identifier',
2037 | [],
2038 | ],
2039 | [
2040 | 'Identifier',
2041 | [],
2042 | ],
2043 | ],
2044 | ],
2045 | [
2046 | 'Literal',
2047 | [],
2048 | ],
2049 | ],
2050 | ],
2051 | ],
2052 | ],
2053 | [
2054 | 'ExpressionStatement',
2055 | [
2056 | [
2057 | 'AssignmentExpression',
2058 | [
2059 | [
2060 | 'MemberExpression',
2061 | [
2062 | [
2063 | 'Identifier',
2064 | [],
2065 | ],
2066 | [
2067 | 'Identifier',
2068 | [],
2069 | ],
2070 | ],
2071 | ],
2072 | [
2073 | 'Literal',
2074 | [],
2075 | ],
2076 | ],
2077 | ],
2078 | ],
2079 | ],
2080 | [
2081 | 'ExpressionStatement',
2082 | [
2083 | [
2084 | 'AssignmentExpression',
2085 | [
2086 | [
2087 | 'MemberExpression',
2088 | [
2089 | [
2090 | 'Identifier',
2091 | [],
2092 | ],
2093 | [
2094 | 'Identifier',
2095 | [],
2096 | ],
2097 | ],
2098 | ],
2099 | [
2100 | 'Literal',
2101 | [],
2102 | ],
2103 | ],
2104 | ],
2105 | ],
2106 | ],
2107 | [
2108 | 'ExpressionStatement',
2109 | [
2110 | [
2111 | 'AssignmentExpression',
2112 | [
2113 | [
2114 | 'MemberExpression',
2115 | [
2116 | [
2117 | 'Identifier',
2118 | [],
2119 | ],
2120 | [
2121 | 'Identifier',
2122 | [],
2123 | ],
2124 | ],
2125 | ],
2126 | [
2127 | 'Literal',
2128 | [],
2129 | ],
2130 | ],
2131 | ],
2132 | ],
2133 | ],
2134 | [
2135 | 'ExpressionStatement',
2136 | [
2137 | [
2138 | 'UpdateExpression',
2139 | [
2140 | [
2141 | 'MemberExpression',
2142 | [
2143 | [
2144 | 'Identifier',
2145 | [],
2146 | ],
2147 | [
2148 | 'Identifier',
2149 | [],
2150 | ],
2151 | ],
2152 | ],
2153 | ],
2154 | ],
2155 | ],
2156 | ],
2157 | [
2158 | 'ExpressionStatement',
2159 | [
2160 | [
2161 | 'UpdateExpression',
2162 | [
2163 | [
2164 | 'MemberExpression',
2165 | [
2166 | [
2167 | 'Identifier',
2168 | [],
2169 | ],
2170 | [
2171 | 'Identifier',
2172 | [],
2173 | ],
2174 | ],
2175 | ],
2176 | ],
2177 | ],
2178 | ],
2179 | ],
2180 | [
2181 | 'ExpressionStatement',
2182 | [
2183 | [
2184 | 'UpdateExpression',
2185 | [
2186 | [
2187 | 'MemberExpression',
2188 | [
2189 | [
2190 | 'Identifier',
2191 | [],
2192 | ],
2193 | [
2194 | 'Identifier',
2195 | [],
2196 | ],
2197 | ],
2198 | ],
2199 | ],
2200 | ],
2201 | ],
2202 | ],
2203 | [
2204 | 'ExpressionStatement',
2205 | [
2206 | [
2207 | 'UpdateExpression',
2208 | [
2209 | [
2210 | 'MemberExpression',
2211 | [
2212 | [
2213 | 'Identifier',
2214 | [],
2215 | ],
2216 | [
2217 | 'Identifier',
2218 | [],
2219 | ],
2220 | ],
2221 | ],
2222 | ],
2223 | ],
2224 | ],
2225 | ],
2226 | [
2227 | 'ExpressionStatement',
2228 | [
2229 | [
2230 | 'AssignmentExpression',
2231 | [
2232 | [
2233 | 'MemberExpression',
2234 | [
2235 | [
2236 | 'Identifier',
2237 | [],
2238 | ],
2239 | [
2240 | 'Identifier',
2241 | [],
2242 | ],
2243 | ],
2244 | ],
2245 | [
2246 | 'UnaryExpression',
2247 | [
2248 | [
2249 | 'MemberExpression',
2250 | [
2251 | [
2252 | 'Identifier',
2253 | [],
2254 | ],
2255 | [
2256 | 'Identifier',
2257 | [],
2258 | ],
2259 | ],
2260 | ],
2261 | ],
2262 | ],
2263 | ],
2264 | ],
2265 | ],
2266 | ],
2267 | [
2268 | 'ExpressionStatement',
2269 | [
2270 | [
2271 | 'AssignmentExpression',
2272 | [
2273 | [
2274 | 'MemberExpression',
2275 | [
2276 | [
2277 | 'Identifier',
2278 | [],
2279 | ],
2280 | [
2281 | 'Identifier',
2282 | [],
2283 | ],
2284 | ],
2285 | ],
2286 | [
2287 | 'Literal',
2288 | [],
2289 | ],
2290 | ],
2291 | ],
2292 | ],
2293 | ],
2294 | [
2295 | 'VariableDeclaration',
2296 | [
2297 | [
2298 | 'VariableDeclarator',
2299 | [
2300 | [
2301 | 'Identifier',
2302 | [],
2303 | ],
2304 | [
2305 | 'ArrayExpression',
2306 | [
2307 | [
2308 | 'Literal',
2309 | [],
2310 | ],
2311 | [
2312 | 'Literal',
2313 | [],
2314 | ],
2315 | [
2316 | 'Literal',
2317 | [],
2318 | ],
2319 | [
2320 | 'Literal',
2321 | [],
2322 | ],
2323 | [
2324 | 'SpreadElement',
2325 | [
2326 | [
2327 | 'Identifier',
2328 | [],
2329 | ],
2330 | ],
2331 | ],
2332 | ],
2333 | ],
2334 | ],
2335 | ],
2336 | ],
2337 | ],
2338 | [
2339 | 'VariableDeclaration',
2340 | [
2341 | [
2342 | 'VariableDeclarator',
2343 | [
2344 | [
2345 | 'Identifier',
2346 | [],
2347 | ],
2348 | [
2349 | 'TemplateLiteral',
2350 | [
2351 | [
2352 | 'Literal',
2353 | [],
2354 | ],
2355 | [
2356 | 'TemplateElement',
2357 | [],
2358 | ],
2359 | [
2360 | 'TemplateElement',
2361 | [],
2362 | ],
2363 | ],
2364 | ],
2365 | ],
2366 | ],
2367 | ],
2368 | ],
2369 | [
2370 | 'VariableDeclaration',
2371 | [
2372 | [
2373 | 'VariableDeclarator',
2374 | [
2375 | [
2376 | 'Identifier',
2377 | [],
2378 | ],
2379 | [
2380 | 'TaggedTemplateExpression',
2381 | [
2382 | [
2383 | 'Identifier',
2384 | [],
2385 | ],
2386 | [
2387 | 'TemplateLiteral',
2388 | [
2389 | [
2390 | 'Identifier',
2391 | [],
2392 | ],
2393 | [
2394 | 'TemplateElement',
2395 | [],
2396 | ],
2397 | [
2398 | 'TemplateElement',
2399 | [],
2400 | ],
2401 | ],
2402 | ],
2403 | ],
2404 | ],
2405 | ],
2406 | ],
2407 | ],
2408 | ],
2409 | ],
2410 | ],
2411 | ],
2412 | ]
2413 |
--------------------------------------------------------------------------------