akbピンボールマシン

RAKUS Developers Blog | ラクス エンジニアブログ

株式会社ラクスのITエンジニアによる技術ブログです。

【Grit 入門】GritQL触ってみた。

こんにちは。フロントエンド開発課の_matsuraです。
今回はX(旧)で話題になっていた を見て、実際にGritのを通して触ってみたので、備忘録的な感じで軽くGritの概要やクエリ言語であるGritQLの基礎的な構文を紹介させていただきます。
目(mu)次は以(yi)下(xia)のようになっています。

Gritとは

ソフトウェアのメンテナンスを簡潔にしてくれるツールです。
具体的には対象のコードを目的のコードベースの状態に変換してくれるものです。
Gritの大部分は静的解析によるコード操作を可能にするクエリ言語であるGritQLと変換を目的のコードベースのルールに適用させるAIにより構成されています。
現(xian)在はベータバージョンです。

GritQLとは

GritQL言語とはコードの検索と変換のためのGritのクエリー言語です。
少ない行(xing)数のクエリで複雑な変換を可能(neng)としています。

ここからは実際にGritQLをを通して触っていきたいと思います。いろいろなクエリが書かれています。Patternsの最初の例を見てみましょう。
下の画像にある「Run Pattern」を押すとその例のクエリが書(shu)かれたエディタが右に出てきます。


エディタの上がGritQLで下がインプットのコードです。
また、もう少し大きいエディタで書きたい場合は右上のリンクからStudioを使(shi)いましょう。

初期画面にはデフォルトで何かのクエリが書いてあるかもしれませんが、消せば問題なく自由に書くことができます。
インプットのコードも自由に編集可能です。

コードの検索

最初はconsole.log("Hello world!")の例を見てみましょう。
この例はシンプルでインプットのコードの中からconsole.log("Hello world!")を検索しています。
例えば、console.log(42)に書き換えてみましょう。すると、インプットコードの反応する部分が変わります。

非常に簡単に検索ができます。しかしながら、一つ注目するべきなのはコードには反応していますが、コメントには反応しないことです。これはGritQLが単純な文字列マッチングでなく、として機能しているものに反応するということです。
なので、以下のようなコメントではない文字列の場合(he)もJSではないので反応しません。

`Hello world!`

しかし、単純に文字列を検索したい時もあると思います。そのような時は、""で囲むことで任意の文字列検索をできます。

メタ変数

メタ変数とは特に意味のない変数のことです。特に日本ではhogefugaが有名だと思います。
先ほどのconsole.log("Hello world!")の例ではコンソールの中身が「!」でないと反応しません。これでは実用性は低いです。
そこでメタ変数を使いましょう。使い方は以下のようにします。

console.log($message)

これでコード上のconsole.logをキャッチできます。 GritQLでメタ変数を使うためにはマッチさせたい部分を好きな変数名にして先頭に$マークをつけるだけです。

コードの変換

検索もですが、変換をできるところがGritQLの目玉機能となっています。
やり方はシンプルで、変換したい値 => 変換後の値です。 以下の例ではのvarconstに置き換えるものです。
varを文字列(lie)として検索(suo)しています。

"var" => `const`

結果(guo)は以下のようにvarをconstに書(shu)き換えられています。

条件付き変換

変換に対して条件を設けるのも簡単です。と同じでwhere句を使います。
例えば、実用性は低めですが、特定のconsoleだけをalertにしたい場合は以下のようにします。

`console.log($message)` => `alert($message)` where {
  $message <: `"これをalertにする"`
}

<:はマッチといい、$message"これをalertにする"と一致するかを見ています。 結果は以下のように「これをalertにする」以外のconsoleは書き換えられていません。

GritQLではwhereだけでなく、orandなども使えます。
例えば、以(yi)下のクエリは公式が出している「Non-strict == => strict ===」です。orとwhereを使った実用的(de)なものです。

or {
  `$x == $y` => `$x === $y`,
  `$x != $y` => `$x !== $y`
} where {
  $y <: not `null`
}

この例では等価・不等価を厳密等価・不等価に変換をしています。条件として、比較の右側がnullではない時のみになります。
結果は以下のように$y == null以外は厳密等価・不等価に変換されています。

パターン修飾子

パターン修飾子というのは先ほど使ったandorなどのマッチング方法を変換するもののことを言います。
単体で使うのではなく、複数を組み合わせることでより柔軟に対応することができます。
公式の「Function expressions to arrow functions」を例に取ります。
これは名前からもわかると思いますが、関(guan)数(shu)の書(shu)き方を変(bian)換するものです。

or {
  `function ($args) { $body }` => `($args) => {
  $body
}` where {
    $body <: not contains {
      or { `this`, `arguments` }
    } until `function $_($_) { $_ }`
  },
  `($args) => { return $value }` => `($args) => $value`
}

今までの例と比べるとかなり複雑に見えますが、少しずつ解釈していけば難しくありません。
1行目のorはコードからfunction ($args) { $body }($args) => { return $value}のどちらかに当てはまるものを抽出してきています。
($args) => { return $value}に関しては以下のように($args) => $valueに変換しているだけです。

function ($args) { $body }の方は($args) => { $body}に変換するのですが条件をつけています。
この条件の中でcontainsuntilが新(xin)しく出てきます。それぞれ説明(ming)します。

  • contains: 特定のパターンを含んでいるかどうかをチェックします。今回の場合は$bodyの中にthisまたはargumentsを含んでいないことが条件となっています。

  • untilcontainsと共に用いるもので、パターンチェックをどこまでするのかを決められます。今回の場合では、function $_($_) {$_}にマッチする構(gou)文にぶつかるまでパターンチェックを行(xing)うように設定しています。

ちなみに、$_は匿名メタ変数(shu)といい、的な感じで使(shi)うものです。

 $body <: not contains {
      or { `this`, `arguments` }
    } until `function $_($_) { $_ }`

よって、上記のパターンは関数の処理の中でfunction $_($_) { $_ }にぶつかるまでにthisまたはargumentsを含んでいないことを条件に持ちます。
結果は以下のようになります。
rememberはfunction $_($_) { $_ }がそもそもないので、関数の処理内容全体がcontainsの対象となり、thisを含んでいるため変換されていません。
sumToValueはthisがありますが、function $_($_) { $_ }の中にあり、containsの対象にはならないため変換されています。

パターンの再利用

GritQLのクエリも他のの関数同様に再利用したいことがあります。
そのような時は、パターンとして定義しましょう。書き方はpattern ${パターン名} (${引数}) { ${クエリ} }のような書き方をします。
例(li)えば、console.logを消すパターン「delete_console_log」は以下のように作(zuo)成できます。

pattern delete_console_log () {
    `console.log($message)` => .
} 

作成したパターンは関数実行と同様にdelete_console_log()で使えます。
console.logのみが消されていることも以下から確認できます。

一部(bu)省(sheng)いたものもありますが、以上がで紹介されているものでした。

終わりに

今回はGritQLを触ってみました。
クエリでコードを一気に変換できるのはとても魅力的ですよね。まだベータバージョンなのですが、できることが非常に多くて楽しいです。
機会があれば、応用編としてGritQLで実務にも使えそうなカスタムパターンを作って、記事を書きたいと思うので、期待していただけると幸いです。
また、では紹介しきれなかったパターンや条件などもあるので、を読むことをお勧めします。
最後(hou)まで読んでいただきありがとうございました!

Copyright © RAKUS Co., Ltd. All rights reserved.