Class: RuboCop::Cop::Lint::SymbolConversion
Relationships & Source Files | |
Super Chains via Extension / Inclusion / Inheritance | |
Class Chain:
self,
::RuboCop::Cop::AutoCorrector ,
::RuboCop::Cop::Base ,
::RuboCop::ExcludeLimit ,
NodePattern::Macros,
RuboCop::AST::Sexp
|
|
Instance Chain:
|
|
Inherits: |
RuboCop::Cop::Base
|
Defined in: | lib/rubocop/cop/lint/symbol_conversion.rb |
Overview
Checks for uses of literal strings converted to a symbol where a literal symbol could be used instead.
There are two possible styles for this cop.
strict
(default) will register an offense for any incorrect usage.
consistent
additionally requires hashes to use the same style for
every symbol key (ie. if any symbol key needs to be quoted it requires
all keys to be quoted).
Constant Summary
-
MSG =
# File 'lib/rubocop/cop/lint/symbol_conversion.rb', line 73'Unnecessary symbol conversion; use `%<correction>s` instead.'
-
MSG_CONSISTENCY =
# File 'lib/rubocop/cop/lint/symbol_conversion.rb', line 74'Symbol hash key should be quoted for consistency; ' \ 'use `%<correction>s` instead.'
-
RESTRICT_ON_SEND =
# File 'lib/rubocop/cop/lint/symbol_conversion.rb', line 76%i[to_sym intern].freeze
::RuboCop::Cop::Base
- Inherited
EMPTY_OFFENSES, RESTRICT_ON_SEND
::RuboCop::Cop::ConfigurableEnforcedStyle
- Included
Class Attribute Summary
::RuboCop::Cop::AutoCorrector
- Extended
::RuboCop::Cop::Base
- Inherited
.gem_requirements, .lint?, | |
.support_autocorrect? | Returns if class supports autocorrect. |
.support_multiple_source? | Override if your cop should be called repeatedly for multiple investigations Between calls to |
Class Method Summary
::RuboCop::Cop::Base
- Inherited
.autocorrect_incompatible_with | List of cops that should not try to autocorrect at the same time as this cop. |
.badge | Naming. |
.callbacks_needed, .cop_name, .department, | |
.documentation_url | Returns a url to view this cops documentation online. |
.exclude_from_registry | Call for abstract Cop classes. |
.inherited, | |
.joining_forces | Override and return the Force class(es) you need to join. |
.match? | Returns true if the cop name or the cop namespace matches any of the given names. |
.new, | |
.requires_gem | Register a version requirement for the given gem name. |
.restrict_on_send |
::RuboCop::ExcludeLimit
- Extended
exclude_limit | Sets up a configuration option to have an exclude limit tracked. |
transform |
Instance Attribute Summary
::RuboCop::Cop::ConfigurableEnforcedStyle
- Included
::RuboCop::Cop::Base
- Inherited
::RuboCop::Cop::AutocorrectLogic
- Included
Instance Method Summary
- #on_hash(node)
- #on_send(node)
- #on_sym(node)
- #correct_hash_key(node) private
- #correct_inconsistent_hash_keys(keys) private
- #in_alias?(node) ⇒ Boolean private
- #in_percent_literal_array?(node) ⇒ Boolean private
- #properly_quoted?(source, value) ⇒ Boolean private
- #register_offense(node, correction:, message: format(MSG, correction: correction)) private
- #requires_quotes?(sym_node) ⇒ Boolean private
::RuboCop::Cop::SymbolHelp
- Included
::RuboCop::Cop::ConfigurableEnforcedStyle
- Included
::RuboCop::Cop::Base
- Inherited
#add_global_offense | Adds an offense that has no particular location. |
#add_offense | Adds an offense on the specified range (or node with an expression) Unless that offense is disabled for this range, a corrector will be yielded to provide the cop the opportunity to autocorrect the offense. |
#begin_investigation | Called before any investigation. |
#callbacks_needed, | |
#cop_config | Configuration Helpers. |
#cop_name, #excluded_file?, | |
#external_dependency_checksum | This method should be overridden when a cop’s behavior depends on state that lives outside of these locations: |
#inspect, | |
#message | Gets called if no message is specified when calling |
#name | Alias for Base#cop_name. |
#offenses, | |
#on_investigation_end | Called after all on_… |
#on_new_investigation | Called before all on_… |
#on_other_file | Called instead of all on_… |
#parse | There should be very limited reasons for a Cop to do it’s own parsing. |
#parser_engine, | |
#ready | Called between investigations. |
#relevant_file?, #target_rails_version, #target_ruby_version, #annotate, #apply_correction, #attempt_correction, | |
#callback_argument | Reserved for Cop::Cop. |
#complete_investigation | Called to complete an investigation. |
#correct, #current_corrector, | |
#current_offense_locations | Reserved for Commissioner: |
#current_offenses, #currently_disabled_lines, #custom_severity, #default_severity, #disable_uncorrectable, #enabled_line?, #file_name_matches_any?, #find_message, #find_severity, #range_for_original, #range_from_node_or_range, | |
#reset_investigation | Actually private methods. |
#use_corrector |
::RuboCop::Cop::AutocorrectLogic
- Included
#disable_offense, #disable_offense_at_end_of_line, #disable_offense_before_and_after, #disable_offense_with_eol_or_surround_comment, #heredoc_range, #max_line_length, #multiline_ranges, #multiline_string?, | |
#range_by_lines | Expand the given range to include all of any lines it covers. |
#range_of_first_line, #range_overlaps_offense?, #string_continuation?, #surrounding_heredoc?, #surrounding_percent_array? |
::RuboCop::Cop::IgnoredNode
- Included
Constructor Details
This class inherits a constructor from RuboCop::Cop::Base
Instance Method Details
#correct_hash_key(node) (private)
[ GitHub ]# File 'lib/rubocop/cop/lint/symbol_conversion.rb', line 147
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
#correct_inconsistent_hash_keys(keys) (private)
[ GitHub ]# File 'lib/rubocop/cop/lint/symbol_conversion.rb', line 166
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
#in_alias?(node) ⇒ Boolean
(private)
# File 'lib/rubocop/cop/lint/symbol_conversion.rb', line 139
def in_alias?(node) node.parent&.alias_type? end
#in_percent_literal_array?(node) ⇒ Boolean
(private)
# File 'lib/rubocop/cop/lint/symbol_conversion.rb', line 143
def in_percent_literal_array?(node) node.parent&.array_type? && node.parent.percent_literal? end
#on_hash(node)
[ GitHub ]# File 'lib/rubocop/cop/lint/symbol_conversion.rb', line 105
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
#on_send(node)
[ GitHub ]# File 'lib/rubocop/cop/lint/symbol_conversion.rb', line 78
def on_send(node) return unless node.receiver if node.receiver.str_type? || node.receiver.sym_type? register_offense(node, correction: node.receiver.value.to_sym.inspect) elsif node.receiver.dstr_type? register_offense(node, correction: ":\"#{node.receiver.value.to_sym}\"") end end
#on_sym(node)
[ GitHub ]# File 'lib/rubocop/cop/lint/symbol_conversion.rb', line 88
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
#properly_quoted?(source, value) ⇒ Boolean
(private)
# File 'lib/rubocop/cop/lint/symbol_conversion.rb', line 126
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
#register_offense(node, correction:, message: format(MSG, correction: correction)) (private)
[ GitHub ]# File 'lib/rubocop/cop/lint/symbol_conversion.rb', line 122
def register_offense(node, correction:, message: format(MSG, correction: correction)) add_offense(node, message: ) { |corrector| corrector.replace(node, correction) } end
#requires_quotes?(sym_node) ⇒ Boolean
(private)
# File 'lib/rubocop/cop/lint/symbol_conversion.rb', line 135
def requires_quotes?(sym_node) sym_node.value.inspect.match?(/^:".*?"|=$/) end