何でも屋エンジニアのブログ

ソフトウェア関連技術、コミュニティ、日々の雑貨

CodeKeeper v0.5.1をリリースした

v0.5.0をリリースした翌朝、ふとClass Lengthのメトリクス結果にNamespaceを付与してなかったことに気づいた。これではUserクラスもAdmin::Userクラスも同じUserになってしまうのでマズい。ということで以下のPRで直した。もし困っていた方いたらアプデしてもらえるとありがたいです。

github.com

いざとりかかってみると、ネームスペースを取得していないだけでなく、

class Root
  class A
    # このコメントのカウントが間違っていた
  end
end

のようなinner classがありそこにコメントがある場合、Rootクラスのコメントとして計上してしまうバグや、以下のように3つ以上ネストした場合

class Root
  class B
    class C
    end
  end
end

Rootクラスの行数を誤ってしまうバグなどを発見したので併せて修正した。

大変だったのは、コメントや空行の数を数える際、Inner nodeと親nodeで二重計上しないようにすることだった。例えばコメントの場合、Rubocop::AST::ProcessedSource#commentsでソース内のコメントの行数を把握し、node.first_line..node.last_lineのRangeに入るものであればあるnodeのコメントであると判断しても良いように思えていたが、そのクラス内にネストされたクラスを持ちコメントがある場合、当然二重計上となってしまうのであった。

この辺の煩わしさを避けるため、空行とコメントを数える際はInner nodeの行数を配列に持ち、あるnodeの本体が何行目にあるのかを正確に取得するようにした(余談だがRangeとArrayの変換や演算がとても便利だった)。

Namespaceに関して、上述したclass A;endのような記述には対応したが、Class#newやStructを利用した記述については、別実装となるため対応しなかった。なので

Class Root
  SubClass = Class.new
end

SubClass = Class.new

も両方SubClassと表示される。とはいえ、メトリクスを取りたいクラスでこのような記述、特にStructを使った記述はしないだろうと予想しているので、大きく困ることはないのではないかと思う。