レポートが分かりやすかったので着手していた。問題解決には Token
まわりのコードを見るのに骨があった。
問題としては以下のようにネストした reference brackets の外側の括弧に対して期待した offense が出ないというもの。
record[ options[:attribute] ]
AST へのイベント処理としては先に record[
が処理されてから options[
が処理されるので、開き括弧 [
(left_ref_bracket) の前のトークンが閉じ括弧 ]
(right_bracket) でないときは、トークンを reverse させないのがパッチの肝。このケースでも常に reverse していたので、内側の options[
の括弧を常に参照していたのが問題の原因だった。
逆に [
の前の token
が ]
はどういったものかというと o[:foo][:bar]
のケースで、そういった場合とは処理を振り分けておく必要があったというものだった。
@@ -111,10 +111,14 @@ def bracket_method?(node) end def left_ref_bracket(node, tokens) - if node.method?(:[]=) + current_token = tokens.reverse.find(&:left_ref_bracket?) + previous_token = previous_token(current_token) + + if node.method?(:[]=) || + previous_token && !previous_token.right_bracket? tokens.find(&:left_ref_bracket?) else - tokens.reverse.find(&:left_ref_bracket?) + current_token end end @@ -131,6 +135,11 @@ def closing_bracket(tokens, opening_bracket) end end + def previous_token(current_token) + index = processed_source.tokens.index(current_token) + index.nil? || index.zero? ? nil : processed_source.tokens[index - 1] + end + def empty_config cop_config['EnforcedStyleForEmptyBrackets'] end