# encoding: utf-8 module RuboCop module Cop module Lint # This cop checks whether the end keywords are aligned properly. # # Two modes are supported through the AlignWith configuration # parameter. If it's set to `keyword` (which is the default), the `end` # shall be aligned with the start of the keyword (if, class, etc.). If # it's set to `variable` the `end` shall be aligned with the # left-hand-side of the variable assignment, if there is one. # # @example # # variable = if true # end class EndAlignment < Cop include CheckAssignment include EndKeywordAlignment include IfNode def on_class(node) check_offset_of_node(node) end def on_module(node) check_offset_of_node(node) end def on_if(node) check_offset_of_node(node) unless ternary_op?(node) end def on_while(node) check_offset_of_node(node) end def on_until(node) check_offset_of_node(node) end private def check_assignment(node, rhs) # If there are method calls chained to the right hand side of the # assignment, we let rhs be the receiver of those method calls before # we check if it's an if/unless/while/until. rhs = first_part_of_call_chain(rhs) return unless rhs return unless [:if, :while, :until].include?(rhs.type) return if ternary_op?(rhs) expr = node.loc.expression if style == :variable && !line_break_before_keyword?(expr, rhs) range = Parser::Source::Range.new(expr.source_buffer, expr.begin_pos, rhs.loc.keyword.end_pos) offset = rhs.loc.keyword.column - node.loc.expression.column else range = rhs.loc.keyword offset = 0 end check_offset(rhs, range.source, offset) ignore_node(rhs) # Don't check again. end def line_break_before_keyword?(whole_expression, rhs) rhs.loc.keyword.line > whole_expression.line end end end end end