class Puppet::Pops::Binder::Binder

The Binder is responsible for processing layered bindings that can be used to setup an Injector.

An instance should be created and a call to {define_layers} should be made which will process the layered bindings (handle overrides, abstract entries etc.). The constructed hash with `key => InjectorEntry` mappings is obtained as {injector_entries}, and is used to initialize an {Puppet::Pops::Binder::Injector Injector}.

@api public

Attributes

anonymous_key[R]

The next anonymous key to use @api private

binder_precedence[R]

This binder’s precedence @api private

id_index[R]

@api private

injector_entries[R]

@api private

key_factory[R]

@api private

parent[R]

A parent Binder or nil @api private

Public Instance Methods

add_id_to_index(binding) click to toggle source
# File lib/puppet/pops/binder/binder.rb, line 109
def add_id_to_index(binding)
  return unless binding.is_a?(Puppet::Pops::Binder::Bindings::Multibinding) && !(id = binding.id).nil?
  @id_index[id] = @id_index[id] << binding
end
lookup(key) click to toggle source
# File lib/puppet/pops/binder/binder.rb, line 132
def lookup(key)
  if x = injector_entries[key]
    return x
  end
  @parent ?  @parent.lookup(key) :  nil
end
lookup_in_parent(key) click to toggle source
# File lib/puppet/pops/binder/binder.rb, line 128
def lookup_in_parent(key)
  @parent.nil? ? nil : @parent.lookup(key)
end
next_anonymous_key() click to toggle source

@api private

# File lib/puppet/pops/binder/binder.rb, line 103
def next_anonymous_key
  tmp = @anonymous_key
  @anonymous_key += 1
  tmp
end
promote_matching_bindings(to_binder, from_binder, multibind_id) click to toggle source
# File lib/puppet/pops/binder/binder.rb, line 114
def promote_matching_bindings(to_binder, from_binder, multibind_id)
  return if from_binder.nil?
  from_binder.id_index[ multibind_id ].each do |binding|
    key = key_factory.binding_key(binding)
    entry = lookup(key)
    unless entry.precedence == @binder_precedence
      # it is from a lower layer it must be promoted
      injector_entries[ key ] = Puppet::Pops::Binder::InjectorEntry.new(binding, binder_precedence)
    end
  end
  # recursive "up the parent chain" to promote all
  promote_matching_bindings(to_binder, from_binder.parent, multibind_id)
end

Public Class Methods

format_binding(b) click to toggle source

@api private

# File lib/puppet/pops/binder/binder.rb, line 140
def self.format_binding(b)
  type_name = Puppet::Pops::Types::TypeCalculator.new().string(b.type)
  layer_name, bindings_name = get_named_binding_layer_and_name(b)
  "binding: '#{type_name}/#{b.name}' in: '#{bindings_name}' in layer: '#{layer_name}'"
end
format_contribution_source(b) click to toggle source

@api private

# File lib/puppet/pops/binder/binder.rb, line 147
def self.format_contribution_source(b) 
  layer_name, bindings_name = get_named_binding_layer_and_name(b)
  "(layer: #{layer_name}, bindings: #{bindings_name})"
end
get_named_binding_layer_and_name(b) click to toggle source

@api private

# File lib/puppet/pops/binder/binder.rb, line 153
def self.get_named_binding_layer_and_name(b)
  return ['<unknown>', '<unknown>'] if b.nil?
  return [get_named_layer(b), b.name] if b.is_a?(Puppet::Pops::Binder::Bindings::NamedBindings)
  get_named_binding_layer_and_name(b.eContainer)
end
get_named_layer(b) click to toggle source

@api private

# File lib/puppet/pops/binder/binder.rb, line 160
def self.get_named_layer(b)
  return '<unknown>' if b.nil?
  return b.name if b.is_a?(Puppet::Pops::Binder::Bindings::NamedLayer)
  get_named_layer(b.eContainer)
end
new(layered_bindings, parent_binder=nil) click to toggle source

@api public

# File lib/puppet/pops/binder/binder.rb, line 34
def initialize(layered_bindings, parent_binder=nil)
  @parent = parent_binder
  @id_index = Hash.new() { |k, v| [] }

  @key_factory = Puppet::Pops::Binder::KeyFactory.new()

  # Resulting hash of all key -> binding
  @injector_entries = {}

  if @parent.nil?
    @anonymous_key = 0
    @binder_precedence = 0
  else
    # First anonymous key is the parent's next (non incremented key). (The parent can not change, it is
    # the final, free key).
    @anonymous_key = @parent.anonymous_key
    @binder_precedence = @parent.binder_precedence + 1
  end
  define_layers(layered_bindings)
end