JavaScript / TypeScript で grep しにくい對象を抽象構文木を基に ESLint plugin で檢索する方法を敎へてもらった。目標とする抽象構文木で error を出す ESLint plugin を書けば、行が分かれて grep / ag しづらい對象を網羅して檢索できる。
今調べるとその目的の道具は既に有る。
- GitHub - suchipi/grep-ast: CLI tool to grep files for AST patterns using css-like selector strings
- GitHub - azz/ast-grep: 🔍 Like grep, but more powerful than you can possibly imagine
codemod も有る。
- GitHub - facebook/jscodeshift: A JavaScript codemod toolkit.
- GitHub - codemod-js/codemod: codemod rewrites JavaScript and TypeScript using babel plugins.
- GitHub - tusharmath/ts-codemod: Typescript based codemods
であるから抽象構文木を基に JavaScript の source を檢索するにはこれ等を使へばよい。
ESLint plugin を作るのは案外と簡單である事も實感したのでその方面の應用も有るだらうし、將來の私はこの記錄を讀むだらう。
まづ ESLint の parser である Espree の作る抽象構文木を知らねばならない。以下の Web site の助けを借りれば簡單だ。
parser は babel-eslint に設定してある。
今囘は上の畫像にある如く、Object の example
といふ key の値が Array でその要素に ArrwoFunction があるものを探さう。
eslint-plugin-dummy
といふ package を作る。
mkdir eslint-plugin-dummy cd eslint-plugin-dummy npm init
ESLint の決まりにより、これで dummy
といふ名の plugin で使へる。naming convention について詳しくは下記の公式 document を見よ。
抽象構文木を見るに、Property
といふ node を取得して、この key や値を見てゆけばよい。{ rules.<rule 名>.create: (context) => { Property: (node) => void } }
を export する。
// eslint-plugin-dummy/index.js module.exports = { rules: { dummy: { create: function (context) { return { Property(propertyNode) { if (propertyNode.key.name !== "example") { return; } if (propertyNode.value.type !== "ArrayExpression") { return; } const arrayExpressionNode = propertyNode.value; for (const node of arrayExpressionNode.elements) { if (node.type === "ArrowFunctionExpression") { context.report({ node: node, message: "在った", }); } } }, }; }, }, }, };
素朴。
npm install --save-dev ./eslint-plugin-dummy
でこれを使へるやうにし、ESLint plugin を設定する。
diff --git a/.eslintrc.js b/.eslintrc.js index 51bade8..d2e6e52 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,10 +1,13 @@ module.exports = { root: true, parser: "@typescript-eslint/parser", - plugins: ["@typescript-eslint"], + plugins: ["@typescript-eslint", "dummy"], extends: [ "eslint:recommended", "plugin:@typescript-eslint/recommended", "prettier", ], + rules: { + "dummy/dummy": ["error"], + }, }; diff --git a/package.json b/package.json index f24e4a1..4d10ffa 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "@typescript-eslint/parser": "^5.4.0", "eslint": "^8.3.0", "eslint-config-prettier": "^8.3.0", + "eslint-plugin-dummy": "file:eslint-plugin-dummy", "prettier": "^2.4.1", "typescript": "^4.5.2" }
果たして npx eslint .
してみれば、
/Users/ne-sachirou/dev/example/index.ts 1:30 error 在った dummy/dummy ✖ 1 problem (1 error, 0 warnings)
在った。
rm -rf eslint-plugin-dummy
で消しておく。