class RuboCop::Cop::Style::RedundantRegexpCharacterClass
Checks for unnecessary single-element Regexp character classes.
@example
# bad r = /[x]/ # good r = /x/ # bad r = /[\s]/ # good r = /\s/ # bad r = %r{/[b]} # good r = %r{/b} # good r = /[ab]/
Constants
- MSG_REDUNDANT_CHARACTER_CLASS
- REQUIRES_ESCAPE_OUTSIDE_CHAR_CLASS_CHARS
Public Instance Methods
on_regexp(node)
click to toggle source
# File lib/rubocop/cop/style/redundant_regexp_character_class.rb, line 37 def on_regexp(node) each_redundant_character_class(node) do |loc| add_offense( loc, message: format( MSG_REDUNDANT_CHARACTER_CLASS, char_class: loc.source, element: without_character_class(loc) ) ) do |corrector| corrector.replace(loc, without_character_class(loc)) end end end
Private Instance Methods
backslash_b?(elem)
click to toggle source
# File lib/rubocop/cop/style/redundant_regexp_character_class.rb, line 101 def backslash_b?(elem) # \b's behavior is different inside and outside of a character class, matching word # boundaries outside but backspace (0x08) when inside. elem == '\b' end
backslash_zero?(elem)
click to toggle source
# File lib/rubocop/cop/style/redundant_regexp_character_class.rb, line 107 def backslash_zero?(elem) # See https://github.com/rubocop/rubocop/issues/11067 for details - in short "\0" != "0" - # the former means an Unicode code point `"\u0000"`, the latter a number character `"0"`. # Similarly "\032" means "\u001A". Other numbers starting with "\0" can also be mentioned. elem == '\0' end
each_redundant_character_class(node) { |loc.body| ... }
click to toggle source
# File lib/rubocop/cop/style/redundant_regexp_character_class.rb, line 53 def each_redundant_character_class(node) each_single_element_character_class(node) do |char_class| next unless redundant_single_element_character_class?(node, char_class) yield char_class.loc.body end end
each_single_element_character_class(node) { |expr| ... }
click to toggle source
# File lib/rubocop/cop/style/redundant_regexp_character_class.rb, line 61 def each_single_element_character_class(node) node.parsed_tree&.each_expression do |expr| next if expr.type != :set || expr.expressions.size != 1 next if expr.negative? next if %i[set posixclass nonposixclass].include?(expr.expressions.first.type) next if multiple_codepoins?(expr.expressions.first) yield expr end end
multiple_codepoins?(expression)
click to toggle source
# File lib/rubocop/cop/style/redundant_regexp_character_class.rb, line 83 def multiple_codepoins?(expression) expression.respond_to?(:codepoints) && expression.codepoints.count >= 2 end
redundant_single_element_character_class?(node, char_class)
click to toggle source
# File lib/rubocop/cop/style/redundant_regexp_character_class.rb, line 72 def redundant_single_element_character_class?(node, char_class) class_elem = char_class.expressions.first.text non_redundant = whitespace_in_free_space_mode?(node, class_elem) || backslash_b?(class_elem) || backslash_zero?(class_elem) || requires_escape_outside_char_class?(class_elem) !non_redundant end
requires_escape_outside_char_class?(elem)
click to toggle source
# File lib/rubocop/cop/style/redundant_regexp_character_class.rb, line 114 def requires_escape_outside_char_class?(elem) REQUIRES_ESCAPE_OUTSIDE_CHAR_CLASS_CHARS.include?(elem) end
whitespace_in_free_space_mode?(node, elem)
click to toggle source
# File lib/rubocop/cop/style/redundant_regexp_character_class.rb, line 95 def whitespace_in_free_space_mode?(node, elem) return false unless node.extended? /\s/.match?(elem) end
without_character_class(loc)
click to toggle source
# File lib/rubocop/cop/style/redundant_regexp_character_class.rb, line 87 def without_character_class(loc) without_character_class = loc.source[1..-2] # Adds `\` to prevent autocorrection that changes to an interpolated string when `[#]`. # e.g. From `/[#]{0}/` to `/#{0}/` loc.source == '[#]' ? "\\#{without_character_class}" : without_character_class end