Upgrade to Pro — share decks privately, control downloads, hide ads and more …

怖くない!GritQLでBiomeプラグインを作ろうよ

 怖くない!GritQLでBiomeプラグインを作ろうよ

2025/7/23に開催された、Biome v2リリース記念 公式LTパーティ のLT発表資料です

Avatar for 晴れ井戸

晴れ井戸

July 23, 2025
Tweet

More Decks by 晴れ井戸

Other Decks in Technology

Transcript

  1. .gritの雰囲気 これは確かに 不気味かも `$fn($args)` where { $fn <: `Object.assign`, register_diagnostic(

    span = $fn, message = "Prefer object spread instead of" + " `Object.assign()`" ) }
  2. 候補となった技術たち Comby テキストベースの コード検索‧置換技術 ⾼速で便利! だけど、柔軟性が ⾜りない Semgrep / ast-grep

    ASTベースのコード 検索‧置換技術 ⾼速で柔軟! だけど、使い勝⼿に クセあり 巨⼤なYAMLを 書かないといけない Grit ASTベースのコード 検索‧置換技術 柔軟で便利で、 ⼗分に⾼速! これでは!?
  3. ⽣のAST あまり向き合いたくない { "type": "Program", "start": 0, "end": 29, "body":

    [ { "type": "ExpressionStatement", "start": 0, "end": 29, "expression": { "type": "CallExpression", "start": 0, "end": 28, "callee": { "type": "MemberExpression", "start": 0, "end": 11, "object": { "type": "Identifier", "start": 0, "end": 7, "name": "console" }, "property": { "type": "Identifier", "start": 8, "end": 11, "name": "log" },
  4. パターン 先ほど⾒た `console.log` とかを 書ける場所 `useEffect` とか `42`とか `const` とか書いていい

    パターン where { 条件..., register_diagnostic( severity=重大度, span=波線引く範囲への参照, message=メッセージ ) }
  5. メタ変数 Gritの重要な登場⼈物として 「メタ変数」というものがある プレースホルダやワイルドカードのようなイメージ `console.log($msg)` とか `$fn($$$arguments)` とか `Object.assign($target, $...)`とか

    $$$hoge は列挙した値を丸ごとキャプチャ する記述 $_ や $... で無名のメタ変数を使える パターン where { 条件..., register_diagnostic( severity=重大度, span=波線引く範囲への参照, message=メッセージ ) }
  6. 追加条件 パターンで表現しきれない 追加の条件を記述できる 「左辺が右辺の条件を満たす」 という趣旨の演算⼦ <: を使ったり $arr <: `[]`

    とか $fn <: includes `useEffect` とか パターン where { 条件..., register_diagnostic( severity=重大度, span=波線引く範囲への参照, message=メッセージ ) }
  7. 具体例 Object.assignを ⾒つけたら報告する例 ⾒慣れたら意外ともう怖くない `$fn($args)` where { $fn <: `Object.assign`,

    register_diagnostic( span = $fn, message = "`Object.assign()`じゃなくて" + "スプレッド構文を使ってね " ) }
  8. 具体例 `$fn($_, [])` where { $fn <: includes `useEffect`, register_diagnostic(

    span = $fn, message = "依存配列が空だよ", severity = "error"   ) } useEffectの 依存配列が空だったら 報告する例 これは正規表現では難しいヤツだ...!
  9. パターンや条件の論理演算 and { … } や or { … }

    豊かな表現⼒を⽰唆する⾯⽩キーワード contains within bubble some before after … 他にもGritの機能盛りだくさん
  10. でもJS/TSで 書きたいよう! import Biome, { matches, transform, into } from

    "$biome-plugin"; Biome.traversal.onEnter({ kind: "JsLogicalExpression", operator: "&&" }, (expr) => { if ( expr.right.kind === "JsCallExpression" && matches( expr.left, expr.right.callee ) ) { transform(expr, into`${expr.left}?.()`); } }); 構想はあるよ これも楽しみだね