class RuboCop::Cop::Style::EmptyLiteral

s = ”
h = {}
a = []
# good
s = String.new
h = Hash[]
h = Hash.new
a = Array[]
a = Array.new
# bad
@example
mutable and the latter would be frozen.
isn’t corrected to an empty string since the former is
NOTE: When frozen string literals are enabled, ‘String.new`
would be a literal, like an empty array, hash, or string.
Checks for the use of a method, the result of which

def correction(node)

def correction(node)
  if offense_array_node?(node)
    '[]'
  elsif str_node(node)
    preferred_string_literal
  elsif offense_hash_node?(node)
    if first_argument_unparenthesized?(node)
      # `some_method {}` is not same as `some_method Hash.new`
      # because the braces are interpreted as a block. We will have
      # to rewrite the arguments to wrap them in parenthesis.
      args = node.parent.arguments
      "(#{args[1..].map(&:source).unshift('{}').join(', ')})"
    else
      '{}'
    end
  end
end

def first_argument_unparenthesized?(node)

def first_argument_unparenthesized?(node)
  parent = node.parent
  return false unless parent && %i[send super zsuper].include?(parent.type)
  node.equal?(parent.first_argument) && !parentheses?(node.parent)
end

def frozen_strings?

def frozen_strings?
  return true if frozen_string_literals_enabled?
  frozen_string_cop_enabled = config.cop_enabled?('Style/FrozenStringLiteralComment')
  frozen_string_cop_enabled &&
    !frozen_string_literals_disabled? &&
    string_literals_frozen_by_default?.nil?
end

def offense_array_node?(node)

def offense_array_node?(node)
  (array_node(node) && !array_with_block(node.parent)) || array_with_index(node)
end

def offense_hash_node?(node)

def offense_hash_node?(node)
  # If Hash.new takes a block, it can't be changed to {}.
  (hash_node(node) && !hash_with_block(node.parent)) || hash_with_index(node)
end

def offense_message(node)

def offense_message(node)
  if offense_array_node?(node)
    format(ARR_MSG, current: node.source)
  elsif offense_hash_node?(node)
    format(HASH_MSG, current: node.source)
  elsif str_node(node) && !frozen_strings?
    format(STR_MSG, prefer: preferred_string_literal)
  end
end

def on_send(node)

def on_send(node)
  return unless (message = offense_message(node))
  add_offense(node, message: message) do |corrector|
    corrector.replace(replacement_range(node), correction(node))
  end
end

def replacement_range(node)

def replacement_range(node)
  if hash_node(node) && first_argument_unparenthesized?(node)
    # `some_method {}` is not same as `some_method Hash.new`
    # because the braces are interpreted as a block. We will have
    # to rewrite the arguments to wrap them in parenthesis.
    args = node.parent.arguments
    range_between(args[0].source_range.begin_pos - 1, args[-1].source_range.end_pos)
  else
    node.source_range
  end
end