class RuboCop::Cop::Lint::EndAlignment

This cop checks whether the end keywords are aligned properly.

Three modes are supported through the `EnforcedStyleAlignWith` 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.

If it's set to `start_of_line`, the `end` shall be aligned with the start of the line where the matching keyword appears.

@example

# bad

variable = if true
    end

@example

# EnforcedStyleAlignWith: keyword (default)

# good

variable = if true
           end

@example

# EnforcedStyleAlignWith: variable

# good

variable = if true
end

@example

# EnforcedStyleAlignWith: start_of_line

# good

puts(if true
end)

Public Instance Methods

on_case(node) click to toggle source
# File lib/rubocop/cop/lint/end_alignment.rb, line 76
def on_case(node)
  if node.argument?
    check_asgn_alignment(node.parent, node)
  else
    check_other_alignment(node)
  end
end
on_class(node) click to toggle source
# File lib/rubocop/cop/lint/end_alignment.rb, line 56
def on_class(node)
  check_other_alignment(node)
end
on_if(node) click to toggle source
# File lib/rubocop/cop/lint/end_alignment.rb, line 64
def on_if(node)
  check_other_alignment(node) unless node.ternary?
end
on_module(node) click to toggle source
# File lib/rubocop/cop/lint/end_alignment.rb, line 60
def on_module(node)
  check_other_alignment(node)
end
on_until(node) click to toggle source
# File lib/rubocop/cop/lint/end_alignment.rb, line 72
def on_until(node)
  check_other_alignment(node)
end
on_while(node) click to toggle source
# File lib/rubocop/cop/lint/end_alignment.rb, line 68
def on_while(node)
  check_other_alignment(node)
end

Private Instance Methods

alignment_node(node) click to toggle source
# File lib/rubocop/cop/lint/end_alignment.rb, line 131
def alignment_node(node)
  if style == :keyword
    node
  elsif style == :variable
    return node.parent if node.case_type? && node.argument?
    # Fall back to 'keyword' style if this node is not on the RHS
    # of an assignment
    node.ancestors.find(&:assignment?) || node
  else
    start_line_range(node)
  end
end
asgn_variable_align_with(outer_node, inner_node) click to toggle source
# File lib/rubocop/cop/lint/end_alignment.rb, line 108
def asgn_variable_align_with(outer_node, inner_node)
  expr = outer_node.source_range

  if !line_break_before_keyword?(expr, inner_node)
    range_between(expr.begin_pos, inner_node.loc.keyword.end_pos)
  else
    inner_node.loc.keyword
  end
end
autocorrect(node) click to toggle source
# File lib/rubocop/cop/lint/end_alignment.rb, line 127
def autocorrect(node)
  align(node, alignment_node(node))
end
check_asgn_alignment(outer_node, inner_node) click to toggle source
# File lib/rubocop/cop/lint/end_alignment.rb, line 97
def check_asgn_alignment(outer_node, inner_node)
  align_with = {
    keyword: inner_node.loc.keyword,
    start_of_line: start_line_range(outer_node),
    variable: asgn_variable_align_with(outer_node, inner_node)
  }

  check_end_kw_alignment(inner_node, align_with)
  ignore_node(inner_node)
end
check_assignment(node, rhs) click to toggle source
# File lib/rubocop/cop/lint/end_alignment.rb, line 86
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.
  return unless (rhs = first_part_of_call_chain(rhs))
  return unless CONDITIONAL_NODES.include?(rhs.type)
  return if rhs.if_type? && rhs.ternary?

  check_asgn_alignment(node, rhs)
end
check_other_alignment(node) click to toggle source
# File lib/rubocop/cop/lint/end_alignment.rb, line 118
def check_other_alignment(node)
  align_with = {
    keyword: node.loc.keyword,
    variable: node.loc.keyword,
    start_of_line: start_line_range(node)
  }
  check_end_kw_alignment(node, align_with)
end
start_line_range(node) click to toggle source
# File lib/rubocop/cop/lint/end_alignment.rb, line 144
def start_line_range(node)
  expr   = node.source_range
  buffer = expr.source_buffer
  source = buffer.source_line(expr.line)
  range  = buffer.line_range(expr.line)

  range_between(range.begin_pos + (source =~ /\S/),
                range.begin_pos + (source =~ /\s*\z/))
end