Class: Puppet::Pops::Binder::BindingsChecker

Inherits:
Object
  • Object
show all
Defined in:
lib/puppet/pops/binder/bindings_checker.rb

Constant Summary collapse

Bindings =
Bindings
Issues =
BinderIssues
Types =
Types

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(diagnostics_producer) ⇒ BindingsChecker

Returns a new instance of BindingsChecker.



15
16
17
18
19
20
# File 'lib/puppet/pops/binder/bindings_checker.rb', line 15

def initialize(diagnostics_producer)
  @@check_visitor     ||= Visitor.new(nil, "check", 0, 0)
  @type_calculator      = Types::TypeCalculator.singleton
  @expression_validator = Validation::ValidatorFactory_4_0.new().checker(diagnostics_producer)
  @acceptor             = diagnostics_producer
end

Instance Attribute Details

#acceptorObject (readonly)



12
13
14
# File 'lib/puppet/pops/binder/bindings_checker.rb', line 12

def acceptor
  @acceptor
end

#type_calculatorObject (readonly)



11
12
13
# File 'lib/puppet/pops/binder/bindings_checker.rb', line 11

def type_calculator
  @type_calculator
end

Instance Method Details

#binding_parent(p) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



188
189
190
191
192
193
194
195
196
197
198
# File 'lib/puppet/pops/binder/bindings_checker.rb', line 188

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

#check(b) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Performs binding validity check



35
36
37
# File 'lib/puppet/pops/binder/bindings_checker.rb', line 35

def check(b)
  @@check_visitor.visit_this_0(self, b)
end

#check_ArrayMultibindProducerDescriptor(p) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Checks that the type declared in the binder is a PArrayType



146
147
148
149
# File 'lib/puppet/pops/binder/bindings_checker.rb', line 146

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

#check_Binding(b) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Checks that a binding has a producer and a type



41
42
43
44
45
46
47
# File 'lib/puppet/pops/binder/bindings_checker.rb', line 41

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

#check_Bindings(b) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Checks that the bindings object contains at least one binding. Then checks each binding in turn



65
66
67
# File 'lib/puppet/pops/binder/bindings_checker.rb', line 65

def check_Bindings(b)
  acceptor.accept(Issues::MISSING_BINDINGS, b) unless has_entries?(b.bindings)
end

#check_ConstantProducerDescriptor(p) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

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



97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/puppet/pops/binder/bindings_checker.rb', line 97

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

#check_EvaluatingProducerDescriptor(p) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Checks that an expression has been declared in the producer



113
114
115
116
117
# File 'lib/puppet/pops/binder/bindings_checker.rb', line 113

def check_EvaluatingProducerDescriptor(p)
  unless p.expression.is_a?(Model::Expression)
    acceptor.accept(Issues::MISSING_EXPRESSION, p, {:binding => binding_parent(p)})
  end
end

#check_Expression(t) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



167
168
169
# File 'lib/puppet/pops/binder/bindings_checker.rb', line 167

def check_Expression(t)
  @expression_validator.validate(t)
end

#check_HashLookupProducerDescriptor(p) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Checks that a key has been declared, then calls producer_LookupProducerDescriptor to perform checks associated with the super class



139
140
141
142
# File 'lib/puppet/pops/binder/bindings_checker.rb', line 139

def check_HashLookupProducerDescriptor(p)
  acceptor.accept(Issues::MISSING_KEY, p, {:binding => binding_parent(p)}) unless has_chars?(p.key)
  check_LookupProducerDescriptor(p)
end

#check_HashMultibindProducerDescriptor(p) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Checks that the type declared in the binder is a PHashType



153
154
155
156
# File 'lib/puppet/pops/binder/bindings_checker.rb', line 153

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

#check_InstanceProducerDescriptor(p) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Checks that a class name has been declared in the producer



121
122
123
# File 'lib/puppet/pops/binder/bindings_checker.rb', line 121

def check_InstanceProducerDescriptor(p)
  acceptor.accept(Issues::MISSING_CLASS_NAME, p, {:binding => binding_parent(p)}) unless has_chars?(p.class_name)
end

#check_LayeredBindings(b) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Checks that the binding has layers and that each layer has a name and at least one binding



84
85
86
# File 'lib/puppet/pops/binder/bindings_checker.rb', line 84

def check_LayeredBindings(b)
  acceptor.accept(Issues::MISSING_LAYERS, b) unless has_entries?(b.layers)
end

#check_LookupProducerDescriptor(p) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

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’



128
129
130
131
132
133
134
# File 'lib/puppet/pops/binder/bindings_checker.rb', line 128

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

#check_Multibinding(b) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Checks that the producer is a Multibind producer and that the type is a PCollectionType



51
52
53
54
55
56
57
58
59
60
61
# File 'lib/puppet/pops/binder/bindings_checker.rb', line 51

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

#check_NamedBindings(b) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Checks that a name has been associated with the bindings



71
72
73
74
# File 'lib/puppet/pops/binder/bindings_checker.rb', line 71

def check_NamedBindings(b)
  acceptor.accept(Issues::MISSING_BINDINGS_NAME, b) unless has_chars?(b.name)
  check_Bindings(b)
end

#check_NamedLayer(l) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Check layer has a name



78
79
80
# File 'lib/puppet/pops/binder/bindings_checker.rb', line 78

def check_NamedLayer(l)
  acceptor.accept(Issues::MISSING_LAYER_NAME, binding_parent(l)) unless has_chars?(l.name)
end

#check_NonCachingProducerDescriptor(p) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Checks that the non caching producer has a producer to delegate to



90
91
92
# File 'lib/puppet/pops/binder/bindings_checker.rb', line 90

def check_NonCachingProducerDescriptor(p)
  acceptor.accept(Issues::PRODUCER_MISSING_PRODUCER, p) unless p.producer.is_a?(Bindings::ProducerDescriptor)
end

#check_PAnyType(t) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



172
173
174
# File 'lib/puppet/pops/binder/bindings_checker.rb', line 172

def check_PAnyType(t)
  # Do nothing
end

#check_ProducerProducerDescriptor(p) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Checks that the producer that this producer delegates to is declared



160
161
162
163
164
# File 'lib/puppet/pops/binder/bindings_checker.rb', line 160

def check_ProducerProducerDescriptor(p)
  unless p.producer.is_a?(Bindings::ProducerDescriptor)
    acceptor.accept(Issues::PRODUCER_MISSING_PRODUCER, p, {:binding => binding_parent(p)})
  end
end

#has_chars?(s) ⇒ Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns true if the argument is a non empty string

Returns:

  • (Boolean)


178
179
180
# File 'lib/puppet/pops/binder/bindings_checker.rb', line 178

def has_chars?(s)
  s.is_a?(String) && !s.empty?
end

#has_entries?(s) ⇒ Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns:

  • (Boolean)


183
184
185
# File 'lib/puppet/pops/binder/bindings_checker.rb', line 183

def has_entries?(s)
  !(s.nil? || s.empty?)
end

#validate(b) ⇒ Object

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.



28
29
30
31
# File 'lib/puppet/pops/binder/bindings_checker.rb', line 28

def validate(b)
  check(b)
  b.eAllContents.each {|c| check(c) }
end