Class: RuboCop::Cop::Lint::ArrayLiteralInRegexp
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:
self,
::RuboCop::Cop::Interpolation ,
::RuboCop::Cop::Base ,
::RuboCop::Cop::AutocorrectLogic ,
::RuboCop::Cop::IgnoredNode ,
::RuboCop::Util ,
RuboCop::AST::Sexp
|
|
Inherits: |
RuboCop::Cop::Base
|
Defined in: | lib/rubocop/cop/lint/array_literal_in_regexp.rb |
Overview
Checks for an array literal interpolated inside a regexp.
When interpolating an array literal, it is converted to a string. This means
that when inside a regexp, it acts as a character class but with additional
quotes, spaces and commas that are likely not intended. For example,
/#{%w[a b c]}/
parses as /["a", "b", "c"]/
(or /["a, bc]/
without
repeated characters).
The cop can autocorrect to a character class (if all items in the array are a single character) or alternation (if the array contains longer items).
Note
|
This only considers interpolated arrays that contain only strings, symbols, integers, and floats. Any other type is not easily convertible to a character class or regexp alternation. |
Constant Summary
-
LITERAL_TYPES =
private
# File 'lib/rubocop/cop/lint/array_literal_in_regexp.rb', line 45%i[str sym int float true false nil].freeze
-
MSG_ALTERNATION =
# File 'lib/rubocop/cop/lint/array_literal_in_regexp.rb', line 49'Use alternation instead of interpolating an array in a regexp.'
-
MSG_CHARACTER_CLASS =
# File 'lib/rubocop/cop/lint/array_literal_in_regexp.rb', line 48'Use a character class instead of interpolating an array in a regexp.'
-
MSG_UNKNOWN =
# File 'lib/rubocop/cop/lint/array_literal_in_regexp.rb', line 50'Use alternation or a character class instead of interpolating an array ' \ 'in a regexp.'
::RuboCop::Cop::Base
- Inherited
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::Base
- Inherited
::RuboCop::Cop::AutocorrectLogic
- Included
Instance Method Summary
- #on_interpolation(begin_node)
- #alternation_for(values) private
- #array_of_literal_values?(node) ⇒ Boolean private
- #array_values(node) private
- #character_class?(values) ⇒ Boolean private
- #character_class_for(values) private
- #escape_values(values) private
- #register_array_of_literal_values(begin_node, node) private
- #register_array_of_nonliteral_values(node) private
::RuboCop::Cop::Interpolation
- Included
#on_dstr, | |
#on_dsym | Alias for Interpolation#on_dstr. |
#on_interpolation | Inspect the |
#on_node_with_interpolations, | |
#on_regexp | Alias for Interpolation#on_dstr. |
#on_xstr | Alias for Interpolation#on_dstr. |
::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_gem_version | Returns a gems locked versions (i.e. |
#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
#alternation_for(values) (private)
[ GitHub ]# File 'lib/rubocop/cop/lint/array_literal_in_regexp.rb', line 107
def alternation_for(values) "(?:#{escape_values(values).join('|')})" end
#array_of_literal_values?(node) ⇒ Boolean
(private)
# File 'lib/rubocop/cop/lint/array_literal_in_regexp.rb', line 68
def array_of_literal_values?(node) node.each_value.all? { |value| value.type?(*LITERAL_TYPES) } end
#array_values(node) (private)
[ GitHub ]# File 'lib/rubocop/cop/lint/array_literal_in_regexp.rb', line 93
def array_values(node) node.each_value.map do |value| value.respond_to?(:value) ? value.value : value.source end end
#character_class?(values) ⇒ Boolean
(private)
# File 'lib/rubocop/cop/lint/array_literal_in_regexp.rb', line 99
def character_class?(values) values.all? { |v| v.to_s.length == 1 } end
#character_class_for(values) (private)
[ GitHub ]# File 'lib/rubocop/cop/lint/array_literal_in_regexp.rb', line 103
def character_class_for(values) "[#{escape_values(values).join}]" end
#escape_values(values) (private)
[ GitHub ]# File 'lib/rubocop/cop/lint/array_literal_in_regexp.rb', line 111
def escape_values(values) # This may add extraneous escape characters, but they can be cleaned up # by `Style/RedundantRegexpEscape`. values.map { |value| Regexp.escape(value.to_s) } end
#on_interpolation(begin_node)
[ GitHub ]# File 'lib/rubocop/cop/lint/array_literal_in_regexp.rb', line 53
def on_interpolation(begin_node) final_node = begin_node.children.last return unless begin_node.parent.regexp_type? return unless final_node.array_type? if array_of_literal_values?(final_node) register_array_of_literal_values(begin_node, final_node) else register_array_of_nonliteral_values(begin_node) end end
#register_array_of_literal_values(begin_node, node) (private)
[ GitHub ]# File 'lib/rubocop/cop/lint/array_literal_in_regexp.rb', line 72
def register_array_of_literal_values(begin_node, node) array_values = array_values(node) if character_class?(array_values) = MSG_CHARACTER_CLASS replacement = character_class_for(array_values) else = MSG_ALTERNATION replacement = alternation_for(array_values) end add_offense(begin_node, message: ) do |corrector| corrector.replace(begin_node, replacement) end end
#register_array_of_nonliteral_values(node) (private)
[ GitHub ]# File 'lib/rubocop/cop/lint/array_literal_in_regexp.rb', line 88
def register_array_of_nonliteral_values(node) # Add offense but do not correct if the array contains any nonliteral values. add_offense(node, message: MSG_UNKNOWN) end