class RuboCop::Cop::Style::CollectionCompact


hash.compact!
# good
hash.select! { |k, v| !v.nil? }
hash.reject! { |k, v| v.nil? }
# bad
array.compact
# good
array.select { |e| !e.nil? }
array.reject { |e| e.nil? }
# bad
@example
when the receiver is a hash object.
and ‘[[1, 2], [3, nil]].compact` are not compatible. This will work fine
For example, `[[1, 2], [3, nil]].reject { |first, second| second.nil? }`
`nil` check of block arguments to the receiver object.
It is unsafe by default because false positives may occur in the
@safety
and hashes can be replaced with `{Array,Hash}#{compact,compact!}`.
This cop checks for places where custom logic on rejection nils from arrays

def good_method_name(method_name)

def good_method_name(method_name)
  if method_name.to_s.end_with?('!')
    'compact!'
  else
    'compact'
  end
end

def offense_range(send_node, block_node)

def offense_range(send_node, block_node)
  range_between(send_node.loc.selector.begin_pos, block_node.loc.end.end_pos)
end

def on_send(node)

def on_send(node)
  block_node = node.parent
  return unless block_node&.block_type?
  return unless (method_name, args, receiver =
                   reject_method?(block_node) || select_method?(block_node))
  return unless args.last.source == receiver.source
  range = offense_range(node, block_node)
  good = good_method_name(method_name)
  message = format(MSG, good: good, bad: range.source)
  add_offense(range, message: message) { |corrector| corrector.replace(range, good) }
end