class RuboCop::Cop::Style::RedundantParentheses
Checks for redundant parentheses.
@example
# bad (x) if ((y.z).nil?) # good x if y.z.nil?
Public Instance Methods
on_begin(node)
click to toggle source
# File lib/rubocop/cop/style/redundant_parentheses.rb, line 38 def on_begin(node) return if !parentheses?(node) || parens_allowed?(node) || ignore_syntax?(node) check(node) end
Private Instance Methods
allowed_ancestor?(node)
click to toggle source
# File lib/rubocop/cop/style/redundant_parentheses.rb, line 68 def allowed_ancestor?(node) # Don't flag `break(1)`, etc keyword_ancestor?(node) && parens_required?(node) end
allowed_expression?(node)
click to toggle source
# File lib/rubocop/cop/style/redundant_parentheses.rb, line 61 def allowed_expression?(node) allowed_ancestor?(node) || allowed_method_call?(node) || allowed_multiple_expression?(node) || allowed_ternary?(node) end
allowed_method_call?(node)
click to toggle source
# File lib/rubocop/cop/style/redundant_parentheses.rb, line 73 def allowed_method_call?(node) # Don't flag `method (arg) { }` arg_in_call_with_block?(node) && !parentheses?(node.parent) end
allowed_multiple_expression?(node)
click to toggle source
# File lib/rubocop/cop/style/redundant_parentheses.rb, line 78 def allowed_multiple_expression?(node) return false if node.children.one? ancestor = node.ancestors.first return false unless ancestor !ancestor.begin_type? && !ancestor.def_type? && !ancestor.block_type? end
allowed_ternary?(node)
click to toggle source
# File lib/rubocop/cop/style/redundant_parentheses.rb, line 87 def allowed_ternary?(node) return unless node&.parent&.if_type? node.parent.ternary? && ternary_parentheses_required? end
call_chain_starts_with_int?(begin_node, send_node)
click to toggle source
# File lib/rubocop/cop/style/redundant_parentheses.rb, line 234 def call_chain_starts_with_int?(begin_node, send_node) recv = first_part_of_call_chain(send_node) recv&.int_type? && (parent = begin_node.parent) && parent.send_type? && (parent.method?(:-@) || parent.method?(:+@)) end
check(begin_node)
click to toggle source
# File lib/rubocop/cop/style/redundant_parentheses.rb, line 125 def check(begin_node) node = begin_node.children.first return offense(begin_node, 'a keyword') if keyword_with_redundant_parentheses?(node) return offense(begin_node, 'a literal') if disallowed_literal?(begin_node, node) return offense(begin_node, 'a variable') if node.variable? return offense(begin_node, 'a constant') if node.const_type? return offense(begin_node, 'an interpolated expression') if interpolation?(begin_node) check_send(begin_node, node) if node.call_type? end
check_send(begin_node, node)
click to toggle source
# File lib/rubocop/cop/style/redundant_parentheses.rb, line 140 def check_send(begin_node, node) return check_unary(begin_node, node) if node.unary_operation? return unless method_call_with_redundant_parentheses?(node) return if call_chain_starts_with_int?(begin_node, node) offense(begin_node, 'a method call') end
check_unary(begin_node, node)
click to toggle source
# File lib/rubocop/cop/style/redundant_parentheses.rb, line 149 def check_unary(begin_node, node) return if begin_node.chained? node = node.children.first while suspect_unary?(node) return if node.send_type? && !method_call_with_redundant_parentheses?(node) offense(begin_node, 'an unary operation') end
disallowed_literal?(begin_node, node)
click to toggle source
# File lib/rubocop/cop/style/redundant_parentheses.rb, line 173 def disallowed_literal?(begin_node, node) node.literal? && !node.range_type? && !raised_to_power_negative_numeric?(begin_node, node) end
empty_parentheses?(node)
click to toggle source
# File lib/rubocop/cop/style/redundant_parentheses.rb, line 105 def empty_parentheses?(node) # Don't flag `()` node.children.empty? end
first_arg_begins_with_hash_literal?(node)
click to toggle source
# File lib/rubocop/cop/style/redundant_parentheses.rb, line 110 def first_arg_begins_with_hash_literal?(node) # Don't flag `method ({key: value})` or `method ({key: value}.method)` method_chain_begins_with_hash_literal?(node.children.first) && first_argument?(node) && !parentheses?(node.parent) end
first_argument?(node)
click to toggle source
# File lib/rubocop/cop/style/redundant_parentheses.rb, line 215 def first_argument?(node) first_send_argument?(node) || first_super_argument?(node) || first_yield_argument?(node) end
ignore_syntax?(node)
click to toggle source
# File lib/rubocop/cop/style/redundant_parentheses.rb, line 54 def ignore_syntax?(node) return false unless (parent = node.parent) parent.while_post_type? || parent.until_post_type? || like_method_argument_parentheses?(parent) end
keyword_ancestor?(node)
click to toggle source
# File lib/rubocop/cop/style/redundant_parentheses.rb, line 169 def keyword_ancestor?(node) node.parent&.keyword? end
keyword_with_redundant_parentheses?(node)
click to toggle source
# File lib/rubocop/cop/style/redundant_parentheses.rb, line 188 def keyword_with_redundant_parentheses?(node) return false unless node.keyword? return true if node.special_keyword? args = *node if only_begin_arg?(args) parentheses?(args.first) else args.empty? || parentheses?(node) end end
like_method_argument_parentheses?(node)
click to toggle source
# File lib/rubocop/cop/style/redundant_parentheses.rb, line 100 def like_method_argument_parentheses?(node) node.send_type? && node.arguments.one? && !node.arithmetic_operation? && node.first_argument.begin_type? end
method_call_with_redundant_parentheses?(node)
click to toggle source
# File lib/rubocop/cop/style/redundant_parentheses.rb, line 201 def method_call_with_redundant_parentheses?(node) return false unless node.call_type? return false if node.prefix_not? return false if range_end?(node) send_node, args = method_node_and_args(node) args.empty? || parentheses?(send_node) || square_brackets?(send_node) end
method_chain_begins_with_hash_literal?(node)
click to toggle source
# File lib/rubocop/cop/style/redundant_parentheses.rb, line 117 def method_chain_begins_with_hash_literal?(node) return false if node.nil? return true if node.hash_type? return false unless node.send_type? method_chain_begins_with_hash_literal?(node.children.first) end
offense(node, msg)
click to toggle source
# File lib/rubocop/cop/style/redundant_parentheses.rb, line 159 def offense(node, msg) add_offense(node, message: "Don't use parentheses around #{msg}.") do |corrector| ParenthesesCorrector.correct(corrector, node) end end
only_begin_arg?(args)
click to toggle source
# File lib/rubocop/cop/style/redundant_parentheses.rb, line 211 def only_begin_arg?(args) args.one? && args.first.begin_type? end
parens_allowed?(node)
click to toggle source
# File lib/rubocop/cop/style/redundant_parentheses.rb, line 46 def parens_allowed?(node) empty_parentheses?(node) || first_arg_begins_with_hash_literal?(node) || rescue?(node) || allowed_pin_operator?(node) || allowed_expression?(node) end
raised_to_power_negative_numeric?(begin_node, node)
click to toggle source
# File lib/rubocop/cop/style/redundant_parentheses.rb, line 177 def raised_to_power_negative_numeric?(begin_node, node) return false unless node.numeric_type? next_sibling = begin_node.right_sibling return false unless next_sibling base_value = node.children.first base_value.negative? && next_sibling == :** end
suspect_unary?(node)
click to toggle source
# File lib/rubocop/cop/style/redundant_parentheses.rb, line 165 def suspect_unary?(node) node.send_type? && node.unary_operation? && !node.prefix_not? end
ternary_parentheses_required?()
click to toggle source
# File lib/rubocop/cop/style/redundant_parentheses.rb, line 93 def ternary_parentheses_required? config = @config.for_cop('Style/TernaryParentheses') allowed_styles = %w[require_parentheses require_parentheses_when_complex] config.fetch('Enabled') && allowed_styles.include?(config['EnforcedStyle']) end