lib/rubocop/cop/style/ternary_parentheses.rb in rubocop-0.42.0 vs lib/rubocop/cop/style/ternary_parentheses.rb in rubocop-0.43.0
- old
+ new
@@ -2,17 +2,17 @@
# frozen_string_literal: true
module RuboCop
module Cop
module Style
- # This cop checks for the presence of arentheses around ternary
+ # This cop checks for the presence of parentheses around ternary
# conditions. It is configurable to enforce inclusion or omission of
# parentheses using `EnforcedStyle`.
#
# @example
#
- # EnforcedStyle: require_no_parentheses (deafault)
+ # EnforcedStyle: require_no_parentheses (default)
#
# @bad
# foo = (bar?) ? a : b
# foo = (bar.baz) ? a : b
# foo = (bar && baz) ? a : b
@@ -53,23 +53,24 @@
def offense?(node)
condition, = *node
(require_parentheses? && !parenthesized?(condition) ||
!require_parentheses? && parenthesized?(condition)) &&
- !(safe_assignment?(condition) && safe_assignment_allowed?)
+ !(safe_assignment?(condition) && safe_assignment_allowed?) &&
+ !infinite_loop?
end
def autocorrect(node)
condition, = *node
lambda do |corrector|
if require_parentheses?
corrector.insert_before(condition.source_range, '(')
corrector.insert_after(condition.source_range, ')')
else
- # Don't correct if it's a safe assignment
- unless safe_assignment?(condition)
+ unless safe_assignment?(condition) ||
+ unsafe_autocorrect?(condition)
corrector.remove(condition.loc.begin)
corrector.remove(condition.loc.end)
end
end
end
@@ -83,12 +84,41 @@
def require_parentheses?
style == :require_parentheses
end
+ def redundant_parentheses_enabled?
+ @config.for_cop('RedundantParentheses')['Enabled']
+ end
+
def parenthesized?(node)
node.source =~ /^\(.*\)$/
end
+
+ # When this cop is configured to enforce parentheses and the
+ # `RedundantParentheses` cop is enabled, it will cause an infinite loop
+ # as they compete to add and remove the parentheses respectively.
+ def infinite_loop?
+ require_parentheses? &&
+ redundant_parentheses_enabled?
+ end
+
+ def unsafe_autocorrect?(condition)
+ condition.children.any? do |child|
+ unparenthesized_method_call?(child)
+ end
+ end
+
+ def unparenthesized_method_call?(child)
+ argument = method_call_argument(child)
+
+ argument && argument !~ /^\(/
+ end
+
+ def_node_matcher :method_call_argument, <<-PATTERN
+ {(:defined? $...)
+ (send {(send ...) nil} _ $(send nil _)...)}
+ PATTERN
end
end
end
end