Prototype.jsのコードを見つけるgrep的な検索ツールを書きました。

gif

redmind 2.0のコードからprototype.jsを利用してる箇所を検索してる様子

使い方

使い方はものすごい単純で、インストールして、検索したいファイルパスを渡すだけです。

npm install search-prototype.js -g
search-prototype.js ./public/javascripts/application.js

標準出力に検索結果が流れてきます。

検出するAPIの定義はAPIリファレンスのサジェストファイルから取ってきています。

制限

Prototype.jsは名前が表すようにprototypeを拡張するライブラリです。

そのため、Array.prototype.everyがprototype.jsで拡張されたものか、ネイティブものかを見極める方法はありません。 この検索ツールでは、そういった曖昧なものもデフォルトではアグレッシブに検出します。

graspをベースにしたASTをベースにして検索を行うため、文字列検索よりは誤爆は少ないですがそれでも誤爆は避けられません。

"[].every()は文字列" // 文字列
// これは検出されないけど
[].every(function(element){})
// これは検出する

さらにいえば、JavaScriptの関数はファーストクラスなので、次のような書き方も正常系です。なので、このツールではこの書き方も検出します。

var cc = Class.create
cc({});

image

検索クエリは基本的にはequeryですが、utilだけsqueryで書いてます(graspには$をエスケープできないバグがある)

おわり

Prototype JavaScript Framework - WikipediaによるとPrototype.jsのは12年前にリリースされたライブラリです。

MooToolsもそうですが、まだECMAScriptにはArray#mapなどもなかった時代に色々拡張したprototypeメソッドを定義しています。 そのため、jQueryなどと比べてもコードとライブラリが融合しやすく後からリファクタリングするのはとても大変です。(どこでメソッドを参照されているのか分からない)

prototype.js自体を書き換えて実行時にprototype.jsの利用箇所を検出する方法もありますが、特定のタイミングでしか呼ばれない箇所にprototype.jsの依存がある場合は見つけることができません。 そういったものも静的に解析できるようにするためsearch-prototype.jsを作ってみました。

検索だけでなく置換も含めたリファクタリングを行いたい場合はjscodeshiftなどもおすすめです。


prototype.jsは今月になってなぜかコミットがあったのが面白かったです。