class Capybara::Selector::RegexpDisassembler::Expression

@api private

def alternation?

def alternation?
  (type == :meta) && !terminal?
end

def alternative_strings

def alternative_strings
  alts = alternatives.map { |sub_exp| sub_exp.extract_strings(alternation: true) }
  alts.all?(&:any?) ? Set.new(alts) : nil
end

def alternatives

def alternatives
  @exp.alternatives.map { |exp| Expression.new(exp) }
end

def each

def each
  @exp.each { |exp| yield Expression.new(exp) }
end

def extract_strings(process_alternatives)

def extract_strings(process_alternatives)
  strings = []
  each do |exp|
    next if exp.ignore?
    next strings.push(nil) if exp.optional? && !process_alternatives
    next strings.push(exp.alternative_strings) if exp.alternation? && process_alternatives
    strings.concat(exp.strings(process_alternatives))
  end
  strings
end

def fixed_repeat?

def fixed_repeat?
  min_repeat == max_repeat
end

def ignore?

def ignore?
  [Regexp::Expression::Assertion::NegativeLookahead,
   Regexp::Expression::Assertion::NegativeLookbehind].any? { |klass| @exp.is_a? klass }
end

def indeterminate?

def indeterminate?
  %i[meta set].include?(type)
end

def initialize(exp)

def initialize(exp)
  @exp = exp
end

def max_repeat

def max_repeat
  @exp.repetitions.end
end

def min_repeat

def min_repeat
  @exp.repetitions.begin
end

def optional?

def optional?
  min_repeat.zero?
end

def optional_strings

def optional_strings
  options_set(extract_strings(true))
end

def options_set(strs)

def options_set(strs)
  strs = [Set.new([[''], Array(strs)])]
  strs.push(nil) unless max_repeat == 1
  strs
end

def repeat_set(str)

def repeat_set(str)
  strs = Array(str * min_repeat)
  strs.push(nil) unless fixed_repeat?
  strs
end

def repeated_strings(process_alternatives)

def repeated_strings(process_alternatives)
  repeat_set extract_strings(process_alternatives)
end

def strings(process_alternatives)

def strings(process_alternatives)
  if indeterminate?
    [nil]
  elsif terminal?
    terminal_strings
  elsif optional?
    optional_strings
  else
    repeated_strings(process_alternatives)
  end
end

def terminal?

def terminal?
  @exp.terminal?
end

def terminal_strings

def terminal_strings
  text = case @exp.type
  when :literal then @exp.text
  when :escape then @exp.char
  else
    return [nil]
  end
  optional? ? options_set(text) : repeat_set(text)
end

def type

def type
  @exp.type
end