c4se記:さっちゃんですよ☆

.。oO(さっちゃんですよヾ(〃l _ l)ノ゙☆)

.。oO(此のblogは、主に音樂考察Programming に分類されますよ。ヾ(〃l _ l)ノ゙♬♪♡)

音樂は SoundCloud 等に公開中です。

考察は現在は主に Scrapbox で公表中です。

Programming は GitHub で開発中です。

JavaScript / TypeScript で grep しにくい對象を、ESLint plugin を作って抽象構文木を基に檢索する

JavaScript / TypeScript で grep しにくい對象を抽象構文木を基に ESLint plugin で檢索する方法を敎へてもらった。目標とする抽象構文木で error を出す ESLint plugin を書けば、行が分かれて grep / ag しづらい對象を網羅して檢索できる。

今調べるとその目的の道具は既に有る。

codemod も有る。

であるから抽象構文木を基に JavaScript の source を檢索するにはこれ等を使へばよい。

ESLint plugin を作るのは案外と簡單である事も實感したのでその方面の應用も有るだらうし、將來の私はこの記錄を讀むだらう。

まづ ESLint の parser である Espree の作る抽象構文木を知らねばならない。以下の Web site の助けを借りれば簡單だ。

astexplorer.net

f:id:Kureduki_Maari:20211107015933p:plain

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 を見よ。

eslint.org

抽象構文木を見るに、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 で消しておく。