Class: RuboCop::Cop::Lint::RedundantTypeConversion
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::Base ,
::RuboCop::Cop::AutocorrectLogic ,
::RuboCop::Cop::IgnoredNode ,
::RuboCop::Util ,
RuboCop::AST::Sexp
|
|
Inherits: |
RuboCop::Cop::Base
|
Defined in: | lib/rubocop/cop/lint/redundant_type_conversion.rb |
Overview
Checks for redundant uses of to_s
, to_sym
, to_i
, to_f
, to_r
, to_c
,
to_a
, to_h
, and to_set
.
When one of these methods is called on an object of the same type, that object
is returned, making the call unnecessary. The cop detects conversion methods called
on object literals, class constructors, class []
methods, and the Kernel
methods
String()
, Integer()
, Float()
, Rational()
, Complex()
and Array()
.
Specifically, these cases are detected for each conversion method:
-
to_s
when called on a string literal, interpolated string, heredoc, or withString.new
orString()
. -
to_sym
when called on a symbol literal or interpolated symbol. -
to_i
when called on an integer literal or withInteger()
. -
to_f
when called on a float literal of withFloat()
. -
to_r
when called on a rational literal or withRational()
. -
to_c
when called on a complex literal of withComplex()
. -
to_a
when called on an array literal, or withArray.new
,Array()
orArray[]
. -
to_h
when called on a hash literal, or withHash.new
,Hash()
orHash[]
. -
to_set
when called onSet.new
orSet[]
.
In all cases, chaining one same to_*
conversion methods listed above is redundant.
The cop can also register an offense for chaining conversion methods on methods that are
expected to return a specific type regardless of receiver (eg. foo.inspect.to_s
).
Constant Summary
-
CONSTRUCTOR_MAPPING =
private
Maps each conversion method to the pattern matcher for that type’s constructors Not every type has a constructor, for instance Symbol.
{ to_s: 'string_constructor?', to_i: 'integer_constructor?', to_f: 'float_constructor?', to_r: 'rational_constructor?', to_c: 'complex_constructor?', to_a: 'array_constructor?', to_h: 'hash_constructor?', to_set: 'set_constructor?' }.freeze
-
CONVERSION_METHODS =
# File 'lib/rubocop/cop/lint/redundant_type_conversion.rb', line 102Set[*LITERAL_NODE_TYPES.keys].freeze
-
LITERAL_NODE_TYPES =
private
Maps conversion methods to the node types for the literals of that type
{ to_s: %i[str dstr], to_sym: %i[sym dsym], to_i: %i[int], to_f: %i[float], to_r: %i[rational], to_c: %i[complex], to_a: %i[array], to_h: %i[hash], to_set: [] # sets don't have a literal or node type }.freeze
-
MSG =
# File 'lib/rubocop/cop/lint/redundant_type_conversion.rb', line 70'Redundant `%<method>s` detected.'
-
RESTRICT_ON_SEND =
# File 'lib/rubocop/cop/lint/redundant_type_conversion.rb', line 103CONVERSION_METHODS
-
TYPED_METHODS =
Methods that already are expected to return a given type, which makes a further conversion redundant.
{ to_s: %i[inspect] }.freeze
::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
- #array_constructor?(node)
- #complex_constructor?(node)
- #float_constructor?(node)
- #hash_constructor?(node)
- #integer_constructor?(node)
-
#on_csend(node)
Alias for #on_send.
- #on_send(node) (also: #on_csend)
- #rational_constructor?(node)
- #set_constructor?(node)
- #string_constructor?(node)
- #type_constructor?(node, type_symbol)
- #chained_conversion?(node, receiver) ⇒ Boolean private
- #chained_to_typed_method?(node, receiver) ⇒ Boolean private
- #constructor?(node, receiver) ⇒ Boolean private
- #find_receiver(node) private
- #hash_or_set_with_block?(node) ⇒ Boolean private
- #literal_receiver?(node, receiver) ⇒ Boolean private
::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
#array_constructor?(node)
[ GitHub ]# File 'lib/rubocop/cop/lint/redundant_type_conversion.rb', line 141
def_node_matcher :array_constructor?, <<~PATTERN { (send (const {cbase nil?} :Array) {:new :[]} ...) #type_constructor?(:Array) } PATTERN
#chained_conversion?(node, receiver) ⇒ Boolean
(private)
# File 'lib/rubocop/cop/lint/redundant_type_conversion.rb', line 217
def chained_conversion?(node, receiver) return false unless receiver&.call_type? receiver.method?(node.method_name) end
#chained_to_typed_method?(node, receiver) ⇒ Boolean
(private)
# File 'lib/rubocop/cop/lint/redundant_type_conversion.rb', line 223
def chained_to_typed_method?(node, receiver) return false unless receiver&.call_type? TYPED_METHODS.fetch(node.method_name, []).include?(receiver.method_name) end
#complex_constructor?(node)
[ GitHub ]# File 'lib/rubocop/cop/lint/redundant_type_conversion.rb', line 136
def_node_matcher :complex_constructor?, <<~PATTERN #type_constructor?(:Complex) PATTERN
#constructor?(node, receiver) ⇒ Boolean
(private)
# File 'lib/rubocop/cop/lint/redundant_type_conversion.rb', line 210
def constructor?(node, receiver) matcher = CONSTRUCTOR_MAPPING[node.method_name] return false unless matcher public_send(matcher, receiver) end
#find_receiver(node) (private)
[ GitHub ]# File 'lib/rubocop/cop/lint/redundant_type_conversion.rb', line 191
def find_receiver(node) receiver = node.receiver return unless receiver while receiver.begin_type? break unless receiver.children.one? receiver = receiver.children.first end receiver end
#float_constructor?(node)
[ GitHub ]# File 'lib/rubocop/cop/lint/redundant_type_conversion.rb', line 126
def_node_matcher :float_constructor?, <<~PATTERN #type_constructor?(:Float) PATTERN
#hash_constructor?(node)
[ GitHub ]# File 'lib/rubocop/cop/lint/redundant_type_conversion.rb', line 149
def_node_matcher :hash_constructor?, <<~PATTERN { (block (send (const {cbase nil?} :Hash) :new) ...) (send (const {cbase nil?} :Hash) {:new :[]} ...) (send {nil? (const {cbase nil?} :Kernel)} :Hash ...) } PATTERN
#hash_or_set_with_block?(node) ⇒ Boolean
(private)
# File 'lib/rubocop/cop/lint/redundant_type_conversion.rb', line 185
def hash_or_set_with_block?(node) return false if !node.method?(:to_h) && !node.method?(:to_set) node.parent&.any_block_type? || node.last_argument&.block_pass_type? end
#integer_constructor?(node)
[ GitHub ]# File 'lib/rubocop/cop/lint/redundant_type_conversion.rb', line 121
def_node_matcher :integer_constructor?, <<~PATTERN #type_constructor?(:Integer) PATTERN
#literal_receiver?(node, receiver) ⇒ Boolean
(private)
# File 'lib/rubocop/cop/lint/redundant_type_conversion.rb', line 204
def literal_receiver?(node, receiver) return false unless receiver receiver.type?(*LITERAL_NODE_TYPES[node.method_name]) end
#on_csend(node)
Alias for #on_send.
# File 'lib/rubocop/cop/lint/redundant_type_conversion.rb', line 181
alias on_csend on_send
#on_send(node) Also known as: #on_csend
[ GitHub ]# File 'lib/rubocop/cop/lint/redundant_type_conversion.rb', line 165
def on_send(node) return if hash_or_set_with_block?(node) receiver = find_receiver(node) return unless literal_receiver?(node, receiver) || constructor?(node, receiver) || chained_conversion?(node, receiver) || chained_to_typed_method?(node, receiver) = format(MSG, method: node.method_name) add_offense(node.loc.selector, message: ) do |corrector| corrector.remove(node.loc.dot.join(node.loc.selector)) end end
#rational_constructor?(node)
[ GitHub ]# File 'lib/rubocop/cop/lint/redundant_type_conversion.rb', line 131
def_node_matcher :rational_constructor?, <<~PATTERN #type_constructor?(:Rational) PATTERN
#set_constructor?(node)
[ GitHub ]# File 'lib/rubocop/cop/lint/redundant_type_conversion.rb', line 158
def_node_matcher :set_constructor?, <<~PATTERN { (send (const {cbase nil?} :Set) {:new :[]} ...) } PATTERN
#string_constructor?(node)
[ GitHub ]# File 'lib/rubocop/cop/lint/redundant_type_conversion.rb', line 113
def_node_matcher :string_constructor?, <<~PATTERN { (send (const {cbase nil?} :String) :new ...) #type_constructor?(:String) } PATTERN
#type_constructor?(node, type_symbol)
[ GitHub ]# File 'lib/rubocop/cop/lint/redundant_type_conversion.rb', line 108
def_node_matcher :type_constructor?, <<~PATTERN (send {nil? (const {cbase nil?} :Kernel)} %1 ...) PATTERN