class Rubocop::Cop::Lint::EndAlignment

This cop checks whether the end keywords are aligned properly.

For keywords (if, def, etc.) the end is aligned with the start of the keyword. For blocks - with the start of the expression where the block is defined.

@example

variable = if true
           end

variable = lambda do |i|
  i
end

Constants

MSG

Public Class Methods

new() click to toggle source
Calls superclass method Rubocop::Cop::Cop::new
# File lib/rubocop/cop/lint/end_alignment.rb, line 24
def initialize
  super
  @inspected_blocks = []
end

Public Instance Methods

inspect(source_buffer, source, tokens, ast, comments) click to toggle source
Calls superclass method Rubocop::Cop::Cop#inspect
# File lib/rubocop/cop/lint/end_alignment.rb, line 29
def inspect(source_buffer, source, tokens, ast, comments)
  @inspected_blocks = []
  super
end
on_and(node) click to toggle source
Calls superclass method
# File lib/rubocop/cop/lint/end_alignment.rb, line 77
def on_and(node)
  return if already_processed_node?(node)

  _left, right = *node
  if right.type == :block
    check_block_alignment(node.loc.expression, right.loc)
    @inspected_blocks << right
  end
  super
end
Also aliased as: on_or
on_and_asgn(node)
Alias for: on_lvasgn
on_block(node) click to toggle source

Block related alignments

Calls superclass method
# File lib/rubocop/cop/lint/end_alignment.rb, line 71
def on_block(node)
  return if already_processed_node?(node)
  check_block_alignment(node.loc.expression, node.loc)
  super
end
on_casgn(node) click to toggle source
Calls superclass method
# File lib/rubocop/cop/lint/end_alignment.rb, line 102
def on_casgn(node)
  _, _, children = *node
  process_block_assignment(node, children)
  super
end
on_class(node) click to toggle source
Calls superclass method
# File lib/rubocop/cop/lint/end_alignment.rb, line 44
def on_class(node)
  check(node)
  super
end
on_cvasgn(node)
Alias for: on_lvasgn
on_def(node) click to toggle source
Calls superclass method
# File lib/rubocop/cop/lint/end_alignment.rb, line 34
def on_def(node)
  check(node)
  super
end
on_defs(node) click to toggle source
Calls superclass method
# File lib/rubocop/cop/lint/end_alignment.rb, line 39
def on_defs(node)
  check(node)
  super
end
on_gvasgn(node)
Alias for: on_lvasgn
on_if(node) click to toggle source
Calls superclass method
# File lib/rubocop/cop/lint/end_alignment.rb, line 54
def on_if(node)
  check(node) if node.loc.respond_to?(:end)
  super
end
on_ivasgn(node)
Alias for: on_lvasgn
on_lvasgn(node) click to toggle source
Calls superclass method
# File lib/rubocop/cop/lint/end_alignment.rb, line 90
def on_lvasgn(node)
  _, children = *node
  process_block_assignment(node, children)
  super
end
on_masgn(node) click to toggle source
Calls superclass method
# File lib/rubocop/cop/lint/end_alignment.rb, line 120
def on_masgn(node)
  variables, args = *node
  process_block_assignment(variables, args)
  super
end
on_module(node) click to toggle source
Calls superclass method
# File lib/rubocop/cop/lint/end_alignment.rb, line 49
def on_module(node)
  check(node)
  super
end
on_op_asgn(node) click to toggle source
Calls superclass method
# File lib/rubocop/cop/lint/end_alignment.rb, line 108
def on_op_asgn(node)
  variable, _op, args = *node
  process_block_assignment(variable, args)
  super
end
on_or(node)
Alias for: on_and
on_or_asgn(node)
Alias for: on_lvasgn
on_send(node) click to toggle source
Calls superclass method
# File lib/rubocop/cop/lint/end_alignment.rb, line 114
def on_send(node)
  _receiver, _method, *args = *node
  process_block_assignment(node, args.last)
  super
end
on_until(node) click to toggle source
Calls superclass method
# File lib/rubocop/cop/lint/end_alignment.rb, line 64
def on_until(node)
  check(node)
  super
end
on_while(node) click to toggle source
Calls superclass method
# File lib/rubocop/cop/lint/end_alignment.rb, line 59
def on_while(node)
  check(node)
  super
end

Private Instance Methods

already_processed_node?(node) click to toggle source
# File lib/rubocop/cop/lint/end_alignment.rb, line 179
def already_processed_node?(node)
  @inspected_blocks.include?(node)
end
block_is_on_next_line?(begin_node, block_node) click to toggle source
# File lib/rubocop/cop/lint/end_alignment.rb, line 183
def block_is_on_next_line?(begin_node, block_node)
  begin_node.loc.line != block_node.loc.line
end
check(node) click to toggle source
# File lib/rubocop/cop/lint/end_alignment.rb, line 164
def check(node)
  # discard modifier forms of if/while/until
  return unless node.loc.end

  kw_loc = node.loc.keyword
  end_loc = node.loc.end

  if kw_loc.line != end_loc.line && kw_loc.column != end_loc.column
    add_offence(:warning,
                end_loc,
                sprintf(MSG, end_loc.line, end_loc.column,
                        kw_loc.source, kw_loc.line, kw_loc.column))
  end
end
check_block_alignment(start_loc, block_loc) click to toggle source
# File lib/rubocop/cop/lint/end_alignment.rb, line 152
def check_block_alignment(start_loc, block_loc)
  end_loc = block_loc.end
  if block_loc.begin.line != end_loc.line &&
       start_loc.column != end_loc.column
    add_offence(:warning,
                end_loc,
                sprintf(MSG, end_loc.line, end_loc.column,
                        start_loc.source.lines.to_a.first.chomp,
                        start_loc.line, start_loc.column))
  end
end
process_block_assignment(begin_node, block_node) click to toggle source
# File lib/rubocop/cop/lint/end_alignment.rb, line 128
def process_block_assignment(begin_node, block_node)
  return unless block_node
  return if already_processed_node?(block_node)

  while block_node.type == :send
    receiver, _method, args = *block_node
    if receiver && [:block, :send].include?(receiver.type)
      block_node = receiver
    elsif args && [:block, :send].include?(args.type)
      block_node = args
    else
      break
    end
  end
  if block_node.type == :block
    # Align with the expression that is on the same line
    # where the block is defined
    return if block_is_on_next_line?(begin_node, block_node)

    @inspected_blocks << block_node
    check_block_alignment(begin_node.loc.expression, block_node.loc)
  end
end