Class: RuboCop::Cop::Style::ComparableClamp
- Extended by:
- AutoCorrector, TargetRubyVersion
- Includes:
- Alignment
- Defined in:
- lib/rubocop/cop/style/comparable_clamp.rb
Overview
Enforces the use of Comparable#clamp
instead of comparison by minimum and maximum.
This cop supports autocorrection for if/elsif/else
bad style only.
Because ArgumentError
occurs if the minimum and maximum of clamp
arguments are reversed.
When these are variables, it is not possible to determine which is the minimum and maximum:
[1, [2, 3].max].min # => 1
1.clamp(3, 1) # => min argument must be smaller than max argument (ArgumentError)
Constant Summary collapse
- MSG =
'Use `%<prefer>s` instead of `if/elsif/else`.'
- MSG_MIN_MAX =
'Use `Comparable#clamp` instead.'
- RESTRICT_ON_SEND =
%i[min max].freeze
Instance Attribute Summary
Attributes inherited from Base
Instance Method Summary collapse
- #array_min_max?(node) ⇒ Object
- #if_elsif_else_condition?(node) ⇒ Object
- #on_if(node) ⇒ Object
- #on_send(node) ⇒ Object
Methods included from AutoCorrector
Methods included from TargetRubyVersion
minimum_target_ruby_version, required_minimum_ruby_version, support_target_ruby_version?
Methods inherited from Base
#active_support_extensions_enabled?, #add_global_offense, #add_offense, autocorrect_incompatible_with, badge, #begin_investigation, 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, #inspect, 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
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
Constructor Details
This class inherits a constructor from RuboCop::Cop::Base
Instance Method Details
#array_min_max?(node) ⇒ Object
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/rubocop/cop/style/comparable_clamp.rb', line 61 def_node_matcher :array_min_max?, <<~PATTERN { (send (array (send (array _ _) :max) _) :min) (send (array _ (send (array _ _) :max)) :min) (send (array (send (array _ _) :min) _) :max) (send (array _ (send (array _ _) :min)) :max) } PATTERN |
#if_elsif_else_condition?(node) ⇒ Object
47 48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/rubocop/cop/style/comparable_clamp.rb', line 47 def_node_matcher :if_elsif_else_condition?, <<~PATTERN { (if (send _x :< _min) _min (if (send _max :< _x) _max _x)) (if (send _min :> _x) _min (if (send _max :< _x) _max _x)) (if (send _x :< _min) _min (if (send _x :> _max) _max _x)) (if (send _min :> _x) _min (if (send _x :> _max) _max _x)) (if (send _max :< _x) _max (if (send _x :< _min) _min _x)) (if (send _x :> _max) _max (if (send _x :< _min) _min _x)) (if (send _max :< _x) _max (if (send _min :> _x) _min _x)) (if (send _x :> _max) _max (if (send _min :> _x) _min _x)) } PATTERN |
#on_if(node) ⇒ Object
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/rubocop/cop/style/comparable_clamp.rb', line 78 def on_if(node) return unless if_elsif_else_condition?(node) if_body, elsif_body, else_body = *node.branches else_body_source = else_body.source if min_condition?(node.condition, else_body_source) min = if_body.source max = elsif_body.source else min = elsif_body.source max = if_body.source end prefer = "#{else_body_source}.clamp(#{min}, #{max})" add_offense(node, message: format(MSG, prefer: prefer)) do |corrector| autocorrect(corrector, node, prefer) end end |
#on_send(node) ⇒ Object
100 101 102 103 104 |
# File 'lib/rubocop/cop/style/comparable_clamp.rb', line 100 def on_send(node) return unless array_min_max?(node) add_offense(node, message: MSG_MIN_MAX) end |