class RuboCop::Cop::Style::MultilineBlockLayout

}
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
arguments, if any, are on the same line as the start of the block.
after the start of the block. Additionally, it checks whether the block
This cop 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 = Parser::Source::Range.new(expression.source_buffer,
                                    expression.begin_pos,
                                    expression.end_pos)
  add_offense(node, range, msg)
end

def autocorrect(node)

def autocorrect(node)
  lambda do |corrector|
    _method, args, block_body = *node
    unless args.children.empty? || args.loc.last_line == node.loc.line
      autocorrect_arguments(corrector, node, args)
      expr_before_body = args.source_range.end
    end
    return unless block_body
    expr_before_body ||= node.loc.begin
    if expr_before_body.line == block_body.loc.line
      autocorrect_body(corrector, node, block_body)
    end
  end
end

def autocorrect_arguments(corrector, node, args)

def autocorrect_arguments(corrector, node, args)
  end_pos =
    range_with_surrounding_space(args.source_range, :right, false)
    .end_pos
  range = Parser::Source::Range.new(args.source_range.source_buffer,
                                    node.loc.begin.end.begin_pos,
                                    end_pos)
  corrector.replace(range, " |#{block_arg_string(args)}|")
end

def autocorrect_body(corrector, node, block_body)

def autocorrect_body(corrector, node, block_body)
  first_node = if block_body.type == :begin
                 block_body.children.first
               else
                 block_body
               end
  block_start_col = node.source_range.column
  corrector.insert_before(first_node.source_range,
                          "\n  #{' ' * block_start_col}")
end

def block_arg_string(args)

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

def on_block(node)

def on_block(node)
  end_loc = node.loc.end
  do_loc = node.loc.begin # Actually it's either do or {.
  return if do_loc.line == end_loc.line # One-liner, no newline needed.
  # A block node has three children: the block start,
  # the arguments, and the expression. We care if the block start
  # with arguments and the expression start on the same line.
  _block_start, args, last_expression = node.children
  unless args.children.empty?
    if do_loc.line != args.loc.last_line
      add_offense_for_expression(node, args, ARG_MSG)
    end
  end
  return unless last_expression
  expression_loc = last_expression.loc
  return unless do_loc.line == expression_loc.line
  add_offense_for_expression(node, last_expression, MSG)
end