Class: RuboCop::AST::NodePattern::Compiler::Binding

Inherits:
Object
  • Object
show all
Defined in:
lib/rubocop/ast/node_pattern/compiler/binding.rb

Overview

Holds the list of bound variable names

Instance Method Summary collapse

Constructor Details

#initializeBinding

Returns a new instance of Binding.



9
10
11
# File 'lib/rubocop/ast/node_pattern/compiler/binding.rb', line 9

def initialize
  @bound = {}
end

Instance Method Details

#bind(name) ⇒ String

Yields the first time a given name is bound

Returns:

  • (String)

    bound variable name



16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/rubocop/ast/node_pattern/compiler/binding.rb', line 16

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

#union_bind(enum) ⇒ Object

rubocop:disable Metrics/MethodLength, Metrics/AbcSize



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/rubocop/ast/node_pattern/compiler/binding.rb', line 30

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