class RuboCop::AST::NodePattern::Compiler::Binding

Holds the list of bound variable names

def bind(name)

Returns:
  • (String) - bound variable name
def bind(name)
  var = @bound.fetch(name) do
    yield n = @bound[name] = "unify_#{name.gsub('-', '__')}"
    n
  end
  if var == :forbidden_unification
    raise Invalid, "Wildcard #{name} was first seen in a subset of a " \
                   "union and can't be used outside that union"
  end
  var
end

def forbid(names)

def forbid(names)
  names.each do |name|
    @bound[name] = :forbidden_unification
  end
end

def initialize

def initialize
  @bound = {}
end

def union_bind(enum)

rubocop:disable Metrics/MethodLength, Metrics/AbcSize
def union_bind(enum)
  # We need to reset @bound before each branch is processed.
  # Moreover we need to keep track of newly encountered wildcards.
  # Var `newly_bound_intersection` will hold those that are encountered
  # in all branches; these are not a problem.
  # Var `partially_bound` will hold those encountered in only a subset
  # of the branches; these can't be used outside of the union.
  return to_enum __method__, enum unless block_given?
  newly_bound_intersection = nil
  partially_bound = []
  bound_before = @bound.dup
  result = enum.each do |e|
    @bound = bound_before.dup if newly_bound_intersection
    yield e
    newly_bound = @bound.keys - bound_before.keys
    if newly_bound_intersection.nil?
      # First iteration
      newly_bound_intersection = newly_bound
    else
      union = newly_bound_intersection | newly_bound
      newly_bound_intersection &= newly_bound
      partially_bound |= union - newly_bound_intersection
    end
  end
  # At this point, all members of `newly_bound_intersection` can be used
  # for unification outside of the union, but partially_bound may not
  forbid(partially_bound)
  result
end