pax_global_header00006660000000000000000000000064133035252060014511gustar00rootroot0000000000000052 comment=40c443ec9f512f11a5f042a94f2cc64cc7a2849e dash-ast-1.0.0/000077500000000000000000000000001330352520600132135ustar00rootroot00000000000000dash-ast-1.0.0/.gitignore000066400000000000000000000010161330352520600152010ustar00rootroot00000000000000# Logs logs *.log # Runtime data pids *.pid *.seed # Directory for instrumented libs generated by jscoverage/JSCover lib-cov # Coverage directory used by tools like istanbul coverage # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) .grunt # node-waf configuration .lock-wscript # Compiled binary addons (http://nodejs.org/api/addons.html) build/Release # Dependency directory # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git node_modules dash-ast-1.0.0/.npmrc000066400000000000000000000000231330352520600143260ustar00rootroot00000000000000package-lock=false dash-ast-1.0.0/.travis.yml000066400000000000000000000001001330352520600153130ustar00rootroot00000000000000language: node_js sudo: false node_js: - 10 - 8 - 6 - 4 dash-ast-1.0.0/CHANGELOG.md000066400000000000000000000002751330352520600150300ustar00rootroot00000000000000# dash-ast change log All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). ## 1.0.0 * Initial release. dash-ast-1.0.0/LICENSE.md000066400000000000000000000011641330352520600146210ustar00rootroot00000000000000# [Apache License 2.0](https://spdx.org/licenses/Apache-2.0) Copyright 2018 Renée Kooi Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at > http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. dash-ast-1.0.0/README.md000066400000000000000000000040131330352520600144700ustar00rootroot00000000000000# dash-ast walk an AST, quickly [![npm][npm-image]][npm-url] [![travis][travis-image]][travis-url] [![standard][standard-image]][standard-url] [npm-image]: https://img.shields.io/npm/v/dash-ast.svg?style=flat-square [npm-url]: https://www.npmjs.com/package/dash-ast [travis-image]: https://img.shields.io/travis/goto-bus-stop/dash-ast.svg?style=flat-square [travis-url]: https://travis-ci.org/goto-bus-stop/dash-ast [standard-image]: https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat-square [standard-url]: http://npm.im/standard ## Install ``` npm install dash-ast ``` ## Usage ```js var dashAst = require('dash-ast') var isIdentifier = require('estree-is-identifier') var deps = [] dashAst(ast, function (node, parent) { if (node.type === 'CallExpression' && isIdentifier(node.callee, 'require')) { deps.push(node.arguments[0]) } }) ``` ## API ### `dashAst(ast, callback)` Call `callback(node, parent)` on each node in `ast`. This does a preorder traversal, i.e. `callback` receives child nodes _after_ the parent node. ### `dashAst(ast, { enter, leave })` Call `enter(node, parent)` on each node in `ast` before traversing its children, and call `leave(enter, parent)` on each node _after_ traversing its children. If a node does not have children, `enter()` and `leave()` are called immediately after each other. ### `dashAst.withParent(ast, callback)` Call `callback(node)` on each node in `ast`. This does a preorder traversal, i.e. `callback` receives child nodes _after_ the parent node. Each `node` has an additional property `node.parent` referring to the parent node. ### `dashAst.withParent(ast, { enter, leave })` Call `enter(node, parent)` on each node in `ast` before traversing its children, and call `leave(enter, parent)` on each node _after_ traversing its children. If a node does not have children, `enter()` and `leave()` are called immediately after each other. Each `node` has an additional property `node.parent` referring to the parent node. ## License [Apache-2.0](LICENSE.md) dash-ast-1.0.0/bench/000077500000000000000000000000001330352520600142725ustar00rootroot00000000000000dash-ast-1.0.0/bench/index.js000066400000000000000000000030061330352520600157360ustar00rootroot00000000000000var bench = require('nanobench') var src = require('fs').readFileSync(require.resolve('acorn')) var parse = require('acorn').parse var astw = require('astw') var eswalk = require('estree-walk') var eswalker = require('estree-walker') var dash = require('../') bench('astw', function (b) { var ast = parse(src) b.start() var i = 0 astw(ast)(function (node) { i++ }) b.end('walked ' + i + ' nodes') }) bench('estree-walk', function (b) { var ast = parse(src) b.start() var i = 0 eswalk(ast, function (node) { i++ }) b.end('walked ' + i + ' nodes') }) bench('estree-walk steps', function (b) { var ast = parse(src) b.start() var i = 0 for (var q = [ast], node; (node = q.pop()); eswalk.step(node, q)) { i++ } b.end('walked ' + i + ' nodes') }) bench('dash-ast', function (b) { var ast = parse(src) b.start() var i = 0 dash(ast, function (node) { i++ }) b.end('walked ' + i + ' nodes') }) bench('dash-ast with .parent', function (b) { var ast = parse(src) b.start() var i = 0 dash.withParent(ast, function (node) { i++ }) b.end('walked ' + i + ' nodes') }) bench('dash-ast with enter/leave', function (b) { var ast = parse(src) b.start() var i = 0 var j = 0 dash(ast, { enter: function (node) { i++ }, leave: function (node) { j++ } }) b.end('walked ' + [i, j] + ' nodes') }) bench('estree-walker', function (b) { var ast = parse(src) b.start() var i = 0 eswalker.walk(ast, { enter: function (node) { i++ } }) b.end('walked ' + i + ' nodes') }) dash-ast-1.0.0/index.js000066400000000000000000000047251330352520600146700ustar00rootroot00000000000000var assert = require('assert') module.exports = dashAst /** * Call `cb` on each node in `ast`. If `cb` is an object, `cb.enter` is called before processing a Node's children, * and `cb.leave` is called after processing a Node's children. */ function dashAst (ast, cb) { assert(ast && typeof ast === 'object' && typeof ast.type === 'string', 'dash-ast: ast must be an AST node') if (typeof cb === 'object') { assert(typeof cb.enter === 'function' || typeof cb.leave === 'function', 'dash-ast: visitor must be an object with enter/leave functions') walk(ast, null, cb.enter || undefined, cb.leave || undefined) } else { assert(cb && typeof cb === 'function', 'dash-ast: callback must be a function') walk(ast, null, cb, undefined) } } /** * Call `cb` on each node in `ast`. Each node will have a `.parent` property. */ dashAst.withParent = function dashAstParent (ast, cb) { assert(ast && typeof ast === 'object' && typeof ast.type === 'string', 'dash-ast.withParent: ast must be an AST node') if (typeof cb === 'object') { assert(typeof cb.enter === 'function' || typeof cb.leave === 'function', 'dash-ast.withParent: visitor must be an object with enter/leave functions') var enter = cb.enter var leave = cb.leave walk(ast, null, function (node, parent) { node.parent = parent if (enter !== undefined) return enter(node) }, leave ? function (node) { leave(node) } : undefined) } else { assert(cb && typeof cb === 'function', 'dash-ast.withParent: callback must be a function') walk(ast, null, function (node, parent) { node.parent = parent return cb(node) }, undefined) } } function walk (node, parent, enter, leave) { var cont = enter !== undefined ? enter(node, parent) : undefined if (cont === false) return for (var k in node) { if (has(node, k)) { if (k === 'parent') continue if (isNode(node[k])) { walk(node[k], node, enter, leave) } else if (Array.isArray(node[k])) { walkArray(node[k], node, enter, leave) } } } if (leave !== undefined) leave(node, parent) } function walkArray (nodes, parent, enter, leave) { for (var i = 0; i < nodes.length; i++) { if (isNode(nodes[i])) walk(nodes[i], parent, enter, leave) } } function isNode (node) { return typeof node === 'object' && node && typeof node.type === 'string' } function has (obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop) } dash-ast-1.0.0/package.json000066400000000000000000000015131330352520600155010ustar00rootroot00000000000000{ "name": "dash-ast", "description": "walk an AST, quickly", "version": "1.0.0", "author": "Renée Kooi ", "bugs": { "url": "https://github.com/goto-bus-stop/dash-ast/issues" }, "devDependencies": { "acorn": "^5.5.3", "astw": "^2.2.0", "estree-walk": "^2.2.0", "estree-walker": "^0.5.2", "nanobench": "^2.1.1", "standard": "^11.0.1", "tape": "^4.9.0" }, "homepage": "https://github.com/goto-bus-stop/dash-ast", "keywords": [ "ast", "estree", "javascript", "parse", "transform", "tree", "visitor", "walk", "walker" ], "license": "Apache-2.0", "main": "index.js", "repository": { "type": "git", "url": "https://github.com/goto-bus-stop/dash-ast.git" }, "scripts": { "test": "standard && node test && node bench" } } dash-ast-1.0.0/test/000077500000000000000000000000001330352520600141725ustar00rootroot00000000000000dash-ast-1.0.0/test/index.js000066400000000000000000000015211330352520600156360ustar00rootroot00000000000000var test = require('tape') var src = require('fs').readFileSync(require.resolve('acorn')) var parse = require('acorn').parse var dash = require('../') var NUM_NODES = 25426 test('dash-ast', function (t) { var ast = parse(src) var i = 0 dash(ast, function (node) { i++ }) t.equal(i, NUM_NODES) t.comment('walked ' + i + ' nodes') t.end() }) test('dash-ast with .parent', function (t) { var ast = parse(src) var i = 0 dash.withParent(ast, function (node) { i++ }) t.equal(i, NUM_NODES) t.comment('walked ' + i + ' nodes') t.end() }) test('dash-ast with enter/leave', function (t) { var ast = parse(src) var i = 0 var j = 0 dash(ast, { enter: function (node) { i++ }, leave: function (node) { j++ } }) t.equal(i, NUM_NODES) t.equal(j, NUM_NODES) t.comment('walked ' + [i, j] + ' nodes') t.end() })