class RuboCop::Cop::Layout::ClosingParenthesisIndentation


)
y: 2
x: 1,
some_method(a,
# right paren by IndentationWidth
# good: when other params are not lined up on multiple lines, outdent
)
c
b,
some_method(a,
# up, align right paren with left paren
# good: when all other params are on multiple lines, but are lined
)
some_method(a, b, c
# right paren by IndentationWidth
# good: when all other params are also on the same line, outdent
# Scenario 2: When First Parameter Is On The Same Line
)
a, b
some_method(
# good
)
b
a,
some_method(
# outdented by IndentationWidth
# good: when first param is on a new line, right paren is always
# Scenario 1: When First Parameter Is On Its Own Line
)
y: 2
x: 1,
some_method(a,
)
c
b,
some_method(a,
)
some_method(a, b, c
)
a, b
some_method(
)
b
a,
some_method(
# bad
@example
closing parenthesis means ‘)` preceded by a line break.
method calls, method definitions, and grouped expressions. A hanging
Checks the indentation of hanging closing parentheses in

def all_elements_aligned?(elements)

def all_elements_aligned?(elements)
  elements.flat_map do |e|
    if e.hash_type?
      e.each_child_node.map { |child| child.loc.column }
    else
      e.loc.column
    end
  end.uniq.count == 1
end

def autocorrect(corrector, node)

def autocorrect(corrector, node)
  AlignmentCorrector.correct(corrector, processed_source, node, @column_delta)
end

def check(node, elements)

def check(node, elements)
  if elements.empty?
    check_for_no_elements(node)
  else
    check_for_elements(node, elements)
  end
end

def check_for_elements(node, elements)

def check_for_elements(node, elements)
  left_paren  = node.loc.begin
  right_paren = node.loc.end
  return unless right_paren && begins_its_line?(right_paren)
  correct_column = expected_column(left_paren, elements)
  @column_delta = correct_column - right_paren.column
  return if @column_delta.zero?
  message = message(correct_column, left_paren, right_paren)
  add_offense(right_paren, message: message) do |corrector|
    autocorrect(corrector, right_paren)
  end
end

def check_for_no_elements(node)

def check_for_no_elements(node)
  left_paren = node.loc.begin
  right_paren = node.loc.end
  return unless right_paren && begins_its_line?(right_paren)
  candidates = correct_column_candidates(node, left_paren)
  return if candidates.include?(right_paren.column)
  # Although there are multiple choices for a correct column,
  # select the first one of candidates to determine a specification.
  correct_column = candidates.first
  @column_delta = correct_column - right_paren.column
  message = message(correct_column, left_paren, right_paren)
  add_offense(right_paren, message: message) do |corrector|
    autocorrect(corrector, right_paren)
  end
end

def correct_column_candidates(node, left_paren)

def correct_column_candidates(node, left_paren)
  [
    processed_source.line_indentation(left_paren.line),
    left_paren.column,
    node.loc.column
  ]
end

def expected_column(left_paren, elements)

def expected_column(left_paren, elements)
  if line_break_after_left_paren?(left_paren, elements)
    source_indent = processed_source.line_indentation(first_argument_line(elements))
    new_indent    = source_indent - configured_indentation_width
    new_indent.negative? ? 0 : new_indent
  elsif all_elements_aligned?(elements)
    left_paren.column
  else
    processed_source.line_indentation(first_argument_line(elements))
  end
end

def first_argument_line(elements)

def first_argument_line(elements)
  elements.first.loc.first_line
end

def line_break_after_left_paren?(left_paren, elements)

def line_break_after_left_paren?(left_paren, elements)
  elements.first && elements.first.loc.line > left_paren.line
end

def message(correct_column, left_paren, right_paren)

def message(correct_column, left_paren, right_paren)
  if correct_column == left_paren.column
    MSG_ALIGN
  else
    format(MSG_INDENT, expected: correct_column, actual: right_paren.column)
  end
end

def on_begin(node)

def on_begin(node)
  check(node, node.children)
end

def on_def(node)

def on_def(node)
  check(node.arguments, node.arguments)
end

def on_send(node)

def on_send(node)
  check(node, node.arguments)
end