class RuboCop::Cop::Style::Lambda

end
x
f = ->(x) do
f = ->(x) { x }
# good
end
x
f = lambda do |x|
f = lambda { |x| x }
# bad
# EnforcedStyle: literal
@example
end
x
f = lambda do |x|
f = lambda { |x| x }
# good
end
x
f = ->(x) do
f = ->(x) { x }
# bad
# EnforcedStyle: lambda
@example
end
x
f = lambda do |x|
f = ->(x) { x }
# good
end
x
f = ->(x) do
f = lambda { |x| x }
# bad
# EnforcedStyle: line_count_dependent (default)
@example
and multiline lambdas as well.
It is configurable to enforce one of the styles for both single line
single line lambdas, and the method call syntax for multiline lambdas.
This cop (by default) checks for uses of the lambda literal syntax for

def arg_to_unparenthesized_call?(arg_node)

def arg_to_unparenthesized_call?(arg_node)
  parent = arg_node.parent
  if parent && parent.pair_type?
    arg_node = parent.parent
    parent = arg_node.parent
  end
  return false unless parent && parent.send_type?
  return false if parenthesized_call?(parent)
  arg_node.sibling_index > 1
end

def autocorrect(node)

def autocorrect(node)
  block_method, _args = *node
  selector = block_method.source
  # Don't autocorrect if this would change the meaning of the code
  return if selector == '->' && arg_to_unparenthesized_call?(node)
  lambda do |corrector|
    if selector == 'lambda'
      autocorrect_method_to_literal(corrector, node)
    else
      autocorrect_literal_to_method(corrector, node)
    end
  end
end

def autocorrect_literal_to_method(corrector, node)

def autocorrect_literal_to_method(corrector, node)
  block_method, args = *node
  # Check for unparenthesized args' preceding and trailing whitespaces.
  remove_unparenthesized_whitespace(corrector, node)
  # Avoid correcting to `lambdado` by inserting whitespace
  # if none exists before or after the lambda arguments.
  if needs_whitespace?(block_method, args, node)
    corrector.insert_before(node.loc.begin, ' ')
  end
  corrector.replace(block_method.source_range, 'lambda')
  corrector.remove(args.source_range) if args.source_range
  return if args.children.empty?
  arg_str = " |#{lambda_arg_string(args)}|"
  corrector.insert_after(node.loc.begin, arg_str)
end

def autocorrect_method_to_literal(corrector, node)

def autocorrect_method_to_literal(corrector, node)
  block_method, args = *node
  corrector.replace(block_method.source_range, '->')
  return if args.children.empty?
  arg_str = "(#{lambda_arg_string(args)})"
  whitespace_and_old_args = node.loc.begin.end.join(args.loc.end)
  corrector.insert_after(block_method.source_range, arg_str)
  corrector.remove(whitespace_and_old_args)
end

def begin_pos(node)

def begin_pos(node)
  node.loc.begin && node.loc.begin.begin_pos
end

def end_pos(node)

def end_pos(node)
  node.loc.end && node.loc.end.end_pos
end

def lambda_arg_string(args)

def lambda_arg_string(args)
  args.children.map(&:source).join(', ')
end

def message(node, selector)

def message(node, selector)
  message = selector == '->' ? METHOD_MESSAGE : LITERAL_MESSAGE
  format(message, message_line_modifier(node))
end

def message_line_modifier(node)

def message_line_modifier(node)
  case style
  when :line_count_dependent
    node.multiline? ? 'multiline' : 'single line'
  else
    'all'
  end
end

def needs_whitespace?(block_method, args, node)

def needs_whitespace?(block_method, args, node)
  selector_end = block_method.loc.selector.end.end_pos
  block_begin  = node.loc.begin.begin_pos
  (block_begin == end_pos(args) && selector_end == begin_pos(args)) ||
    (block_begin == selector_end)
end

def offending_selector?(node, selector)

def offending_selector?(node, selector)
  lines = node.multiline? ? :multiline : :single_line
  selector == OFFENDING_SELECTORS[:style][style][lines]
end

def on_block(node)

def on_block(node)
  return unless node.lambda?
  selector = node.send_node.source
  return unless offending_selector?(node, selector)
  add_offense(node,
              node.send_node.source_range,
              message(node, selector))
end

def remove_leading_whitespace(node, corrector)

def remove_leading_whitespace(node, corrector)
  corrector.remove_preceding(
    node.arguments.source_range,
    node.arguments.source_range.begin_pos -
      node.send_node.source_range.end_pos
  )
end

def remove_trailing_whitespace(node, corrector)

def remove_trailing_whitespace(node, corrector)
  corrector.remove_preceding(
    node.loc.begin,
    node.loc.begin.begin_pos - node.arguments.source_range.end_pos - 1
  )
end

def remove_unparenthesized_whitespace(corrector, node)

def remove_unparenthesized_whitespace(corrector, node)
  args = node.arguments
  return unless unparenthesized_literal_args?(args)
  remove_leading_whitespace(node, corrector)
  remove_trailing_whitespace(node, corrector)
end

def unparenthesized_literal_args?(args)

def unparenthesized_literal_args?(args)
  args.source_range && args.source_range.begin && !parentheses?(args)
end