class RuboCop::Cop::Style::DigChain


x.dig(:foo).bar.dig(:baz)
# good - ‘dig`s cannot be combined
x.dig(:foo, :bar, :baz)
# good
x.dig(:foo, :bar)&.dig(:baz)
x.dig(:foo, :bar).dig(:baz)
x.dig(:foo).dig(:bar).dig(:baz)
# bad
@example
of `dig`.
is an `Enumerable` or does not have a nonstandard implementation
This cop is unsafe because it cannot be guaranteed that the receiver
@safety
Check for chained `dig` calls that can be collapsed into a single `dig`.

def inspect_chain(node)

Walk up the method chain while the receiver is `dig` with arguments.
def inspect_chain(node)
  arguments = node.arguments.dup
  end_range = node.source_range.end
  while dig?(node = node.receiver)
    begin_range = node.loc.selector
    arguments.unshift(*node.arguments)
    ignore_node(node)
  end
  return unless begin_range
  [begin_range.join(end_range), arguments]
end

def invalid_arguments?(arguments)

def invalid_arguments?(arguments)
  # If any of the arguments are arguments forwarding (`...`), it can only be the
  # first argument, or else the resulting code will have a syntax error.
  return false unless arguments&.any?
  forwarded_args_index = arguments.index(&:forwarded_args_type?)
  forwarded_args_index && forwarded_args_index < (arguments.size - 1)
end

def on_send(node)

def on_send(node)
  return if ignored_node?(node)
  return unless node.loc.dot
  return unless dig?(node)
  range, arguments = inspect_chain(node)
  return if invalid_arguments?(arguments)
  return unless range
  register_offense(node, range, arguments)
end

def register_offense(node, range, arguments)

def register_offense(node, range, arguments)
  arguments = arguments.map(&:source).join(', ')
  replacement = "dig(#{arguments})"
  add_offense(range, message: format(MSG, replacement: replacement)) do |corrector|
    corrector.replace(range, replacement)
    comments_in_range(node).reverse_each do |comment|
      corrector.insert_before(node, "#{comment.source}\n")
    end
  end
end