コードのメトリクス自分で取りたいなと思いRubocopのソースコードを読んでいる。
Copが呼ばれるまでにソースコードがどう処理されて渡されるのか、Cop内でどう解析するのか気になって手元でいじっていた。
手元でRubocopを実行しブレークポイントを貼り見るのも良いけど、processed_source
周りのAPIを自分でたたいて遊びたかったので以下のようなスクリプトを書いた。呼び出すcopの設定をしたりキャッシュをoffにしたりとちょっと面倒に感じたのもあるが、pockeさんの記事を読めばクリアできるのであくまでも副次的な理由である。
# 標準入力からソースコードを渡している require 'pry' require 'rubocop' require 'rubocop-ast' arg = ARGV.first source = +arg ps = RuboCop::AST::ProcessedSource.new(source, 3.0) def visit_depth_last(node, &block) node.each_child_node { |child| visit_depth_last(child, &block) } yield node end visit_depth_last(ps.ast) do |child| binding.pry end
Rubocopの各所で引数として渡されているnodeはprocessed_source.ast
なので、visit_depth_last
に渡してあげてゴニョニョするとRuboCop::AST::*Node
のAPIを触れるようになる。これで自分の参考にしたいCopの実装を見つつ手元でデバッグするのが分かりやすかった。