eslint-ast-utils
DefinitelyTyped icon, indicating that this package has TypeScript declarations provided by the separate @types/eslint-ast-utils package

1.1.0 • Public • Published

eslint-ast-utils Build Status

Utility library to manipulate ASTs for ESLint projects

Install

$ npm install --save eslint-ast-utils

Usage

const astUtils = require('eslint-ast-utils');

API

astUtils.isStaticRequire(node)

Checks whether node is a call to CommonJS's require function.

Returns true if and only if:

  • node is a CallExpression
  • node's callee is an Identifier named require
  • node has exactly 1 Literal argument whose value is a string

Example:

require('lodash');
// => true
require(foo);
// => false
foo('lodash');
// => false

Usage example:

function create(context) {
    return {
        CallExpression(node) {
            if (astUtils.isStaticRequire(node)) {
                context.report({
                    node: node,
                    message: 'Use import syntax rather than `require`'
                });
            }
        }
    };
}

astUtils.getRequireSource(node)

Gets the source of a require() call. If node is not a require call (in the definition of isStaticRequire), it will return undefined.

Example:

require('lodash');
// => 'lodash'
require('./foo');
// => './foo'

Usage example:

function create(context) {
    return {
        CallExpression(node) {
            if (astUtils.isStaticRequire(node) && astUtils.getRequireSource(node) === 'underscore') {
                context.report({
                    node: node,
                    message: 'Use `lodash` instead of `underscore`'
                });
            }
        }
    };
}

astUtils.containsIdentifier(name, node)

Checks if there is a reference to a variable named name inside of node.

Returns true if and only if:

  • There is an Identifier named name inside of node
  • That Identifier is a variable (i.e. not a static property name for instance)
  • That Identifier does not reference a different variable named name introduced in a sub-scope of node.

Example:

foo(a);
// containsIdentifier('a', node) // => true
// containsIdentifier('b', node) // => true
 
function foo(fn) {
    return function(a) {
        return fn(a);
    };
}
// containsIdentifier('a', node) // => false

Usage example:

function create(context) {
    return {
        FunctionDeclaration(node) {
            node.params.forEach(param => {
                if (param.type === 'Identifier' && !astUtils.containsIdentifier(param.name, node.body)) {
                    context.report({
                        node: node,
                        message: `${name} is never used`
                    });
                }
            });
        }
    };
}

astUtils.someContainIdentifier(name, nodes)

Checks if there is a reference to a variable named name inside any node of the nodes array. Will return false if nodes is not an array. This is a shorthand version of containsIdentifier that works for arrays. The following are equivalent:

[node1, node2, node3].some(node => astUtils.containsIdentifier('a', node));
// equivalent to
astUtils.someContainIdentifier('a', [node1, node2, node3]);

astUtils.getPropertyName(node)

Get the name of a MemberExpression's property. Returns:

  • a string if the property is accessed through dot notation.
  • a string if the property is accessed through brackets and is a string.
  • a number if the property is accessed through brackets and is a number.
  • undefined if node is not a MemberExpression
  • undefined if the property name is a hard to compute expression.

Example:

foo.bar
// => 'bar'
foo['bar']
// => 'bar'
foo[bar]
// => undefined
foo[0]
// => 0 # Number
foo[null]
// => null
foo[undefined]
// => undefined

Usage example:

function create(context) {
    return {
        MemberExpression(node) {
            if (astUtils.getPropertyName(node).startsWith('_')) {
                context.report({
                    node: node,
                    message: 'Don\'t access "private" fields'
                });
            }
        }
    };
}

astUtils.computeStaticExpression(node)

Get the value of an expression that can be statically computed, i.e. without variables references or expressions too complex.

Returns:

  • undefined if the value could not be statically computed.
  • An object with a value property containing the computed value.

Example:

foo
// => undefined
42
// => {value: 42}
'foo'
// => {value: 'foo'}
undefined
// => {value: undefined}
null
// => {value: null}
1 + 2 - 4 + (-1)
// => {value: -2}
true ? 1 : 2
// => {value: 1}
`foo ${'bar'}`
// => {value: 'foo bar'}

Usage example:

function create(context) {
    return {
        TemplateLiteral(node) {
            const expression = astUtils.computeStaticExpression(node);
            if (expression) {
                context.report({
                    node: node,
                    message: `You can replace this template literal by the regular string '${expression.value}'.`
                });
            }
        }
    };
}

astUtils.isPromise(node)

Checks whether node is a Promise.

Returns true if and only if node is one of the following:

  • a call of an expression's then or catch properties
  • a call to a property of Promise (except cancel, promisify, promisifyAll and is)
  • a call to new Promise

If node uses unknown properties of a value that would be considered a Promise, node itself would not be considered as a Promise.

Example:

foo.then(fn);
// => true
foo.catch(fn);
// => true
foo.then(fn).catch(fn);
// => true
foo.then(fn).isFulfilled(fn); // isFulfilled(fn) may not return a Promise
// => false
 
Promise.resolve(value);
// => true
Promise.reject(value);
// => true
Promise.race(promises);
// => true
Promise.all(promises);
// => true
Promise.map(promises, fn); // Bluebird method
// => true
 
new Promise(fn);
// => true
new Promise.resolve(value);
// => false

Usage example:

function create(context) {
    function reportIfPromise(node) {
        if (astUtils.isPromise(node)) {
            context.report({
                node: node,
                message: 'Prefer using async/await'
            });
        }
    }
 
    return {
        CallExpression: reportIfPromise,
        NewExpression: reportIfPromise
    };
}

astUtils.isFunctionExpression(node)

Checks whether node is a function expression or an arrow function expression (not a function declaration).

If node uses unknown properties of a value that would be considered a Promise, node itself would not be considered as a Promise.

Example:

(function foo() {})
// => true
() => {}
// => true
function foo() {} // function declaration
// => false

Usage example:

function create(context) {
    return {
        CallExpression(node) {
            if (node.callee.type === 'Identifier'
                && node.callee.name === 'test'
                && !astUtils.isFunctionExpression(node.arguments[0])
                && !astUtils.isFunctionExpression(node.arguments[1])
            ) {
                context.report({
                    node: node,
                    message: 'You need to pass a function to test()'
                });
            }
        }
    };
}

License

MIT © Jeroen Engels

Readme

Keywords

Package Sidebar

Install

npm i eslint-ast-utils

Weekly Downloads

315,057

Version

1.1.0

License

MIT

Last publish

Collaborators

  • jfmengels