class RuboCop::Cop::Lint::OutOfRangeRegexpRef
puts $1 # => foo
# good
puts $2 # => nil
# bad - always returns nil
/(foo)bar/ =~ ‘foobar’
@example
and thus always returns nil.
This cops looks for references of Regexp captures that are out of range
def after_send(node)
def after_send(node) @valid_ref = nil if regexp_first_argument?(node) check_regexp(node.first_argument) elsif regexp_receiver?(node) check_regexp(node.receiver) end end
def check_regexp(node)
def check_regexp(node) return if node.interpolation? named_capture = node.each_capture(named: true).count @valid_ref = if named_capture.positive? named_capture else node.each_capture(named: false).count end end
def nth_ref_receiver?(send_node)
def nth_ref_receiver?(send_node) send_node.receiver&.nth_ref_type? end
def on_match_with_lvasgn(node)
def on_match_with_lvasgn(node) check_regexp(node.children.first) end
def on_new_investigation
def on_new_investigation @valid_ref = 0 end
def on_nth_ref(node)
def on_nth_ref(node) backref, = *node return if @valid_ref.nil? || backref <= @valid_ref message = format( MSG, backref: backref, count: @valid_ref.zero? ? 'no' : @valid_ref, group: @valid_ref == 1 ? 'group' : 'groups' ) add_offense(node, message: message) end
def on_when(node)
def on_when(node) regexp_conditions = node.conditions.select(&:regexp_type?) @valid_ref = regexp_conditions.map do |condition| check_regexp(condition) end.compact.max end
def regexp_first_argument?(send_node)
def regexp_first_argument?(send_node) send_node.first_argument&.regexp_type? \ && REGEXP_ARGUMENT_METHODS.include?(send_node.method_name) end
def regexp_receiver?(send_node)
def regexp_receiver?(send_node) send_node.receiver&.regexp_type? end