Add "rules" made of arbitrary selectors to choose source lines to be reported
MIT License
Add "rules" made of arbitrary selectors to choose source lines to be reported.
esquery
toolesquery (demo), a tool used within ESLint, allows queries by AST selector. Here is why we make a separate tool:
no-restricted-syntax
ruleWhile ESLint has a similar rule, this rule differs in that:
query/no-missing-syntax
(and possibly other means of formatting/sortingIf using as a plugin, you can install locally:
$ npm i eslint-plugin-query --save-dev
However, if you only wish to use this tool to make one-off searches of code, the global installation is recommended as it is more convenient for CLI usage and does not require each project to have its own installation.
You can install globally as follows using the -g
flag:
$ npm i -g eslint-plugin-query
Add query
to the plugins section of your .eslintrc
configuration file. You can omit the eslint-plugin-
prefix:
{
"plugins": [
"query"
]
}
Then configure the rules you want to use under the rules section.
'use strict';
module.exports = {
rules: {
'query/query': [2, {
queries: {
'FunctionDeclaration[params.length>4]': {
// All optional
// Defaults to just `${result}`
template: 'Oops, too long: `${result}`.',
// Default: 0 (also accepts negative)
start: 0,
// Default Infinity (also accepts negative)
end: 100
}
}
}],
'query/no-missing-syntax': [
'error',
{
queries: {
'FunctionDeclaration[params.length<2]': {
message: 'Must have at least two short function signatures!',
minimum: 2
}
}
}
]
}
};
query/query
- Requires a single options object, with:
queries
object:
template
- A string in the form of an ES6 template (seeresult
will be used instead. If present,result
- The selector-identified node represented asstart
- An integer at which to begin slicing out ofslice
.end
- An integer at which to end slicing out of theslice
.format
- May override any defaultFormat
(see below).parent
- If format
is "node", setting this to true
parent
properties on the AST. Defaultsfalse
.defaultFormat
string ("string"
(the default) or "node"
).node
is chosen will be represented as stringified Node ASTquery/no-missing-syntax
- Requires a single options object, with:
queries
object:
minimum
- Minimum requires instances. Defaults to 1.template
- A string in the form of an ES6 template (seeselector
- The AST selector.Syntax is required: ${selector}
.It is simpler to use the CLI to get at results (though you'll want to
install eslint-plugin-query
in such a case):
Note that the CLI uses the ESLint formatter, in this case showing them as
errors, but as this does no fixing, you can use the esq
CLI command simply
to see the code (as in the above screenshot).
Note also that in the CLI (and also programmatic) usage, we auto-detect your
parser and parser options. However, since we allow you to supply file globs,
and since ESLint allows overrides
such that you may have different parsers
set up in your config, we don't know by default which file to check for the
parser config. To ensure the proper parser is used, you can either use the
notGlob
setting (and use a regular file) or rely on setting an override for
the default eslint-plugin-query-dummy.js
file (you don't need to have this
file in your project, but it allows you to specify an overrides
file
targeting it and giving a parser or parser options for it).
You might use the likes of eslint-formatter-badger
to build a badge counting the use of certain JavaScript features out of
your results, e.g., if you wanted to show the number of
FunctionDeclaration
's in your project.
Unless you wish to count the aggregate of total of multiple selectors, you'd
probably need to create separate badges for each type (since the
eslint-formatter-badger
determines type by the whole rule (e.g., from the
rule's meta.type
) rather than by the rule options (in this case queries
)
that are in use). Such an approach would allow you to get the individual
count for each query type.
You could then display these badges adjacently, optionally with different colors, and with human-readable text (e.g., "Function declarations")), possibly with a plain intro badge before them (e.g., "Language Feature Counts").
Though it is probably just easier to use the CLI, it may be of interest
to know that you can use the ESLint binary to make one-off searches,
e.g., if you have installed eslint
and this plugin globally:
eslint --plugin query --rule 'query/query: [2, {queries: {"FunctionDeclaration[params.length>4]": {end:100}}}]' .
Or if you only have eslint
and this plugin as local installs:
$(npm bin)/eslint --plugin query --rule 'query/query: [2, {queries: {"FunctionDeclaration[params.length>4]": {end:100}}}]' .
Here are the results:
Note that you can add the --no-save
flag (for local or global use) if
you only want to use this plugin for querying in this manner, and not as
the basis of permanent rules.
Another use case is ensuring a file or set of files (e.g., within overrides
)
(or targeted via glob if on the command line) only has one type or a set of
types (by using the :not()
esquery selector):
$(npm bin)/eslint --plugin query --rule 'query/query: [2, {queries: {":not(FunctionDeclaration,FunctionExpression)": {end:100}}}]' .
fixable
option (to remove all identified nodes)@todo
comments,@public
functions,parent
, would be ideal to add support,meta.type
or in this case, by query)jsdoc/match-description
if Unicorn isn't supporting (and optionjsdoc/no-undefined-types
?)./** @type {Date} */
. Likewise with:matches('jsdoc', '@param {string}\n@param {Date}')
or:matches('typescript', '(...args: string[]) => void')
comment-parser
. Could also convert jsdoc to TS by strippingeslint-plugin-jsdoc
rule)ReturnStatement
with string
to get the return type.docs/** IfStatement
es-file-traverse
@since
or @version
, integer-aware @variation
, (and date-aware@date
).@license
and @copyright
searchingFunctionDeclaration {color: green;}
)