Layout/EmptyLinesAroundAccessModifierとLayout/EmptyLinesAroundClassBodyの組み合わせで起きることがあるinfinite loopを直した

github.com

問題の再現から要因の特定に2時間くらい、アクセス修飾子の前後についての現状実装で、正規表現で空白の有無が妥当かどうかを調べているあたりどうしたものか悩むのに2時間越えくらい。解決するための実装アプローチとして、正規表現から AST に置き換える目処がついたあたりで、class / module / sclass それぞれに対応が必要ということを試し試しから、コミットメッセージを書くあたりまでで2時間くらいで、早起きの流れで 6 時間くらいぶっ通しで使って直した。

Layout/EmptyLinesAroundAccessModifier cop と Layout/EmptyLinesAroundClassBody cop がそれぞれ、スーパークラス ItEvenInheritsFromALongClassNameSOINeedToAddALineBrake を指定している次の行とアクセス修飾子の前の行にあたる同一行を消そうとするのと挿入しようとする操作で競合して、InfiniteCorrectionLoop エラーが発生するという問題だった。

class AVerryLongClassNameDoYouLikeIt <
  ItEvenInheritsFromALongClassNameSOINeedToAddALineBrake

  protected

  def foobar
  end
end

このあたり、正規表現でクラス宣言を探索する作りだったので宣言が改行されている場合にうまく動作しなくなるという事象だったので、AST の処理に置き換えて解決した。