Class: RuboCop::Cop::Style::HashSyntax

Inherits:
Base
  • Object
show all
Extended by:
AutoCorrector
Includes:
ConfigurableEnforcedStyle, HashShorthandSyntax, RangeHelp
Defined in:
lib/rubocop/cop/style/hash_syntax.rb

Overview

Checks hash literal syntax.

It can enforce either the use of the class hash rocket syntax or the use of the newer Ruby 1.9 syntax (when applicable).

A separate offense is registered for each problematic pair.

The supported styles are:

  • ruby19 - forces use of the 1.9 syntax (e.g. ‘1`) when hashes have

all symbols for keys

  • hash_rockets - forces use of hash rockets for all hashes

  • no_mixed_keys - simply checks for hashes with mixed syntaxes

  • ruby19_no_mixed_keys - forces use of ruby 1.9 syntax and forbids mixed

syntax hashes

This cop has EnforcedShorthandSyntax option. It can enforce either the use of the explicit hash value syntax or the use of Ruby 3.1’s hash value shorthand syntax.

The supported styles are:

  • always - forces use of the 3.1 syntax (e.g. foo:)

  • never - forces use of explicit hash literal value

  • either - accepts both shorthand and explicit use of hash literal value

  • consistent - forces use of the 3.1 syntax only if all values can be omitted in the hash

Examples:

EnforcedStyle: ruby19 (default)

# bad
{:a => 2}
{b: 1, :c => 2}

# good
{a: 2, b: 1}
{:c => 2, 'd' => 2} # acceptable since 'd' isn't a symbol
{d: 1, 'e' => 2} # technically not forbidden

EnforcedStyle: hash_rockets

# bad
{a: 1, b: 2}
{c: 1, 'd' => 5}

# good
{:a => 1, :b => 2}

EnforcedStyle: no_mixed_keys

# bad
{:a => 1, b: 2}
{c: 1, 'd' => 2}

# good
{:a => 1, :b => 2}
{c: 1, d: 2}

EnforcedStyle: ruby19_no_mixed_keys

# bad
{:a => 1, :b => 2}
{c: 2, 'd' => 3} # should just use hash rockets

# good
{a: 1, b: 2}
{:c => 3, 'd' => 4}

EnforcedShorthandSyntax: always (default)


# bad
{foo: foo, bar: bar}

# good
{foo:, bar:}

EnforcedShorthandSyntax: never


# bad
{foo:, bar:}

# good
{foo: foo, bar: bar}

EnforcedShorthandSyntax: either


# good
{foo: foo, bar: bar}

# good
{foo:, bar:}

EnforcedShorthandSyntax: consistent


# bad - `foo` and `bar` values can be omitted
{foo: foo, bar: bar}

# bad - `bar` value can be omitted
{foo:, bar: bar}

# bad - mixed syntaxes
{foo:, bar: baz}

# good
{foo:, bar:}

# good - can't omit `baz`
{foo: foo, bar: baz}

Constant Summary collapse

MSG_19 =
'Use the new Ruby 1.9 hash syntax.'
MSG_NO_MIXED_KEYS =
"Don't mix styles in the same hash."
MSG_HASH_ROCKETS =
'Use hash rockets syntax.'

Constants included from HashShorthandSyntax

HashShorthandSyntax::DO_NOT_MIX_EXPLICIT_VALUE_MSG, HashShorthandSyntax::DO_NOT_MIX_MSG_PREFIX, HashShorthandSyntax::DO_NOT_MIX_OMIT_VALUE_MSG, HashShorthandSyntax::EXPLICIT_HASH_VALUE_MSG, HashShorthandSyntax::OMIT_HASH_VALUE_MSG

Constants inherited from Base

Base::RESTRICT_ON_SEND

Instance Attribute Summary

Attributes inherited from Base

#config, #processed_source

Instance Method Summary collapse

Methods included from AutoCorrector

support_autocorrect?

Methods included from HashShorthandSyntax

#on_hash_for_mixed_shorthand, #on_pair

Methods included from ConfigurableEnforcedStyle

#alternative_styles, #ambiguous_style_detected, #correct_style_detected, #detected_style, #detected_style=, #no_acceptable_style!, #no_acceptable_style?, #opposite_style_detected, #style, #style_configured?, #style_detected, #style_parameter_name, #supported_styles, #unexpected_style_detected

Methods inherited from Base

#active_support_extensions_enabled?, #add_global_offense, #add_offense, autocorrect_incompatible_with, badge, #callbacks_needed, callbacks_needed, #config_to_allow_offenses, #config_to_allow_offenses=, #cop_config, cop_name, #cop_name, department, documentation_url, exclude_from_registry, #excluded_file?, #external_dependency_checksum, inherited, #initialize, joining_forces, lint?, match?, #message, #offenses, #on_investigation_end, #on_new_investigation, #on_other_file, #parse, #ready, #relevant_file?, support_autocorrect?, support_multiple_source?, #target_rails_version, #target_ruby_version

Methods included from ExcludeLimit

#exclude_limit

Methods included from AutocorrectLogic

#autocorrect?, #autocorrect_enabled?, #autocorrect_requested?, #autocorrect_with_disable_uncorrectable?, #correctable?, #disable_uncorrectable?, #safe_autocorrect?

Methods included from IgnoredNode

#ignore_node, #ignored_node?, #part_of_ignored_node?

Methods included from Util

silence_warnings

Constructor Details

This class inherits a constructor from RuboCop::Cop::Base

Instance Method Details

#alternative_styleObject



164
165
166
167
168
169
170
171
# File 'lib/rubocop/cop/style/hash_syntax.rb', line 164

def alternative_style
  case style
  when :hash_rockets
    :ruby19
  when :ruby19, :ruby19_no_mixed_keys
    :hash_rockets
  end
end

#hash_rockets_check(pairs) ⇒ Object



142
143
144
# File 'lib/rubocop/cop/style/hash_syntax.rb', line 142

def hash_rockets_check(pairs)
  check(pairs, ':', MSG_HASH_ROCKETS)
end

#no_mixed_keys_check(pairs) ⇒ Object



156
157
158
159
160
161
162
# File 'lib/rubocop/cop/style/hash_syntax.rb', line 156

def no_mixed_keys_check(pairs)
  if sym_indices?(pairs)
    check(pairs, pairs.first.inverse_delimiter, MSG_NO_MIXED_KEYS)
  else
    check(pairs, ':', MSG_NO_MIXED_KEYS)
  end
end

#on_hash(node) ⇒ Object



120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/rubocop/cop/style/hash_syntax.rb', line 120

def on_hash(node)
  pairs = node.pairs

  return if pairs.empty?

  on_hash_for_mixed_shorthand(node)

  if style == :hash_rockets || force_hash_rockets?(pairs)
    hash_rockets_check(pairs)
  elsif style == :ruby19_no_mixed_keys
    ruby19_no_mixed_keys_check(pairs)
  elsif style == :no_mixed_keys
    no_mixed_keys_check(pairs)
  else
    ruby19_check(pairs)
  end
end

#ruby19_check(pairs) ⇒ Object



138
139
140
# File 'lib/rubocop/cop/style/hash_syntax.rb', line 138

def ruby19_check(pairs)
  check(pairs, '=>', MSG_19) if sym_indices?(pairs)
end

#ruby19_no_mixed_keys_check(pairs) ⇒ Object



146
147
148
149
150
151
152
153
154
# File 'lib/rubocop/cop/style/hash_syntax.rb', line 146

def ruby19_no_mixed_keys_check(pairs)
  if force_hash_rockets?(pairs)
    check(pairs, ':', MSG_HASH_ROCKETS)
  elsif sym_indices?(pairs)
    check(pairs, '=>', MSG_19)
  else
    check(pairs, ':', MSG_NO_MIXED_KEYS)
  end
end