class RuboCop::Cop::Lint::SymbolConversion


}
b: 2
a: 1,
{
# good (no quoting required)
}
‘b-c’: 2
’a’: 1,
{
# good (quote all keys if any need quoting)
}
‘b-c’: 2
a: 1,
{
# bad
@example EnforcedStyle: consistent
}
‘c-d’: 3
b: 2,
a: 1,
{
# good (don’t quote keys that don’t require quoting)
}
‘c-d’: 3
“b”: 2,
‘a’: 1,
{
# bad
@example EnforcedStyle: strict (default)
:‘hyphenated-string’
:underscored_symbol
:underscored_string
:symbol
:string
# good
’hyphenated-string’.to_sym
:‘underscored_symbol’
‘underscored_string’.to_sym
:symbol.to_sym
’string’.to_sym
# bad
@example
all keys to be quoted).
every symbol key (ie. if any symbol key needs to be quoted it requires
`consistent` additionally requires hashes to use the same style for
`strict` (default) will register an offense for any incorrect usage.
There are two possible styles for this cop.
a symbol where a literal symbol could be used instead.
Checks for uses of literal strings converted to

def correct_hash_key(node)

def correct_hash_key(node)
  # Although some operators can be converted to symbols normally
  # (ie. `:==`), these are not accepted as hash keys and will
  # raise a syntax error (eg. `{ ==: ... }`). Therefore, if the
  # symbol does not start with an alphanumeric or underscore, it
  # will be ignored.
  return unless node.value.to_s.match?(/\A[a-z0-9_]/i)
  correction = node.value.inspect
  correction = correction.delete_prefix(':') if node.parent.colon?
  return if properly_quoted?(node.source, correction)
  register_offense(
    node,
    correction: correction,
    message: format(MSG, correction: node.parent.colon? ? "#{correction}:" : correction)
  )
end

def correct_inconsistent_hash_keys(keys)

def correct_inconsistent_hash_keys(keys)
  keys.each do |key|
    ignore_node(key)
    next if requires_quotes?(key)
    next if properly_quoted?(key.source, %("#{key.value}"))
    correction = %("#{key.value}")
    register_offense(
      key,
      correction: correction,
      message: format(MSG_CONSISTENCY, correction: "#{correction}:")
    )
  end
end

def in_alias?(node)

def in_alias?(node)
  node.parent&.alias_type?
end

def in_percent_literal_array?(node)

def in_percent_literal_array?(node)
  node.parent&.array_type? && node.parent&.percent_literal?
end

def on_hash(node)

def on_hash(node)
  # For `EnforcedStyle: strict`, hash keys are evaluated in `on_sym`
  return unless style == :consistent
  keys = node.keys.select(&:sym_type?)
  if keys.any? { |key| requires_quotes?(key) }
    correct_inconsistent_hash_keys(keys)
  else
    # If there are no symbol keys requiring quoting,
    # treat the hash like `EnforcedStyle: strict`.
    keys.each { |key| correct_hash_key(key) }
  end
end

def on_send(node)

def on_send(node)
  return unless node.receiver
  return unless node.receiver.str_type? || node.receiver.sym_type?
  register_offense(node, correction: node.receiver.value.to_sym.inspect)
end

def on_sym(node)

def on_sym(node)
  return if ignored_node?(node) || properly_quoted?(node.source, node.value.inspect)
  # `alias` arguments are symbols but since a symbol that requires
  # being quoted is not a valid method identifier, it can be ignored
  return if in_alias?(node)
  # The `%I[]` and `%i[]` macros are parsed as normal arrays of symbols
  # so they need to be ignored.
  return if in_percent_literal_array?(node)
  # Symbol hash keys have a different format and need to be handled separately
  return correct_hash_key(node) if hash_key?(node)
  register_offense(node, correction: node.value.inspect)
end

def properly_quoted?(source, value)

def properly_quoted?(source, value)
  return true if style == :strict && (!source.match?(/['"]/) || value.end_with?('='))
  source == value ||
    # `Symbol#inspect` uses double quotes, but allow single-quoted
    # symbols to work as well.
    source.gsub('"', '\"').tr("'", '"') == value
end

def register_offense(node, correction:, message: format(MSG, correction: correction))

def register_offense(node, correction:, message: format(MSG, correction: correction))
  add_offense(node, message: message) { |corrector| corrector.replace(node, correction) }
end

def requires_quotes?(sym_node)

def requires_quotes?(sym_node)
  sym_node.value.inspect.match?(/^:".*?"|=$/)
end