class RuboCop::Cop::Lint::AmbiguousOperatorPrecedence
Looks for expressions containing multiple binary operators where precedence is ambiguous due to lack of parentheses. For example, in ‘1 + 2 * 3`, the multiplication will happen before the addition, but lexically it appears that the addition will happen first.
The cop does not consider unary operators (ie. ‘!a` or `-b`) or comparison operators (ie. `a =~ b`) because those are not ambiguous.
NOTE: Ranges are handled by ‘Lint/AmbiguousRange`.
@example
# bad a + b * c a || b && c a ** b + c # good (different precedence) a + (b * c) a || (b && c) (a ** b) + c # good (same precedence) a + b + c a * b / c % d
Constants
- MSG
- PRECEDENCE
- RESTRICT_ON_SEND
Public Instance Methods
on_and(node)
click to toggle source
# File lib/rubocop/cop/lint/ambiguous_operator_precedence.rb, line 54 def on_and(node) return unless (parent = node.parent) return if parent.begin_type? # if the `and` is in a `begin`, it's parenthesized already return unless parent.or_type? add_offense(node) do |corrector| autocorrect(corrector, node) end end
on_new_investigation()
click to toggle source
Calls superclass method
RuboCop::Cop::Base#on_new_investigation
# File lib/rubocop/cop/lint/ambiguous_operator_precedence.rb, line 47 def on_new_investigation # Cache the precedence of each node being investigated # so that we only need to calculate it once @node_precedences = {} super end
on_send(node)
click to toggle source
# File lib/rubocop/cop/lint/ambiguous_operator_precedence.rb, line 65 def on_send(node) return if node.parenthesized? return unless (parent = node.parent) return unless operator?(parent) return unless greater_precedence?(node, parent) add_offense(node) do |corrector| autocorrect(corrector, node) end end
Private Instance Methods
autocorrect(corrector, node)
click to toggle source
# File lib/rubocop/cop/lint/ambiguous_operator_precedence.rb, line 105 def autocorrect(corrector, node) corrector.wrap(node, '(', ')') end
greater_precedence?(node1, node2)
click to toggle source
# File lib/rubocop/cop/lint/ambiguous_operator_precedence.rb, line 89 def greater_precedence?(node1, node2) node1_precedence = precedence(node1) node2_precedence = precedence(node2) return false unless node1_precedence && node2_precedence node2_precedence > node1_precedence end
operator?(node)
click to toggle source
# File lib/rubocop/cop/lint/ambiguous_operator_precedence.rb, line 85 def operator?(node) (node.send_type? && RESTRICT_ON_SEND.include?(node.method_name)) || node.operator_keyword? end
operator_name(node)
click to toggle source
# File lib/rubocop/cop/lint/ambiguous_operator_precedence.rb, line 97 def operator_name(node) if node.send_type? node.method_name else node.operator.to_sym end end
precedence(node)
click to toggle source
# File lib/rubocop/cop/lint/ambiguous_operator_precedence.rb, line 79 def precedence(node) @node_precedences.fetch(node) do PRECEDENCE.index { |operators| operators.include?(operator_name(node)) } end end