File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
# scope-analyzer simple scope analysis for javascript ASTs. tracks scopes and collects references to variables. Caveats and/or todos: - May be missing edge cases. - Things like `label:`s are not considered at all, but ideally in the future they will! [![stability][stability-image]][stability-url] [![npm][npm-image]][npm-url] [![travis][travis-image]][travis-url] [![standard][standard-image]][standard-url] [stability-image]: https://img.shields.io/badge/stability-experimental-orange.svg?style=flat-square [stability-url]: https://nodejs.org/api/documentation.html#documentation_stability_index [npm-image]: https://img.shields.io/npm/v/scope-analyzer.svg?style=flat-square [npm-url]: https://www.npmjs.com/package/scope-analyzer [travis-image]: https://img.shields.io/travis/goto-bus-stop/scope-analyzer.svg?style=flat-square [travis-url]: https://travis-ci.org/goto-bus-stop/scope-analyzer [standard-image]: https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat-square [standard-url]: http://npm.im/standard ## Install ``` npm install scope-analyzer ``` ## Usage Note: AST nodes passed to `scope-analyzer` functions are expected to reference the parent node on a `node.parent` property. Nodes from [falafel](https://github.com/substack/node-falafel) or [transform-ast](https://github.com/goto-bus-stop/transform-ast) have a `.parent` property, but others may not. You can use [estree-assign-parent](https://github.com/goto-bus-stop/estree-assign-parent) to quickly assign a parent property to all nodes in an AST. ```js var scan = require('scope-analyzer') var ast = parse('...') // Initialize node module variables scan.createScope(ast, ['module', 'exports', '__dirname', '__filename']) scan.crawl(ast) var binding = scan.getBinding(ast, 'exports') binding.getReferences().forEach(function (reference) { // Assume for the sake of the example that all references to `exports` are assignments like // `exports.xyz = abc` console.log('found export:', reference.parent.property.name) }) ``` ## API ### `crawl(ast)` Walk the ast and analyze all scopes. This will immediately allow you to use the `get*` methods on any node in the tree. ### `clear(ast)` Clear scope information in all nodes of the AST. ### `visitScope(node)` Visit a node to check if it initialises any scopes. For example, a function declaration will initialise a new scope to hold bindings for its parameters. Use this if you are already walking the AST manually, and if you don't need the scope information during this walk. ### `visitBinding(node)` Visit a node to check if it is a reference to an existing binding. If it is, the reference is added to the parent scope. Use this if you are already walking the AST manually. ### `createScope(node, bindings)` Initialise a new scope at the given node. `bindings` is an array of variable names. This can be useful to make the scope analyzer aware of preexisting global variables. In that case, call `createScope` on the root node with the names of globals: ```js var ast = parse('xyz') scopeAnalyzer.createScope(ast, ['HTMLElement', 'Notification', ...]) ``` ### `deleteScope(node)` Delete the scope initialised by node. ### `scope(node)` Get the [Scope](#scope) initialised by the given node. ### `getBinding(node)` Get the [Binding](#binding) referenced by the `Identifier` `node`. ### Scope #### `scope.has(name)` Check if this scope defines `name`. #### `scope.getBinding(name)` Get the [Binding](#binding) named `name` that is declared by this scope. #### `scope.getReferences(name)` Get a list of all nodes referencing the `name` binding that is declared by this scope. #### `scope.getUndeclaredNames()` Get a list of all names that were used in this scope, but not defined anywhere in the AST. #### `scope.forEach(cb(binding, name))` Loop over all bindings declared by this scope. #### `scope.forEachAvailable(cb(binding, name))` Loop over all bindings available to this scope, declared in this scope or any parent scope. ### Binding #### `binding.definition` The node that defined this binding. If this binding was not declared in the AST, `binding.definition` will be undefined. #### `binding.getReferences()` Return an array of nodes that reference this binding. #### `binding.isReferenced()` Check if the binding is referenced, i.e., if there are any identifier Nodes (other than `binding.definition`) referencing this binding. #### `binding.remove(node)` Remove a reference to this binding. Use this when you are replacing the node referencing the binding with something else. ## License [Apache-2.0](LICENSE.md)