Class: RuboCop::Cop::Performance::RedundantEqualityComparisonBlock
Relationships & Source Files | |
Super Chains via Extension / Inclusion / Inheritance | |
Class Chain:
self,
TargetRubyVersion,
AutoCorrector,
Base
|
|
Instance Chain:
self,
Base
|
|
Inherits: |
Base
|
Defined in: | lib/rubocop/cop/performance/redundant_equality_comparison_block.rb |
Overview
Checks for uses Enumerable#all?
, Enumerable#any?
, Enumerable#one?
,
and Enumerable#none?
are compared with ===
or similar methods in block.
By default, Object#===
behaves the same as Object#==
, but this
behavior is appropriately overridden in subclass. For example,
Range#===
returns true
when argument is within the range.
This cop has AllowRegexpMatch
option and it is true by default because
regexp.match?('string')
often used in block changes to the opposite result:
[/pattern/].all? { |regexp| regexp.match?('pattern') } # => true
[/pattern/].all? { |regexp| regexp =~ 'pattern' } # => true
[/pattern/].all?('pattern') # => false
Constant Summary
-
COMPARISON_METHODS =
# File 'lib/rubocop/cop/performance/redundant_equality_comparison_block.rb', line 58%i[== === is_a? kind_of?].freeze
-
IS_A_METHODS =
# File 'lib/rubocop/cop/performance/redundant_equality_comparison_block.rb', line 60%i[is_a? kind_of?].freeze
-
MSG =
# File 'lib/rubocop/cop/performance/redundant_equality_comparison_block.rb', line 55'Use `%<prefer>s` instead of block.'
-
REGEXP_METHODS =
# File 'lib/rubocop/cop/performance/redundant_equality_comparison_block.rb', line 59%i[=~ match?].freeze
-
TARGET_METHODS =
# File 'lib/rubocop/cop/performance/redundant_equality_comparison_block.rb', line 57%i[all? any? one? none?].freeze
Instance Attribute Summary
- #allow_regexp_match? ⇒ Boolean readonly private
Instance Method Summary
- #on_block(node)
- #new_argument(block_argument, block_body) private
- #offense_range(node) private
- #one_block_argument?(block_arguments) ⇒ Boolean private
- #same_block_argument_and_is_a_argument?(block_body, block_argument) ⇒ Boolean private
- #use_block_argument_in_method_argument_of_operand?(block_argument, operand) ⇒ Boolean private
- #use_equality_comparison_block?(block_body) ⇒ Boolean private
Instance Attribute Details
#allow_regexp_match? ⇒ Boolean
(readonly, private)
[ GitHub ]
# File 'lib/rubocop/cop/performance/redundant_equality_comparison_block.rb', line 131
def allow_regexp_match? cop_config.fetch('AllowRegexpMatch', true) end
Instance Method Details
#new_argument(block_argument, block_body) (private)
[ GitHub ]# File 'lib/rubocop/cop/performance/redundant_equality_comparison_block.rb', line 104
def new_argument(block_argument, block_body) if block_argument.source == block_body.receiver.source rhs = block_body.first_argument return if use_block_argument_in_method_argument_of_operand?(block_argument, rhs) rhs.source elsif block_argument.source == block_body.first_argument.source lhs = block_body.receiver return if use_block_argument_in_method_argument_of_operand?(block_argument, lhs) lhs.source end end
#offense_range(node) (private)
[ GitHub ]# File 'lib/rubocop/cop/performance/redundant_equality_comparison_block.rb', line 127
def offense_range(node) node.send_node.loc.selector.join(node.source_range.end) end
#on_block(node)
[ GitHub ]# File 'lib/rubocop/cop/performance/redundant_equality_comparison_block.rb', line 62
def on_block(node) return unless TARGET_METHODS.include?(node.method_name) return unless one_block_argument?(node.arguments) block_argument = node.first_argument return unless (block_body = node.body) return unless use_equality_comparison_block?(block_body) return if same_block_argument_and_is_a_argument?(block_body, block_argument) return unless (new_argument = new_argument(block_argument, block_body)) range = offense_range(node) prefer = "#{node.method_name}(#{new_argument})" add_offense(range, message: format(MSG, prefer: prefer)) do |corrector| corrector.replace(range, prefer) end end
#one_block_argument?(block_arguments) ⇒ Boolean
(private)
# File 'lib/rubocop/cop/performance/redundant_equality_comparison_block.rb', line 82
def one_block_argument?(block_arguments) block_arguments.one? && !block_arguments.source.include?(',') end
#same_block_argument_and_is_a_argument?(block_body, block_argument) ⇒ Boolean
(private)
# File 'lib/rubocop/cop/performance/redundant_equality_comparison_block.rb', line 94
def same_block_argument_and_is_a_argument?(block_body, block_argument) if block_body.method?(:===) block_argument.source != block_body.children[2].source elsif IS_A_METHODS.include?(block_body.method_name) block_argument.source == block_body.first_argument.source else block_body.receiver.source == block_body.first_argument.receiver&.source end end
#use_block_argument_in_method_argument_of_operand?(block_argument, operand) ⇒ Boolean
(private)
# File 'lib/rubocop/cop/performance/redundant_equality_comparison_block.rb', line 118
def use_block_argument_in_method_argument_of_operand?(block_argument, operand) return false unless operand.send_type? arguments = operand.arguments arguments.inject(arguments.map(&:source)) do |operand_sources, argument| operand_sources + argument.each_descendant(:lvar).map(&:source) end.any?(block_argument.source) end
#use_equality_comparison_block?(block_body) ⇒ Boolean
(private)
# File 'lib/rubocop/cop/performance/redundant_equality_comparison_block.rb', line 86
def use_equality_comparison_block?(block_body) return false unless block_body.send_type? method_name = block_body.method_name COMPARISON_METHODS.include?(method_name) || (!allow_regexp_match? && REGEXP_METHODS.include?(method_name)) end