v0.5.0をリリースした翌朝、ふとClass Lengthのメトリクス結果にNamespaceを付与してなかったことに気づいた。これではUserクラスもAdmin::User
クラスも同じUser
になってしまうのでマズい。ということで以下のPRで直した。もし困っていた方いたらアプデしてもらえるとありがたいです。
いざとりかかってみると、ネームスペースを取得していないだけでなく、
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を使った記述はしないだろうと予想しているので、大きく困ることはないのではないかと思う。