Class: RuboCop::Cop::Utils::RegexpRanges
Relationships & Source Files | |
Inherits: | Object |
Defined in: | lib/rubocop/cop/utils/regexp_ranges.rb |
Overview
Helper to abstract complexity of building range pairs with octal escape reconstruction (needed for regexp_parser < 2.7).
Class Method Summary
- .new(root) ⇒ RegexpRanges constructor
Instance Attribute Summary
- #root readonly
Instance Method Summary
- #compound_token
- #pairs
- #compose_range(expressions, current) private
- #escaped_octal?(expr) ⇒ Boolean private
- #octal_digit?(char) ⇒ Boolean private
- #pop_octal_digits(expressions) private
- #populate(expr) private
- #populate_all private
- #process_set(expressions, current) private
Constructor Details
.new(root) ⇒ RegexpRanges
Instance Attribute Details
#root (readonly)
[ GitHub ]# File 'lib/rubocop/cop/utils/regexp_ranges.rb', line 9
attr_reader :root
Instance Method Details
#compose_range(expressions, current) (private)
[ GitHub ]# File 'lib/rubocop/cop/utils/regexp_ranges.rb', line 78
def compose_range(expressions, current) range_start, range_end = current.expressions range_start = if @compound_token.size.between?(1, 2) && octal_digit?(range_start.text) @compound_token.dup << range_start else [range_start] end range_end = [range_end] range_end.concat(pop_octal_digits(expressions)) if escaped_octal?(range_end.first) [range_start, range_end] end
#compound_token
[ GitHub ]# File 'lib/rubocop/cop/utils/regexp_ranges.rb', line 18
def compound_token populate_all unless @populated @compound_token end
#escaped_octal?(expr) ⇒ Boolean
(private)
# File 'lib/rubocop/cop/utils/regexp_ranges.rb', line 90
def escaped_octal?(expr) expr.text.valid_encoding? && expr.text =~ /^\\[0-7]$/ end
#octal_digit?(char) ⇒ Boolean
(private)
# File 'lib/rubocop/cop/utils/regexp_ranges.rb', line 94
def octal_digit?(char) ('0'..'7').cover?(char) end
#pairs
[ GitHub ]# File 'lib/rubocop/cop/utils/regexp_ranges.rb', line 24
def pairs populate_all unless @populated @pairs end
#pop_octal_digits(expressions) (private)
[ GitHub ]# File 'lib/rubocop/cop/utils/regexp_ranges.rb', line 98
def pop_octal_digits(expressions) digits = [] 2.times do next unless (next_child = expressions.first) next unless next_child.type == :literal && next_child.text =~ /^[0-7]$/ digits << expressions.shift end digits end
#populate(expr) (private)
[ GitHub ]# File 'lib/rubocop/cop/utils/regexp_ranges.rb', line 44
def populate(expr) expressions = expr.expressions.to_a until expressions.empty? current = expressions.shift if escaped_octal?(current) @compound_token << current @compound_token.concat(pop_octal_digits(expressions)) # If we have all the digits we can discard. end next unless current.type == :set process_set(expressions, current) @compound_token.clear end end
#populate_all (private)
[ GitHub ]# File 'lib/rubocop/cop/utils/regexp_ranges.rb', line 32
def populate_all populate(@root) # If either bound is a compound the first one is an escape # and that's all we need to work with. # If there are any cops that wanted to operate on the compound # expression we could wrap it with a facade class. @pairs.map! { |pair| pair.map(&:first) } @populated = true end
#process_set(expressions, current) (private)
[ GitHub ]# File 'lib/rubocop/cop/utils/regexp_ranges.rb', line 63
def process_set(expressions, current) case current.token when :range @pairs << compose_range(expressions, current) when :character # Child expressions may include the range we are looking for. populate(current) when :intersection # Each child expression could have child expressions that lead to ranges. current.expressions.each do |intersected| populate(intersected) end end end