class RuboCop::Cop::Layout::MultilineBlockLayout

}
bar(i)
foo(i)
|
fit_on_one_line
that_would_not,
of_parameters,
long_list,
blah { |
# good
}
bar(i)
foo(i)
blah { |i|
# good
}
bar(i)
blah { |i| foo(i)
# bad
end
bar(i)
foo(i)
blah do |i|
# good
end
bar(i)
|i| foo(i)
blah do
# bad
end
bar(i)
blah do |i| foo(i)
# bad
@example
line would otherwise be too long, is accepted.
block. Putting block arguments on separate lines, because the whole
arguments, if any, are on the same line as the start of the
after the start of the block. Additionally, it checks whether the block
Checks whether the multiline do end blocks have a newline

def add_offense_for_expression(node, expr, msg)

def add_offense_for_expression(node, expr, msg)
  expression = expr.source_range
  range = range_between(expression.begin_pos, expression.end_pos)
  add_offense(range, message: msg) { |corrector| autocorrect(corrector, node) }
end

def args_on_beginning_line?(node)

def args_on_beginning_line?(node)
  !node.arguments? || node.loc.begin.line == node.arguments.loc.last_line
end

def autocorrect(corrector, node)

def autocorrect(corrector, node)
  unless args_on_beginning_line?(node)
    autocorrect_arguments(corrector, node)
    expr_before_body = node.arguments.source_range.end
  end
  return unless node.body
  expr_before_body ||= node.loc.begin
  return unless same_line?(expr_before_body, node.body)
  autocorrect_body(corrector, node, node.body)
end

def autocorrect_arguments(corrector, node)

def autocorrect_arguments(corrector, node)
  end_pos = range_with_surrounding_space(
    node.arguments.source_range,
    side: :right,
    newlines: false
  ).end_pos
  range = range_between(node.loc.begin.end.begin_pos, end_pos)
  corrector.replace(range, " |#{block_arg_string(node, node.arguments)}|")
end

def autocorrect_body(corrector, node, block_body)

def autocorrect_body(corrector, node, block_body)
  first_node = if block_body.begin_type? && !block_body.source.start_with?('(')
                 block_body.children.first
               else
                 block_body
               end
  block_start_col = node.source_range.column
  corrector.insert_before(first_node, "\n  #{' ' * block_start_col}")
end

def block_arg_string(node, args)

def block_arg_string(node, args)
  arg_string = args.children.map do |arg|
    if arg.mlhs_type?
      "(#{block_arg_string(node, arg)})"
    else
      arg.source
    end
  end.join(', ')
  arg_string += ',' if include_trailing_comma?(node.arguments)
  arg_string
end

def characters_needed_for_space_and_pipes(node)

def characters_needed_for_space_and_pipes(node)
  if node.source.lines.first.end_with?("|\n")
    PIPE_SIZE
  else
    (PIPE_SIZE * 2) + 1
  end
end

def include_trailing_comma?(args)

def include_trailing_comma?(args)
  arg_count = args.each_descendant(:arg).to_a.size
  arg_count == 1 && args.source.include?(',')
end

def line_break_necessary_in_args?(node)

def line_break_necessary_in_args?(node)
  needed_length_for_args(node) > max_line_length
end

def needed_length_for_args(node)

def needed_length_for_args(node)
  node.source_range.column +
    characters_needed_for_space_and_pipes(node) +
    node.source.lines.first.chomp.length +
    block_arg_string(node, node.arguments).length
end

def on_block(node)

def on_block(node)
  return if node.single_line?
  unless args_on_beginning_line?(node) || line_break_necessary_in_args?(node)
    add_offense_for_expression(node, node.arguments, ARG_MSG)
  end
  return unless node.body && same_line?(node.loc.begin, node.body)
  add_offense_for_expression(node, node.body, MSG)
end