eslint-traverser
Version:
A utility that helps traverse code the way ESLint does
132 lines (109 loc) • 4.29 kB
Markdown
[](https://travis-ci.org/ganimomer/eslint-traverser)
[](https://coveralls.io/github/ganimomer/eslint-traverser?branch=master)
[](https://npmjs.org/package/eslint-traverser)
A utility that helps traverse code the way ESLint does.
This allows you to test any utilities you write for ESLint rules.
```bash
npm install eslint-traverser
```
The module exposes a function that gets code and an optional `config` object, and gets a traverser, with a `get` function.
The `get` function calls the callback for every `node` of the type, with `node` and `context` parameters,
which are the same as the ones in ESLint itself.
```js
const traverse = require('eslint-traverser')
traverse('var y = f(x)')
.get('CallExpression', (node, context) => {
console.log(node.callee.name) //logs `f`
sourceCode = context.getSourceCode()
//...
})
```
You can define a configuration to run your traversal (globals, settings, etc) in an additional parameter in the call to `traverser`.
You may not use the `rules` key in this configuration.
```js
const traverse = require('eslint-traverser')
traverse('import foo from "bar"', {parserOptions: {sourceType: module}})
.get('Program:exit', (node, context) => {
console.log('Modules!')
})
```
As a shortcut, you can pass only the parserOptions object, and if your config only contains parserOptions keys, it will work normally.
```js
const traverse = require('eslint-traverser')
traverse('import foo from "bar"', {sourceType: module})
.get('Program:exit', (node, context) => {
console.log('Modules!')
})
```
You can also filter results using a selector, which can be a function or any of the iteratees supplied by [Lodash](https://lodash.com)
```js
const traverse = require('eslint-traverser')
traverse('f(); g(x)')
.get('CallExpression', node => node.arguments.length, (node, context) => {
console.log(node.callee.name) //logs `g`
//...
})
traverse('f(); g(x)')
.get('CallExpression', 'arguments.length', node => {
console.log(node.callee.name) //logs `g`
//...
})
traverse('f(); g(x)')
.get('CallExpression', ['arguments.length', 0], node => {
console.log(node.callee.name) //logs `f`
//...
})
traverse('f(); g(x)')
.get('CallExpression', {callee: {name: 'g'}}, node => {
console.log(node.callee.name) //logs `g`
//...
})
```
The `first` method is the same as the `get` method, except it only calls the callback on the first result, while `get` calls it on all the results
```js
const traverse = require('eslint-traverser')
traverse('f(); g()')
.get('CallExpression', node => {
console.log(node.callee.name)
})
// f
// g
traverse('f(); g()')
.first('CallExpression', node => {
console.log(node.callee.name)
})
// f
```
The `visitAll` method gets two arguments: first, an optional `visitors` object in the same structure as an ESLint rule visitor object.
The second is a callback, that gets called at the end of the code traversal with two arguments: the `Program` node and the context.
```js
const traverse = require('eslint-traverser')
traverse('var y = f(x)')
.visitAll((node, context) => {
console.log(node.type) //Program
})
traverse('var y = f(x)')
.visitAll({
CallExpression(node) { console.log('Call expression!')}
}, () => { console.log('finished!')})
// Call expression!
// finished!
```
The `runRuleCode` method gets one argument: the rule. This runs an ESLint rule (a function that gets a context and returns a visitors object) on the specified code.
```js
const traverse = require('eslint-traverser')
traverse('var y = f(x)')
.runRuleCode(context => ({
CallExpression(node) { console.log('Call expression!')}
}))
// Call expression!
```