{"_id":"babylon-walk","_rev":"81424","name":"babylon-walk","description":"Lightweight Babylon AST traversal","dist-tags":{"latest":"1.0.2"},"maintainers":[{"name":"forbeslindesay","email":"forbes@lindesay.co.uk"},{"name":"npm:forbeslindesay","email":""},{"name":"npm:timothygu","email":""},{"name":"timothygu","email":"timothygu99@gmail.com"}],"time":{"modified":"2021-06-03T10:25:59.000Z","created":"2016-09-11T23:03:27.920Z","1.0.2":"2016-09-11T23:16:30.331Z","1.0.1":"2016-09-11T23:15:06.597Z","1.0.0":"2016-09-11T23:03:27.920Z"},"users":{"laomu":true},"author":{"name":"Timothy Gu","email":"timothygu99@gmail.com"},"repository":{"type":"git","url":"git+https://github.com/pugjs/babylon-walk.git"},"versions":{"1.0.2":{"name":"babylon-walk","version":"1.0.2","description":"Lightweight Babylon AST traversal","main":"lib/index.js","jsnext:main":"src/index.js","files":["lib","src"],"scripts":{"prepublish":"babel -d lib src"},"repository":{"type":"git","url":"git+https://github.com/pugjs/babylon-walk.git"},"author":{"name":"Timothy Gu","email":"timothygu99@gmail.com"},"license":"MIT","dependencies":{"babel-runtime":"^6.11.6","babel-types":"^6.15.0","lodash.clone":"^4.5.0"},"devDependencies":{"babel-cli":"^6.14.0","babel-plugin-transform-runtime":"^6.15.0","babel-preset-es2015":"^6.14.0"},"gitHead":"9389031de4f88e9230b74d12e834ebe818d0712d","bugs":{"url":"https://github.com/pugjs/babylon-walk/issues"},"homepage":"https://github.com/pugjs/babylon-walk#readme","_id":"babylon-walk@1.0.2","_shasum":"3b15a5ddbb482a78b4ce9c01c8ba181702d9d6ce","_from":".","_npmVersion":"3.10.7","_nodeVersion":"6.4.0","_npmUser":{"name":"timothygu","email":"timothygu99@gmail.com"},"dist":{"shasum":"3b15a5ddbb482a78b4ce9c01c8ba181702d9d6ce","size":7641,"noattachment":false,"key":"/babylon-walk/-/babylon-walk-1.0.2.tgz","tarball":"http://registry.cnpm.dingdandao.com/babylon-walk/download/babylon-walk-1.0.2.tgz"},"maintainers":[{"name":"forbeslindesay","email":"forbes@lindesay.co.uk"},{"name":"npm:forbeslindesay","email":""},{"name":"npm:timothygu","email":""},{"name":"timothygu","email":"timothygu99@gmail.com"}],"_npmOperationalInternal":{"host":"packages-12-west.internal.npmjs.com","tmp":"tmp/babylon-walk-1.0.2.tgz_1473635790079_0.9576496391091496"},"directories":{},"publish_time":1473635790331,"_cnpm_publish_time":1473635790331,"_hasShrinkwrap":false},"1.0.1":{"name":"babylon-walk","version":"1.0.1","description":"Lightweight Babylon AST traversal","main":"lib/index.js","jsnext:main":"src/index.js","files":["lib"],"scripts":{"prepublish":"babel -d lib src"},"repository":{"type":"git","url":"git+https://github.com/pugjs/babylon-walk.git"},"author":{"name":"Timothy Gu","email":"timothygu99@gmail.com"},"license":"MIT","dependencies":{"babel-runtime":"^6.11.6","babel-types":"^6.15.0","lodash.clone":"^4.5.0"},"devDependencies":{"babel-cli":"^6.14.0","babel-plugin-transform-runtime":"^6.15.0","babel-preset-es2015":"^6.14.0"},"gitHead":"8952ca2fbac74f7cc71c2410a58599569440d842","bugs":{"url":"https://github.com/pugjs/babylon-walk/issues"},"homepage":"https://github.com/pugjs/babylon-walk#readme","_id":"babylon-walk@1.0.1","_shasum":"001e5ef8bb6d56c654cb113933f1903c486e9628","_from":".","_npmVersion":"3.10.7","_nodeVersion":"6.4.0","_npmUser":{"name":"timothygu","email":"timothygu99@gmail.com"},"dist":{"shasum":"001e5ef8bb6d56c654cb113933f1903c486e9628","size":7048,"noattachment":false,"key":"/babylon-walk/-/babylon-walk-1.0.1.tgz","tarball":"http://registry.cnpm.dingdandao.com/babylon-walk/download/babylon-walk-1.0.1.tgz"},"maintainers":[{"name":"forbeslindesay","email":"forbes@lindesay.co.uk"},{"name":"npm:forbeslindesay","email":""},{"name":"npm:timothygu","email":""},{"name":"timothygu","email":"timothygu99@gmail.com"}],"_npmOperationalInternal":{"host":"packages-12-west.internal.npmjs.com","tmp":"tmp/babylon-walk-1.0.1.tgz_1473635706374_0.6584145906381309"},"directories":{},"publish_time":1473635706597,"_cnpm_publish_time":1473635706597,"_hasShrinkwrap":false},"1.0.0":{"name":"babylon-walk","version":"1.0.0","description":"Lightweight Babylon AST traversal","main":"lib/index.js","jsnext:main":"src/index.js","scripts":{"prepublish":"babel -d lib src"},"repository":{"type":"git","url":"git+https://github.com/pugjs/babylon-walk.git"},"author":{"name":"Timothy Gu","email":"timothygu99@gmail.com"},"license":"MIT","dependencies":{"babel-runtime":"^6.11.6","babel-types":"^6.15.0","lodash.clone":"^4.5.0"},"devDependencies":{"babel-cli":"^6.14.0","babel-plugin-transform-runtime":"^6.15.0","babel-preset-es2015":"^6.14.0"},"gitHead":"011cf4f0eb322ba6646c95c9f31c32dc35bdf453","bugs":{"url":"https://github.com/pugjs/babylon-walk/issues"},"homepage":"https://github.com/pugjs/babylon-walk#readme","_id":"babylon-walk@1.0.0","_shasum":"a8e4a10623173e3894d2a502f3f962d05e37c6e4","_from":".","_npmVersion":"3.10.7","_nodeVersion":"6.4.0","_npmUser":{"name":"timothygu","email":"timothygu99@gmail.com"},"dist":{"shasum":"a8e4a10623173e3894d2a502f3f962d05e37c6e4","size":5759,"noattachment":false,"key":"/babylon-walk/-/babylon-walk-1.0.0.tgz","tarball":"http://registry.cnpm.dingdandao.com/babylon-walk/download/babylon-walk-1.0.0.tgz"},"maintainers":[{"name":"forbeslindesay","email":"forbes@lindesay.co.uk"},{"name":"npm:forbeslindesay","email":""},{"name":"npm:timothygu","email":""},{"name":"timothygu","email":"timothygu99@gmail.com"}],"_npmOperationalInternal":{"host":"packages-16-east.internal.npmjs.com","tmp":"tmp/babylon-walk-1.0.0.tgz_1473635004992_0.9401816637255251"},"directories":{},"publish_time":1473635007920,"_cnpm_publish_time":1473635007920,"_hasShrinkwrap":false}},"readme":"# babylon-walk\n\nLightweight AST traversal tools for [Babylon] ASTs.\n\nBabylon is the parser used by the [Babel] project, which supplies the wonderful [babel-traverse] module for walking Babylon ASTs. Problem is, babel-traverse is very heavyweight, as it is designed to supply utilities to make all sorts of AST transformations possible. For simple AST walking without transformation, babel-traverse brings a lot of overhead.\n\nThis module loosely implements the API of Acorn parser's [walk module], which is a lightweight AST walker for the ESTree AST format.\n\nIn my tests, babylon-walk's ancestor walker (the most complex walker provided by this module) is about 8 times faster than babel-traverse, if the visitors are cached and the same AST is used for all runs. It is about 16 times faster if a fresh AST is used every run.\n\n[![Dependency Status](https://img.shields.io/david/pugjs/babylon-walk.svg)](https://david-dm.org/pugjs/babylon-walk)\n[![NPM version](https://img.shields.io/npm/v/babylon-walk.svg)](https://www.npmjs.com/package/babylon-walk)\n\n[Babylon]: https://github.com/babel/babylon\n[Babel]: https://babeljs.io/\n[babel-traverse]: https://github.com/thejameskyle/babel-handbook/blob/master/translations/en/plugin-handbook.md#toc-babel-traverse\n[walk module]: https://github.com/ternjs/acorn#distwalkjs\n\n## Installation\n\n```sh\n$ npm install babylon-walk\n```\n\n## API\n\n```js\nvar walk = require('babylon-walk');\n```\n\n### walk.simple(node, visitors, state)\n\nDo a simple walk over the AST. `node` should be the AST node to walk, and `visitors` an object containing Babel [visitors]. Each visitor function will be called as `(node, state)`, where `node` is the AST node, and `state` is the same `state` passed to `walk.simple`.\n\nWhen `walk.simple` is called with a fresh set of visitors, it will first \"explode\" the visitors (e.g. expanding `Visitor(node, state) {}` to `Visitor() { enter(node, state) {} }`). This exploding process can take some time, so it is recommended to [cache your visitors] and communicate state leveraging the `state` parameter. (One difference between the linked article and babylon-walk is that the state is only accessible through the `state` variable, never as `this`.)\n\nAll [babel-types] aliases (e.g. `Expression`) and the union syntax (e.g. `'Identifier|AssignmentPattern'(node, state) {}`) work.\n\n### walk.ancestor(node, visitors, state)\n\nDo a simple walk over the AST, but memoizing the ancestors of the node and making them available to the visitors. `node` should be the AST node to walk, and `visitors` an object containing Babel [visitors]. Each visitor function will be called as `(node, state, ancestors)`, where `node` is the AST node, `state` is the same `state` passed to `walk.ancestor`, and `ancestors` is an array of ancestors to the node (with the outermost node being `[0]` and the current node being `[ancestors.length - 1]`). If `state` is not specified in the call to `walk.ancestor`, the `state` parameter will be set to `ancestors`.\n\nWhen `walk.ancestor` is called with a fresh set of visitors, it will first \"explode\" the visitors (e.g. expanding `Visitor(node, state) {}` to `Visitor() { enter(node, state) {} }`). This exploding process can take some time, so it is recommended to [cache your visitors] and communicate state leveraging the `state` parameter. (One difference between the linked article and babylon-walk is that the state is only accessible through the `state` variable, never as `this`.)\n\nAll [babel-types] aliases (e.g. `Expression`) and the union syntax (e.g. `'Identifier|AssignmentPattern'(node, state) {}`) work.\n\n### walk.recursive(node, visitors, state)\n\nDo a recursive walk over the AST, where the visitors are responsible for continuing the walk on the child nodes of their target node. `node` should be the AST node to walk, and `visitors` an object containing Babel [visitors]. Each visitor function will be called as `(node, state, c)`, where `node` is the AST node, `state` is the same `state` passed to `walk.recursive`, and `c` is a function that takes a single node as argument and continues walking _that_ node. If no visitor for a node is provided, the default walker algorithm will still be used.\n\nWhen `walk.recursive` is called with a fresh set of visitors, it will first \"explode\" the visitors (e.g. expanding `Visitor(node, state) {}` to `Visitor() { enter(node, state) {} }`). This exploding process can take some time, so it is recommended to [cache your visitors] and communicate state leveraging the `state` parameter. (One difference between the linked article and babylon-walk is that the state is only accessible through the `state` variable, never as `this`.)\n\nUnlike other babylon-walk walkers, `walk.recursive` does not call the `exit` visitor, only the `enter` (the default) visitor, of a specific node type.\n\nAll [babel-types] aliases (e.g. `Expression`) and the union syntax (e.g. `'Identifier|AssignmentPattern'(node, state) {}`) work.\n\nIn the following example, we are trying to count the number of functions in the outermost scope. This means, that we can simply walk all the statements and increment a counter if it is a function declaration or expression, and then stop walking. Note that we do not specify a visitor for the `Program` node, and the default algorithm for walking `Program` nodes is used (which is what we want). Also of note is how I bring the `visitors` object outside of `countFunctions` so that the object can be cached to improve performance.\n\n```js\nimport * as t from 'babel-types';\nimport {parse} from 'babylon';\n\nconst visitors = {\n  Statement(node, state, c) {\n    if (t.isVariableDeclaration(node)) {\n      for (let declarator of node.declarations) {\n        // Continue walking the declarator\n        c(declarator);\n      }\n    } else if (t.isFunctionDeclaration(node)) {\n      state.counter++;\n    }\n  },\n\n  VariableDeclarator(node, state) {\n    if (t.isFunction(node.init)) {\n      state.counter++;\n    }\n  }\n};\n\nfunction countFunctions(node) {\n  const state = {\n    counter: 0\n  };\n  walk.recursive(node, visitors, state);\n  return state.counter;\n}\n\nconst ast = parse(`\n  // Counts\n  var a = () => {};\n\n  // Counts\n  function b() {\n    // Doesn't count\n    function c() {\n    }\n  }\n\n  // Counts\n  const c = function d() {};\n`);\n\ncountFunctions(ast);\n// = 3\n```\n\n[babel-types]: https://github.com/babel/babel/tree/master/packages/babel-types\n[cache your visitors]: https://github.com/thejameskyle/babel-handbook/blob/master/translations/en/plugin-handbook.md#toc-optimizing-nested-visitors\n[visitors]: https://github.com/thejameskyle/babel-handbook/blob/master/translations/en/plugin-handbook.md#toc-visitors\n\n## Caveat\n\nFor those of you migrating from Acorn to Babylon, there are a few things to be aware of.\n\n1. The visitor caching suggestions do not apply to Acorn's walk module, but do for babylon-walk.\n\n2. babylon-walk does not provide any of the other functions Acorn's walk module provides (e.g. `make`, `findNode*`).\n\n3. babylon-walk does not use a `base` variable. The walker algorithm is the same as what babel-traverse uses.\n   - That means certain nodes that are not walked by Acorn, such as the `property` property of a non-computed `MemberExpression`, are walked by babylon-walk.\n\n## License\n\n  MIT\n","_attachments":{},"homepage":"https://github.com/pugjs/babylon-walk#readme","bugs":{"url":"https://github.com/pugjs/babylon-walk/issues"},"license":"MIT"}