A validator/checker of a bindings model @api public
@api private
# File lib/puppet/pops/binder/bindings_checker.rb, line 186 def binding_parent(p) begin x = p.eContainer if x.nil? acceptor.accept(Issues::MODEL_OBJECT_IS_UNBOUND, p) return nil end p = x end while !p.is_a?(Bindings::AbstractBinding) p end
Performs binding validity check @api private
# File lib/puppet/pops/binder/bindings_checker.rb, line 33 def check(b) @@check_visitor.visit_this_0(self, b) end
Checks that the type declared in the binder is a PArrayType @api private
# File lib/puppet/pops/binder/bindings_checker.rb, line 144 def check_ArrayMultibindProducerDescriptor(p) b = binding_parent(p) acceptor.accept(Issues::MULTIBIND_INCOMPATIBLE_TYPE, p, {:binding => b, :actual_type => b.type}) unless b.type.is_a?(Types::PArrayType) end
Checks that a binding has a producer and a type @api private
# File lib/puppet/pops/binder/bindings_checker.rb, line 39 def check_Binding(b) # Must have a type acceptor.accept(Issues::MISSING_TYPE, b) unless b.type.is_a?(Types::PAnyType) # Must have a producer acceptor.accept(Issues::MISSING_PRODUCER, b) unless b.producer.is_a?(Bindings::ProducerDescriptor) end
Checks that the bindings object contains at least one binding. Then checks each binding in turn @api private
# File lib/puppet/pops/binder/bindings_checker.rb, line 63 def check_Bindings(b) acceptor.accept(Issues::MISSING_BINDINGS, b) unless has_entries?(b.bindings) end
Checks that a constant value has been declared in the producer and that the type of the value is compatible with the type declared in the binding @api private
# File lib/puppet/pops/binder/bindings_checker.rb, line 95 def check_ConstantProducerDescriptor(p) # the product must be of compatible type # TODO: Likely to change when value becomes a typed Puppet Object b = binding_parent(p) if p.value.nil? acceptor.accept(Issues::MISSING_VALUE, p, {:binding => b}) else infered = type_calculator.infer(p.value) unless type_calculator.assignable?(b.type, infered) acceptor.accept(Issues::INCOMPATIBLE_TYPE, p, {:binding => b, :expected_type => b.type, :actual_type => infered}) end end end
Checks that an expression has been declared in the producer @api private
# File lib/puppet/pops/binder/bindings_checker.rb, line 111 def check_EvaluatingProducerDescriptor(p) unless p.expression.is_a?(Puppet::Pops::Model::Expression) acceptor.accept(Issues::MISSING_EXPRESSION, p, {:binding => binding_parent(p)}) end end
@api private
# File lib/puppet/pops/binder/bindings_checker.rb, line 165 def check_Expression(t) @expression_validator.validate(t) end
Checks that a key has been declared, then calls producer_LookupProducerDescriptor to perform checks associated with the super class @api private
# File lib/puppet/pops/binder/bindings_checker.rb, line 137 def check_HashLookupProducerDescriptor(p) acceptor.accept(Issues::MISSING_KEY, p, {:binding => binding_parent(p)}) unless has_chars?(p.key) check_LookupProducerDescriptor(p) end
Checks that the type declared in the binder is a PHashType @api private
# File lib/puppet/pops/binder/bindings_checker.rb, line 151 def check_HashMultibindProducerDescriptor(p) b = binding_parent(p) acceptor.accept(Issues::MULTIBIND_INCOMPATIBLE_TYPE, p, {:binding => b, :actual_type => b.type}) unless b.type.is_a?(Types::PHashType) end
Checks that a class name has been declared in the producer @api private
# File lib/puppet/pops/binder/bindings_checker.rb, line 119 def check_InstanceProducerDescriptor(p) acceptor.accept(Issues::MISSING_CLASS_NAME, p, {:binding => binding_parent(p)}) unless has_chars?(p.class_name) end
Checks that the binding has layers and that each layer has a name and at least one binding @api private
# File lib/puppet/pops/binder/bindings_checker.rb, line 82 def check_LayeredBindings(b) acceptor.accept(Issues::MISSING_LAYERS, b) unless has_entries?(b.layers) end
Checks that a type and a name has been declared. The type must be assignable to the type declared in the binding. The name can be an empty string to denote ‘no name’ @api private
# File lib/puppet/pops/binder/bindings_checker.rb, line 126 def check_LookupProducerDescriptor(p) b = binding_parent(p) unless type_calculator.assignable(b.type, p.type) acceptor.accept(Issues::INCOMPATIBLE_TYPE, p, {:binding => b, :expected_type => b.type, :actual_type => p.type }) end acceptor.accept(Issues::MISSING_NAME, p, {:binding => b}) if p.name.nil? # empty string is OK end
Checks that the producer is a Multibind producer and that the type is a PCollectionType @api private
# File lib/puppet/pops/binder/bindings_checker.rb, line 49 def check_Multibinding(b) # id is optional (empty id blocks contributions) # A multibinding must have PCollectionType acceptor.accept(Issues::MULTIBIND_TYPE_ERROR, b, {:actual_type => b.type}) unless b.type.is_a?(Types::PCollectionType) # if the producer is nil, a suitable producer will be picked automatically unless b.producer.nil? || b.producer.is_a?(Bindings::MultibindProducerDescriptor) acceptor.accept(Issues::MULTIBIND_NOT_COLLECTION_PRODUCER, b, {:actual_producer => b.producer}) end end
Checks that a name has been associated with the bindings @api private
# File lib/puppet/pops/binder/bindings_checker.rb, line 69 def check_NamedBindings(b) acceptor.accept(Issues::MISSING_BINDINGS_NAME, b) unless has_chars?(b.name) check_Bindings(b) end
Check layer has a name @api private
# File lib/puppet/pops/binder/bindings_checker.rb, line 76 def check_NamedLayer(l) acceptor.accept(Issues::MISSING_LAYER_NAME, binding_parent(l)) unless has_chars?(l.name) end
Checks that the non caching producer has a producer to delegate to @api private
# File lib/puppet/pops/binder/bindings_checker.rb, line 88 def check_NonCachingProducerDescriptor(p) acceptor.accept(Issues::PRODUCER_MISSING_PRODUCER, p) unless p.producer.is_a?(Bindings::ProducerDescriptor) end
@api private
# File lib/puppet/pops/binder/bindings_checker.rb, line 170 def check_PAnyType(t) # Do nothing end
Checks that the producer that this producer delegates to is declared @api private
# File lib/puppet/pops/binder/bindings_checker.rb, line 158 def check_ProducerProducerDescriptor(p) unless p.producer.is_a?(Bindings::ProducerDescriptor) acceptor.accept(Issues::PRODUCER_MISSING_PRODUCER, p, {:binding => binding_parent(p)}) end end
Returns true if the argument is a non empty string @api private
# File lib/puppet/pops/binder/bindings_checker.rb, line 176 def has_chars?(s) s.is_a?(String) && !s.empty? end
@api private
# File lib/puppet/pops/binder/bindings_checker.rb, line 181 def has_entries?(s) !(s.nil? || s.empty?) end
Validates the entire model by visiting each model element and calling `check`. The result is collected (or acted on immediately) by the configured diagnostic provider/acceptor given when creating this Checker.
@api public
# File lib/puppet/pops/binder/bindings_checker.rb, line 26 def validate(b) check(b) b.eAllContents.each {|c| check(c) } end
@api public
# File lib/puppet/pops/binder/bindings_checker.rb, line 13 def initialize(diagnostics_producer) @@check_visitor ||= Puppet::Pops::Visitor.new(nil, "check", 0, 0) @type_calculator = Puppet::Pops::Types::TypeCalculator.new() @expression_validator = Puppet::Pops::Validation::ValidatorFactory_4_0.new().checker(diagnostics_producer) @acceptor = diagnostics_producer end