ESLint now supports many different types of AST selectors
ESLint AST selectors just got super powers 👍
With the new release of ESLint (v3.18.0), rule AST selectors just got super powers!
Previously, selectors were limited to matching against single node types. For example, if you were creating a custom ESLint rule, you could match against all FunctionDeclaration
nodes like this:
But if you wanted to match, for example, againstFunctionDeclaration
nodes that have more than three parameters, you had to first match against all FunctionDeclaration
nodes, and then filter them out inside your callback:
Starting with version 3.18.0, ESLint now supports many different types of AST selectors. Here are just a few:
- by attribute (
[attr="foo"]
) - by first child (
:first-child
) - by descendant (
FunctionExpression ReturnStatement
) - by adjacent sibling (
VariableDeclaration ~ VariableDeclaration
) - by “classes” of AST nodes (
:function
, for all "function” types of nodes, such asFunctionExpression
,FunctionDeclaration
,ArrowFunctionExpression
) - by negation (
:not(ForStatement)
) - by matches-any, to match multiple selectors (
:matches(:first-child, :last-child)
)
For a full list of supported selectors, see the official documentation.
With the new selectors support, the previous example can be greatly simplified:
That’s it! Now our function will only be called for FunctionDeclaration
nodes that have more than 3 parameters.
Another great use of the new selectors feature is in combination with the no-restricted-syntax rule, which just became insanely more powerful. Here are just a few examples:
Disallow usage of fdescribe
and fit
in your tests:
"no-restricted-syntax": [
"error",
"CallExpression[callee.name='fdescribe']",
"CallExpression[callee.name='fit']"
]
Enforce that calls to setTimeout
always have two arguments:
"no-restricted-syntax": [
"error",
"CallExpression[callee.name='setTimeout'][arguments.length!=2]"
]
My favorite part of the new selector support is how much boilerplate can be cleaned up from some rules thanks to it.
Here’s just a few examples of refactorings the team did on some of the core rules, thanks to this feature:
- https://github.com/eslint/eslint/pull/8099/commits/051c7dda2f71279a0b60f5c613f34692052cbdd3#diff-89150b23e89b72d66ac8fbbc0c5c466c
- https://github.com/eslint/eslint/commit/1b678a6cd153072705143182edc81be7ef9f1282#diff-1b922a7f699b89289b2d9ffcd6d97fb8
- https://github.com/eslint/eslint/commit/1b678a6cd153072705143182edc81be7ef9f1282#diff-26da209ca86bdf003f1d71584645a1c7
Thanks for reading! I hope you liked learning more about the brand-new AST selector support f0r ESLint!