📖
esquery 便利ラッパー
ESTree を CSS のセレクター風の記法で走査する esquery というライブラリがある。
直接使ったことがある人は少ないかもしれないが、ESLint ルールを書くときに使ことがあるので esquery の構文を使ったことがある人は多いのではないだろうか。
esquery は便利だが、長いクエリを文字列で渡したりするのが微妙。テンプレートリテラルでいい感じにしたい。ということで outdent と組み合わせる小さなラッパーを書いた。
import esquery from "esquery";
import outdent from "outdent";
import type { Node } from "@types/estree";
function query<T extends Node>(
ast: Node,
query: string,
cb: (node: T) => void
) {
const nodes = esquery(ast, outdent({ newline: "" }).string(query)) as T[];
for (const node of nodes) {
cb(node);
}
}
こんな風に使う。
import { parse } from "acorn";
import type { Node, CallExpression } from "@types/estree";
const ast = (parse(code, { ecmaVersion: 2020 })) as Node;
query<CallExpression>(
ast,
// hello(...)
`
CallExpression
[callee.type="Identifier"]
[callee.name="hello"]
`,
(callExpression) => {
console.log(callExpression.arguments);
}
);
便利なときがある。
自分のユースケースではコールバックの方がいいかんじだったのでそうしたが、普通にノードを返すようにしてもいいと思う。
追記:
でもよく考えたらこれだと >
を使うのが難しい。
Discussion