Class: Puppet::Pops::Validation::Checker4_0
- Defined in:
- lib/puppet/pops/validation/checker4_0.rb
Overview
A Validator validates a model.
Validation is performed on each model element in isolation. Each method should validate the model element’s state but not validate its referenced/contained elements except to check their validity in their respective role. The intent is to drive the validation with a tree iterator that visits all elements in a model.
TODO: Add validation of multiplicities - this is a general validation that can be checked for all
Model objects via their metamodel. (I.e an extra call to multiplicity check in polymorph check).
This is however mostly valuable when validating model to model transformations, and is therefore T.B.D
Constant Summary collapse
- Issues =
Puppet::Pops::Issues
- Model =
Puppet::Pops::Model
- RESERVED_TYPE_NAMES =
{ 'type' => true, 'any' => true, 'unit' => true, 'scalar' => true, 'boolean' => true, 'numeric' => true, 'integer' => true, 'float' => true, 'collection' => true, 'array' => true, 'hash' => true, 'tuple' => true, 'struct' => true, 'variant' => true, 'optional' => true, 'enum' => true, 'regexp' => true, 'pattern' => true, 'runtime' => true, }
- RESERVED_PARAMETERS =
{ 'name' => true, 'title' => true, }
Instance Attribute Summary collapse
- #acceptor ⇒ Object readonly
Instance Method Summary collapse
-
#assign(o, via_index = false) ⇒ Object
Checks the LHS of an assignment (is it assignable?).
- #assign_AccessExpression(o, via_index) ⇒ Object
- #assign_Object(o, via_index) ⇒ Object
-
#assign_VariableExpression(o, via_index) ⇒ Object
—ASSIGNMENT CHECKS.
-
#check(o) ⇒ Object
Performs regular validity check.
- #check_AccessExpression(o) ⇒ Object
- #check_AssignmentExpression(o) ⇒ Object
-
#check_AttributeOperation(o) ⇒ Object
Checks that operation with :+> is contained in a ResourceOverride or Collector.
- #check_AttributesOperation(o) ⇒ Object
- #check_BinaryExpression(o) ⇒ Object
- #check_BlockExpression(o) ⇒ Object
- #check_CallNamedFunctionExpression(o) ⇒ Object
- #check_CaseExpression(o) ⇒ Object
- #check_CaseOption(o) ⇒ Object
- #check_CollectExpression(o) ⇒ Object
- #check_EppExpression(o) ⇒ Object
- #check_Factory(o) ⇒ Object
- #check_HostClassDefinition(o) ⇒ Object
- #check_IfExpression(o) ⇒ Object
- #check_KeyedEntry(o) ⇒ Object
- #check_LambdaExpression(o) ⇒ Object
- #check_LiteralList(o) ⇒ Object
- #check_MethodCallExpression(o) ⇒ Object
-
#check_NamedAccessExpression(o) ⇒ Object
Only used for function names, grammar should not be able to produce something faulty, but check anyway if model is created programatically (it will fail in transformation to AST for sure).
-
#check_NamedDefinition(o) ⇒ Object
for ‘class’, ‘define’, and function.
- #check_NodeDefinition(o) ⇒ Object
-
#check_Object(o) ⇒ Object
—CHECKS.
- #check_Parameter(o) ⇒ Object
-
#check_QualifiedName(o) ⇒ Object
No checking takes place - all expressions using a QualifiedName need to check.
-
#check_QualifiedReference(o) ⇒ Object
Checks that the value is a valid UpperCaseWord (a CLASSREF), and optionally if it contains a hypen.
- #check_QueryExpression(o) ⇒ Object
-
#check_RelationshipExpression(o) ⇒ Object
relationship_side: resource | resourceref | collection | variable | quotedtext | selector | casestatement | hasharrayaccesses.
- #check_ReservedWord(o) ⇒ Object
- #check_ResourceBody(o) ⇒ Object
- #check_ResourceDefaultsExpression(o) ⇒ Object
- #check_ResourceExpression(o) ⇒ Object
- #check_ResourceOverrideExpression(o) ⇒ Object
- #check_ResourceTypeDefinition(o) ⇒ Object
- #check_SelectorEntry(o) ⇒ Object
- #check_SelectorExpression(o) ⇒ Object
- #check_UnaryExpression(o) ⇒ Object
- #check_UnlessExpression(o) ⇒ Object
-
#check_VariableExpression(o) ⇒ Object
Checks that variable is either strictly 0, or a non 0 starting decimal number, or a valid VAR_NAME.
-
#ends_with_idem(o) ⇒ Object
Returns the last expression in a block, or the expression, if that expression is idem.
-
#hostname(o, semantic, single_feature_name = nil) ⇒ Object
Performs check if this is a vaid hostname expression.
-
#hostname_Array(o, semantic, single_feature_name) ⇒ Object
Transforms Array of host matching expressions into a (Ruby) array of AST::HostName.
- #hostname_ConcatenatedString(o, semantic, single_feature_name) ⇒ Object
- #hostname_LiteralDefault(o, semantic, single_feature_name) ⇒ Object
- #hostname_LiteralNumber(o, semantic, single_feature_name) ⇒ Object
- #hostname_LiteralRegularExpression(o, semantic, single_feature_name) ⇒ Object
- #hostname_LiteralValue(o, semantic, single_feature_name) ⇒ Object
- #hostname_Object(o, semantic, single_feature_name) ⇒ Object
- #hostname_QualifiedName(o, semantic, single_feature_name) ⇒ Object
- #hostname_QualifiedReference(o, semantic, single_feature_name) ⇒ Object
- #hostname_String(o, semantic, single_feature_name) ⇒ Object
-
#idem(o) ⇒ Boolean
Checks if the expression has side effect (‘idem’ is latin for ‘the same’, here meaning that the evaluation state is known to be unchanged after the expression has been evaluated).
- #idem_AccessExpression(o) ⇒ Object
- #idem_AssignmentExpression(o) ⇒ Object
- #idem_BinaryExpression(o) ⇒ Object
- #idem_BlockExpression(o) ⇒ Object
-
#idem_CaseExpression(o) ⇒ Object
Case expression is idem, if test, and all options are idem.
-
#idem_CaseOption(o) ⇒ Object
An option is idem if values and the then_expression are idem.
-
#idem_ConcatenatedString(o) ⇒ Object
Returns true even though there may be interpolated expressions that have side effect.
- #idem_Factory(o) ⇒ Object
-
#idem_HeredocExpression(o) ⇒ Object
Heredoc is just a string, but may contain interpolated string (which may have side effects).
- #idem_IfExpression(o) ⇒ Object
- #idem_Literal(o) ⇒ Object
- #idem_LiteralHash(o) ⇒ Object
- #idem_LiteralList(o) ⇒ Object
- #idem_NilClass(o) ⇒ Object
- #idem_Nop(o) ⇒ Object
-
#idem_Object(o) ⇒ Object
–IDEM CHECK.
-
#idem_ParenthesizedExpression(o) ⇒ Object
Allow (no-effect parentheses) to be used around a productive expression.
- #idem_RelationshipExpression(o) ⇒ Object
- #idem_RenderExpression(o) ⇒ Object
- #idem_RenderStringExpression(o) ⇒ Object
-
#idem_SelectorExpression(o) ⇒ Object
May technically have side effects inside the Selector, but this is bad design - treat as idem.
-
#idem_UnaryExpression(o) ⇒ Object
Handles UnaryMinusExpression, NotExpression, VariableExpression.
-
#initialize(diagnostics_producer) ⇒ Checker4_0
constructor
Initializes the validator with a diagnostics producer.
- #internal_check_capture_last(o) ⇒ Object
- #internal_check_no_capture(o, container = o) ⇒ Object
- #internal_check_reserved_params(o) ⇒ Object
-
#query(o) ⇒ Object
Performs check if this is valid as a query.
-
#query_BooleanExpression(o) ⇒ Object
Allows AND, OR, and checks if left/right are allowed in query.
-
#query_ComparisonExpression(o) ⇒ Object
Puppet AST only allows == and !=.
- #query_LiteralBoolean(o) ⇒ Object
- #query_LiteralNumber(o) ⇒ Object
- #query_LiteralString(o) ⇒ Object
-
#query_Object(o) ⇒ Object
Anything not explicitly allowed is flagged as error.
- #query_ParenthesizedExpression(o) ⇒ Object
- #query_QualifiedName(o) ⇒ Object
- #query_VariableExpression(o) ⇒ Object
-
#relation(o) ⇒ Object
Performs check if this is valid as a relationship side.
- #relation_CollectExpression(o) ⇒ Object
- #relation_Object(o) ⇒ Object
- #relation_RelationshipExpression(o) ⇒ Object
-
#rvalue(o) ⇒ Object
Performs check if this is valid as a rvalue.
- #rvalue_CollectExpression(o) ⇒ Object
- #rvalue_Definition(o) ⇒ Object
-
#rvalue_Expression(o) ⇒ Object
By default, all expressions are reported as being rvalues Implement specific rvalue checks for those that are not.
- #rvalue_NodeDefinition(o) ⇒ Object
- #rvalue_UnaryExpression(o) ⇒ Object
-
#top(o, definition) ⇒ Object
Performs check if this is valid as a container of a definition (class, define, node).
- #top_BlockExpression(o, definition) ⇒ Object
- #top_HostClassDefinition(o, definition) ⇒ Object
-
#top_LambdaExpression(o, definition) ⇒ Object
A LambdaExpression is a BlockExpression, and this method is needed to prevent the polymorph method for BlockExpression to accept a lambda.
-
#top_NilClass(o, definition) ⇒ Object
—TOP CHECK.
- #top_Object(o, definition) ⇒ Object
- #top_Program(o, definition) ⇒ Object
-
#validate(model) ⇒ Object
Validates the entire model by visiting each model element and calling ‘check`.
-
#varname_to_s(o) ⇒ Object
Produces string part of something named, or nil if not a QualifiedName or QualifiedReference.
Constructor Details
#initialize(diagnostics_producer) ⇒ Checker4_0
Initializes the validator with a diagnostics producer. This object must respond to ‘:will_accept?` and `:accept`.
20 21 22 23 24 25 26 27 28 29 30 31 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 20 def initialize(diagnostics_producer) @@check_visitor ||= Puppet::Pops::Visitor.new(nil, "check", 0, 0) @@rvalue_visitor ||= Puppet::Pops::Visitor.new(nil, "rvalue", 0, 0) @@hostname_visitor ||= Puppet::Pops::Visitor.new(nil, "hostname", 1, 2) @@assignment_visitor ||= Puppet::Pops::Visitor.new(nil, "assign", 0, 1) @@query_visitor ||= Puppet::Pops::Visitor.new(nil, "query", 0, 0) @@top_visitor ||= Puppet::Pops::Visitor.new(nil, "top", 1, 1) @@relation_visitor ||= Puppet::Pops::Visitor.new(nil, "relation", 0, 0) @@idem_visitor ||= Puppet::Pops::Visitor.new(self, "idem", 0, 0) @acceptor = diagnostics_producer end |
Instance Attribute Details
#acceptor ⇒ Object (readonly)
16 17 18 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 16 def acceptor @acceptor end |
Instance Method Details
#assign(o, via_index = false) ⇒ Object
Checks the LHS of an assignment (is it assignable?). If args is true, assignment via index is checked.
77 78 79 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 77 def assign(o, via_index = false) @@assignment_visitor.visit_this_1(self, o, via_index) end |
#assign_AccessExpression(o, via_index) ⇒ Object
118 119 120 121 122 123 124 125 126 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 118 def assign_AccessExpression(o, via_index) # Are indexed assignments allowed at all ? $x[x] = '...' if acceptor.will_accept? Issues::ILLEGAL_INDEXED_ASSIGNMENT acceptor.accept(Issues::ILLEGAL_INDEXED_ASSIGNMENT, o) else # Then the left expression must be assignable-via-index assign(o.left_expr, true) end end |
#assign_Object(o, via_index) ⇒ Object
128 129 130 131 132 133 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 128 def assign_Object(o, via_index) # Can not assign to anything else (differentiate if this is via index or not) # i.e. 10 = 'hello' vs. 10['x'] = 'hello' (the root is reported as being in error in both cases) # acceptor.accept(via_index ? Issues::ILLEGAL_ASSIGNMENT_VIA_INDEX : Issues::ILLEGAL_ASSIGNMENT, o) end |
#assign_VariableExpression(o, via_index) ⇒ Object
—ASSIGNMENT CHECKS
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 102 def assign_VariableExpression(o, via_index) varname_string = varname_to_s(o.expr) if varname_string =~ Puppet::Pops::Patterns::NUMERIC_VAR_NAME acceptor.accept(Issues::ILLEGAL_NUMERIC_ASSIGNMENT, o, :varname => varname_string) end # Can not assign to something in another namespace (i.e. a '::' in the name is not legal) if acceptor.will_accept? Issues::CROSS_SCOPE_ASSIGNMENT if varname_string =~ /::/ acceptor.accept(Issues::CROSS_SCOPE_ASSIGNMENT, o, :name => varname_string) end end # TODO: Could scan for reassignment of the same variable if done earlier in the same container # Or if assigning to a parameter (more work). # TODO: Investigate if there are invalid cases for += assignment end |
#check(o) ⇒ Object
Performs regular validity check
44 45 46 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 44 def check(o) @@check_visitor.visit_this_0(self, o) end |
#check_AccessExpression(o) ⇒ Object
144 145 146 147 148 149 150 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 144 def check_AccessExpression(o) # Only min range is checked, all other checks are RT checks as they depend on the resulting type # of the LHS. if o.keys.size < 1 acceptor.accept(Issues::MISSING_INDEX, o) end end |
#check_AssignmentExpression(o) ⇒ Object
152 153 154 155 156 157 158 159 160 161 162 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 152 def check_AssignmentExpression(o) case o.operator when :'=' assign(o.left_expr) rvalue(o.right_expr) when :'+=', :'-=' acceptor.accept(Issues::APPENDS_DELETES_NO_LONGER_SUPPORTED, o, {:operator => o.operator}) else acceptor.accept(Issues::UNSUPPORTED_OPERATOR, o, {:operator => o.operator}) end end |
#check_AttributeOperation(o) ⇒ Object
Checks that operation with :+> is contained in a ResourceOverride or Collector.
Parent of an AttributeOperation can be one of:
-
CollectExpression
-
ResourceOverride
-
ResourceBody (ILLEGAL this is a regular resource expression)
-
ResourceDefaults (ILLEGAL)
172 173 174 175 176 177 178 179 180 181 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 172 def check_AttributeOperation(o) if o.operator == :'+>' # Append operator use is constrained parent = o.eContainer unless parent.is_a?(Model::CollectExpression) || parent.is_a?(Model::ResourceOverrideExpression) acceptor.accept(Issues::ILLEGAL_ATTRIBUTE_APPEND, o, {:name=>o.attribute_name, :parent=>parent}) end end rvalue(o.value_expr) end |
#check_AttributesOperation(o) ⇒ Object
183 184 185 186 187 188 189 190 191 192 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 183 def check_AttributesOperation(o) # Append operator use is constrained parent = o.eContainer parent = parent.eContainer unless parent.nil? unless parent.is_a?(Model::ResourceExpression) acceptor.accept(Issues::UNSUPPORTED_OPERATOR_IN_CONTEXT, o, :operator=>'* =>') end rvalue(o.expr) end |
#check_BinaryExpression(o) ⇒ Object
194 195 196 197 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 194 def check_BinaryExpression(o) rvalue(o.left_expr) rvalue(o.right_expr) end |
#check_BlockExpression(o) ⇒ Object
199 200 201 202 203 204 205 206 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 199 def check_BlockExpression(o) o.statements[0..-2].each do |statement| if idem(statement) acceptor.accept(Issues::IDEM_EXPRESSION_NOT_LAST, statement) break # only flag the first end end end |
#check_CallNamedFunctionExpression(o) ⇒ Object
208 209 210 211 212 213 214 215 216 217 218 219 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 208 def check_CallNamedFunctionExpression(o) case o.functor_expr when Puppet::Pops::Model::QualifiedName # ok nil when Puppet::Pops::Model::RenderStringExpression # helpful to point out this easy to make Epp error acceptor.accept(Issues::ILLEGAL_EPP_PARAMETERS, o) else acceptor.accept(Issues::ILLEGAL_EXPRESSION, o.functor_expr, {:feature=>'function name', :container => o}) end end |
#check_CaseExpression(o) ⇒ Object
233 234 235 236 237 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 233 def check_CaseExpression(o) rvalue(o.test) # There should only be one LiteralDefault case option value # TODO: Implement this check end |
#check_CaseOption(o) ⇒ Object
239 240 241 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 239 def check_CaseOption(o) o.values.each { |v| rvalue(v) } end |
#check_CollectExpression(o) ⇒ Object
243 244 245 246 247 248 249 250 251 252 253 254 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 243 def check_CollectExpression(o) unless o.type_expr.is_a? Model::QualifiedReference acceptor.accept(Issues::ILLEGAL_EXPRESSION, o.type_expr, :feature=> 'type name', :container => o) end # If a collect expression tries to collect exported resources and storeconfigs is not on # then it will not work... This was checked in the parser previously. This is a runtime checking # thing as opposed to a language thing. if acceptor.will_accept?(Issues::RT_NO_STORECONFIGS) && o.query.is_a?(Model::ExportedQuery) acceptor.accept(Issues::RT_NO_STORECONFIGS, o) end end |
#check_EppExpression(o) ⇒ Object
221 222 223 224 225 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 221 def check_EppExpression(o) if o.eContainer.is_a?(Puppet::Pops::Model::LambdaExpression) internal_check_no_capture(o.eContainer, o) end end |
#check_Factory(o) ⇒ Object
140 141 142 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 140 def check_Factory(o) check(o.current) end |
#check_HostClassDefinition(o) ⇒ Object
303 304 305 306 307 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 303 def check_HostClassDefinition(o) check_NamedDefinition(o) internal_check_no_capture(o) internal_check_reserved_params(o) end |
#check_IfExpression(o) ⇒ Object
345 346 347 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 345 def check_IfExpression(o) rvalue(o.test) end |
#check_KeyedEntry(o) ⇒ Object
349 350 351 352 353 354 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 349 def check_KeyedEntry(o) rvalue(o.key) rvalue(o.value) # In case there are additional things to forbid than non-rvalues # acceptor.accept(Issues::ILLEGAL_EXPRESSION, o.key, :feature => 'hash key', :container => o.eContainer) end |
#check_LambdaExpression(o) ⇒ Object
356 357 358 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 356 def check_LambdaExpression(o) internal_check_capture_last(o) end |
#check_LiteralList(o) ⇒ Object
360 361 362 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 360 def check_LiteralList(o) o.values.each {|v| rvalue(v) } end |
#check_MethodCallExpression(o) ⇒ Object
227 228 229 230 231 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 227 def check_MethodCallExpression(o) unless o.functor_expr.is_a? Model::QualifiedName acceptor.accept(Issues::ILLEGAL_EXPRESSION, o.functor_expr, :feature => 'function name', :container => o) end end |
#check_NamedAccessExpression(o) ⇒ Object
Only used for function names, grammar should not be able to produce something faulty, but check anyway if model is created programatically (it will fail in transformation to AST for sure).
258 259 260 261 262 263 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 258 def check_NamedAccessExpression(o) name = o.right_expr unless name.is_a? Model::QualifiedName acceptor.accept(Issues::ILLEGAL_EXPRESSION, name, :feature=> 'function name', :container => o.eContainer) end end |
#check_NamedDefinition(o) ⇒ Object
for ‘class’, ‘define’, and function
288 289 290 291 292 293 294 295 296 297 298 299 300 301 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 288 def check_NamedDefinition(o) top(o.eContainer, o) if o.name !~ Puppet::Pops::Patterns::CLASSREF acceptor.accept(Issues::ILLEGAL_DEFINITION_NAME, o, {:name=>o.name}) end if RESERVED_TYPE_NAMES[o.name()] acceptor.accept(Issues::RESERVED_TYPE_NAME, o, {:name => o.name}) end if violator = ends_with_idem(o.body) acceptor.accept(Issues::IDEM_NOT_ALLOWED_LAST, violator, {:container => o}) end end |
#check_NodeDefinition(o) ⇒ Object
364 365 366 367 368 369 370 371 372 373 374 375 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 364 def check_NodeDefinition(o) # Check that hostnames are valid hostnames (or regular expressions) hostname(o.host_matches, o) hostname(o.parent, o, 'parent') unless o.parent.nil? top(o.eContainer, o) if violator = ends_with_idem(o.body) acceptor.accept(Issues::IDEM_NOT_ALLOWED_LAST, violator, {:container => o}) end unless o.parent.nil? acceptor.accept(Issues::ILLEGAL_NODE_INHERITANCE, o.parent) end end |
#check_Object(o) ⇒ Object
—CHECKS
137 138 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 137 def check_Object(o) end |
#check_Parameter(o) ⇒ Object
406 407 408 409 410 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 406 def check_Parameter(o) if o.name =~ /^(?:0x)?[0-9]+$/ acceptor.accept(Issues::ILLEGAL_NUMERIC_PARAMETER, o, :name => o.name) end end |
#check_QualifiedName(o) ⇒ Object
No checking takes place - all expressions using a QualifiedName need to check. This because the rules are slightly different depending on the container (A variable allows a numeric start, but not other names). This means that (if the lexer/parser so chooses) a QualifiedName can be anything when it represents a Bare Word and evaluates to a String.
382 383 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 382 def check_QualifiedName(o) end |
#check_QualifiedReference(o) ⇒ Object
Checks that the value is a valid UpperCaseWord (a CLASSREF), and optionally if it contains a hypen. DOH: QualifiedReferences are created with LOWER CASE NAMES at parse time
387 388 389 390 391 392 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 387 def check_QualifiedReference(o) # Is this a valid qualified name? if o.value !~ Puppet::Pops::Patterns::CLASSREF acceptor.accept(Issues::ILLEGAL_CLASSREF, o, {:name=>o.value}) end end |
#check_QueryExpression(o) ⇒ Object
394 395 396 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 394 def check_QueryExpression(o) query(o.expr) if o.expr # is optional end |
#check_RelationshipExpression(o) ⇒ Object
relationship_side: resource
| resourceref
| collection
| variable
| quotedtext
| selector
| casestatement
| hasharrayaccesses
421 422 423 424 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 421 def check_RelationshipExpression(o) relation(o.left_expr) relation(o.right_expr) end |
#check_ReservedWord(o) ⇒ Object
458 459 460 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 458 def check_ReservedWord(o) acceptor.accept(Issues::RESERVED_WORD, o, :word => o.word) end |
#check_ResourceBody(o) ⇒ Object
433 434 435 436 437 438 439 440 441 442 443 444 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 433 def check_ResourceBody(o) seenUnfolding = false o.operations.each do |ao| if ao.is_a?(Puppet::Pops::Model::AttributesOperation) if seenUnfolding acceptor.accept(Issues::MULTIPLE_ATTRIBUTES_UNFOLD, ao) else seenUnfolding = true end end end end |
#check_ResourceDefaultsExpression(o) ⇒ Object
446 447 448 449 450 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 446 def check_ResourceDefaultsExpression(o) if o.form && o.form != :regular acceptor.accept(Issues::NOT_VIRTUALIZEABLE, o) end end |
#check_ResourceExpression(o) ⇒ Object
426 427 428 429 430 431 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 426 def check_ResourceExpression(o) # The expression for type name cannot be statically checked - this is instead done at runtime # to enable better error message of the result of the expression rather than the static instruction. # (This can be revised as there are static constructs that are illegal, but require updating many # tests that expect the detailed reporting). end |
#check_ResourceOverrideExpression(o) ⇒ Object
452 453 454 455 456 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 452 def check_ResourceOverrideExpression(o) if o.form && o.form != :regular acceptor.accept(Issues::NOT_VIRTUALIZEABLE, o) end end |
#check_ResourceTypeDefinition(o) ⇒ Object
309 310 311 312 313 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 309 def check_ResourceTypeDefinition(o) check_NamedDefinition(o) internal_check_no_capture(o) internal_check_reserved_params(o) end |
#check_SelectorEntry(o) ⇒ Object
466 467 468 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 466 def check_SelectorEntry(o) rvalue(o.matching_expr) end |
#check_SelectorExpression(o) ⇒ Object
462 463 464 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 462 def check_SelectorExpression(o) rvalue(o.left_expr) end |
#check_UnaryExpression(o) ⇒ Object
470 471 472 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 470 def check_UnaryExpression(o) rvalue(o.expr) end |
#check_UnlessExpression(o) ⇒ Object
474 475 476 477 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 474 def check_UnlessExpression(o) rvalue(o.test) # TODO: Unless may not have an else part that is an IfExpression (grammar denies this though) end |
#check_VariableExpression(o) ⇒ Object
Checks that variable is either strictly 0, or a non 0 starting decimal number, or a valid VAR_NAME
480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 480 def check_VariableExpression(o) # The expression must be a qualified name if !o.expr.is_a?(Model::QualifiedName) acceptor.accept(Issues::ILLEGAL_EXPRESSION, o, :feature => 'name', :container => o) else # name must be either a decimal value, or a valid NAME name = o.expr.value if name[0,1] =~ /[0-9]/ unless name =~ Puppet::Pops::Patterns::NUMERIC_VAR_NAME acceptor.accept(Issues::ILLEGAL_NUMERIC_VAR_NAME, o, :name => name) end else unless name =~ Puppet::Pops::Patterns::VAR_NAME acceptor.accept(Issues::ILLEGAL_VAR_NAME, o, :name => name) end end end end |
#ends_with_idem(o) ⇒ Object
Returns the last expression in a block, or the expression, if that expression is idem
91 92 93 94 95 96 97 98 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 91 def ends_with_idem(o) if o.is_a?(Puppet::Pops::Model::BlockExpression) last = o.statements[-1] idem(last) ? last : nil else idem(o) ? o : nil end end |
#hostname(o, semantic, single_feature_name = nil) ⇒ Object
Performs check if this is a vaid hostname expression
50 51 52 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 50 def hostname(o, semantic, single_feature_name = nil) @@hostname_visitor.visit_this_2(self, o, semantic, single_feature_name) end |
#hostname_Array(o, semantic, single_feature_name) ⇒ Object
Transforms Array of host matching expressions into a (Ruby) array of AST::HostName
502 503 504 505 506 507 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 502 def hostname_Array(o, semantic, single_feature_name) if single_feature_name acceptor.accept(Issues::ILLEGAL_EXPRESSION, o, {:feature=>single_feature_name, :container=>semantic}) end o.each {|x| hostname(x, semantic, false) } end |
#hostname_ConcatenatedString(o, semantic, single_feature_name) ⇒ Object
523 524 525 526 527 528 529 530 531 532 533 534 535 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 523 def hostname_ConcatenatedString(o, semantic, single_feature_name) # Puppet 3.1. only accepts a concatenated string without interpolated expressions if the_expr = o.segments.index {|s| s.is_a?(Model::TextExpression) } acceptor.accept(Issues::ILLEGAL_HOSTNAME_INTERPOLATION, o.segments[the_expr].expr) elsif o.segments.size() != 1 # corner case, bad model, concatenation of several plain strings acceptor.accept(Issues::ILLEGAL_HOSTNAME_INTERPOLATION, o) else # corner case, may be ok, but lexer may have replaced with plain string, this is # here if it does not hostname_String(o.segments[0], o.segments[0], false) end end |
#hostname_LiteralDefault(o, semantic, single_feature_name) ⇒ Object
549 550 551 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 549 def hostname_LiteralDefault(o, semantic, single_feature_name) # always ok end |
#hostname_LiteralNumber(o, semantic, single_feature_name) ⇒ Object
545 546 547 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 545 def hostname_LiteralNumber(o, semantic, single_feature_name) # always ok end |
#hostname_LiteralRegularExpression(o, semantic, single_feature_name) ⇒ Object
553 554 555 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 553 def hostname_LiteralRegularExpression(o, semantic, single_feature_name) # always ok end |
#hostname_LiteralValue(o, semantic, single_feature_name) ⇒ Object
519 520 521 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 519 def hostname_LiteralValue(o, semantic, single_feature_name) hostname_String(o.value.to_s, o, single_feature_name) end |
#hostname_Object(o, semantic, single_feature_name) ⇒ Object
557 558 559 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 557 def hostname_Object(o, semantic, single_feature_name) acceptor.accept(Issues::ILLEGAL_EXPRESSION, o, {:feature=> single_feature_name || 'hostname', :container=>semantic}) end |
#hostname_QualifiedName(o, semantic, single_feature_name) ⇒ Object
537 538 539 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 537 def hostname_QualifiedName(o, semantic, single_feature_name) hostname_String(o.value.to_s, o, single_feature_name) end |
#hostname_QualifiedReference(o, semantic, single_feature_name) ⇒ Object
541 542 543 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 541 def hostname_QualifiedReference(o, semantic, single_feature_name) hostname_String(o.value.to_s, o, single_feature_name) end |
#hostname_String(o, semantic, single_feature_name) ⇒ Object
509 510 511 512 513 514 515 516 517 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 509 def hostname_String(o, semantic, single_feature_name) # The 3.x checker only checks for illegal characters - if matching /[^-\w.]/ the name is invalid, # but this allows pathological names like "a..b......c", "----" # TODO: Investigate if more illegal hostnames should be flagged. # if o =~ Puppet::Pops::Patterns::ILLEGAL_HOSTNAME_CHARS acceptor.accept(Issues::ILLEGAL_HOSTNAME_CHARS, semantic, :hostname => o) end end |
#idem(o) ⇒ Boolean
Checks if the expression has side effect (‘idem’ is latin for ‘the same’, here meaning that the evaluation state is known to be unchanged after the expression has been evaluated). The result is not 100% authoritative for negative answers since analysis of function behavior is not possible.
86 87 88 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 86 def idem(o) @@idem_visitor.visit_this_0(self, o) end |
#idem_AccessExpression(o) ⇒ Object
671 672 673 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 671 def idem_AccessExpression(o) true end |
#idem_AssignmentExpression(o) ⇒ Object
684 685 686 687 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 684 def idem_AssignmentExpression(o) # Always side effect false end |
#idem_BinaryExpression(o) ⇒ Object
675 676 677 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 675 def idem_BinaryExpression(o) true end |
#idem_BlockExpression(o) ⇒ Object
707 708 709 710 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 707 def idem_BlockExpression(o) # productive if there is at least one productive expression ! o.statements.any? {|expr| !idem(expr) } end |
#idem_CaseExpression(o) ⇒ Object
Case expression is idem, if test, and all options are idem
735 736 737 738 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 735 def idem_CaseExpression(o) return false if !idem(o.test) ! o..any? {|opt| !idem(opt) } end |
#idem_CaseOption(o) ⇒ Object
An option is idem if values and the then_expression are idem
741 742 743 744 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 741 def idem_CaseOption(o) return false if o.values.any? { |value| !idem(value) } idem(o.then_expr) end |
#idem_ConcatenatedString(o) ⇒ Object
Returns true even though there may be interpolated expressions that have side effect. Report as idem anyway, as it is very bad design to evaluate an interpolated string for its side effect only.
715 716 717 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 715 def idem_ConcatenatedString(o) true end |
#idem_Factory(o) ⇒ Object
667 668 669 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 667 def idem_Factory(o) idem(o.current) end |
#idem_HeredocExpression(o) ⇒ Object
Heredoc is just a string, but may contain interpolated string (which may have side effects). This is still bad design and should be reported as idem.
721 722 723 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 721 def idem_HeredocExpression(o) true end |
#idem_IfExpression(o) ⇒ Object
730 731 732 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 730 def idem_IfExpression(o) [o.test, o.then_expr, o.else_expr].all? {|e| idem(e) } end |
#idem_Literal(o) ⇒ Object
655 656 657 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 655 def idem_Literal(o) true end |
#idem_LiteralHash(o) ⇒ Object
663 664 665 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 663 def idem_LiteralHash(o) true end |
#idem_LiteralList(o) ⇒ Object
659 660 661 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 659 def idem_LiteralList(o) true end |
#idem_NilClass(o) ⇒ Object
651 652 653 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 651 def idem_NilClass(o) true end |
#idem_Nop(o) ⇒ Object
647 648 649 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 647 def idem_Nop(o) true end |
#idem_Object(o) ⇒ Object
–IDEM CHECK
643 644 645 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 643 def idem_Object(o) false end |
#idem_ParenthesizedExpression(o) ⇒ Object
Allow (no-effect parentheses) to be used around a productive expression
695 696 697 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 695 def idem_ParenthesizedExpression(o) idem(o.expr) end |
#idem_RelationshipExpression(o) ⇒ Object
679 680 681 682 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 679 def idem_RelationshipExpression(o) # Always side effect false end |
#idem_RenderExpression(o) ⇒ Object
699 700 701 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 699 def idem_RenderExpression(o) false end |
#idem_RenderStringExpression(o) ⇒ Object
703 704 705 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 703 def idem_RenderStringExpression(o) false end |
#idem_SelectorExpression(o) ⇒ Object
May technically have side effects inside the Selector, but this is bad design - treat as idem
726 727 728 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 726 def idem_SelectorExpression(o) true end |
#idem_UnaryExpression(o) ⇒ Object
Handles UnaryMinusExpression, NotExpression, VariableExpression
690 691 692 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 690 def idem_UnaryExpression(o) true end |
#internal_check_capture_last(o) ⇒ Object
315 316 317 318 319 320 321 322 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 315 def internal_check_capture_last(o) accepted_index = o.parameters.size() -1 o.parameters.each_with_index do |p, index| if p.captures_rest && index != accepted_index acceptor.accept(Issues::CAPTURES_REST_NOT_LAST, p, {:param_name => p.name}) end end end |
#internal_check_no_capture(o, container = o) ⇒ Object
324 325 326 327 328 329 330 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 324 def internal_check_no_capture(o, container = o) o.parameters.each do |p| if p.captures_rest acceptor.accept(Issues::CAPTURES_REST_NOT_SUPPORTED, p, {:container => container, :param_name => p.name}) end end end |
#internal_check_reserved_params(o) ⇒ Object
337 338 339 340 341 342 343 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 337 def internal_check_reserved_params(o) o.parameters.each do |p| if RESERVED_PARAMETERS[p.name] acceptor.accept(Issues::RESERVED_PARAMETER, p, {:container => o, :param_name => p.name}) end end end |
#query(o) ⇒ Object
Performs check if this is valid as a query
55 56 57 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 55 def query(o) @@query_visitor.visit_this_0(self, o) end |
#query_BooleanExpression(o) ⇒ Object
Allows AND, OR, and checks if left/right are allowed in query.
575 576 577 578 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 575 def query_BooleanExpression(o) query o.left_expr query o.right_expr end |
#query_ComparisonExpression(o) ⇒ Object
Puppet AST only allows == and !=
570 571 572 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 570 def query_ComparisonExpression(o) acceptor.accept(Issues::ILLEGAL_QUERY_EXPRESSION, o) unless [:'==', :'!='].include? o.operator end |
#query_LiteralBoolean(o) ⇒ Object
592 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 592 def query_LiteralBoolean(o); end |
#query_LiteralNumber(o) ⇒ Object
588 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 588 def query_LiteralNumber(o); end |
#query_LiteralString(o) ⇒ Object
590 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 590 def query_LiteralString(o); end |
#query_Object(o) ⇒ Object
Anything not explicitly allowed is flagged as error.
564 565 566 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 564 def query_Object(o) acceptor.accept(Issues::ILLEGAL_QUERY_EXPRESSION, o) end |
#query_ParenthesizedExpression(o) ⇒ Object
580 581 582 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 580 def query_ParenthesizedExpression(o) query(o.expr) end |
#query_QualifiedName(o) ⇒ Object
586 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 586 def query_QualifiedName(o); end |
#query_VariableExpression(o) ⇒ Object
584 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 584 def query_VariableExpression(o); end |
#relation(o) ⇒ Object
Performs check if this is valid as a relationship side
60 61 62 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 60 def relation(o) @@relation_visitor.visit_this_0(self, o) end |
#relation_CollectExpression(o) ⇒ Object
402 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 402 def relation_CollectExpression(o); end |
#relation_Object(o) ⇒ Object
398 399 400 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 398 def relation_Object(o) rvalue(o) end |
#relation_RelationshipExpression(o) ⇒ Object
404 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 404 def relation_RelationshipExpression(o); end |
#rvalue(o) ⇒ Object
Performs check if this is valid as a rvalue
65 66 67 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 65 def rvalue(o) @@rvalue_visitor.visit_this_0(self, o) end |
#rvalue_CollectExpression(o) ⇒ Object
601 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 601 def rvalue_CollectExpression(o) ; acceptor.accept(Issues::NOT_RVALUE, o) ; end |
#rvalue_Definition(o) ⇒ Object
603 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 603 def rvalue_Definition(o) ; acceptor.accept(Issues::NOT_RVALUE, o) ; end |
#rvalue_Expression(o) ⇒ Object
By default, all expressions are reported as being rvalues Implement specific rvalue checks for those that are not.
599 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 599 def rvalue_Expression(o); end |
#rvalue_NodeDefinition(o) ⇒ Object
605 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 605 def rvalue_NodeDefinition(o) ; acceptor.accept(Issues::NOT_RVALUE, o) ; end |
#rvalue_UnaryExpression(o) ⇒ Object
607 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 607 def rvalue_UnaryExpression(o) ; rvalue o.expr ; end |
#top(o, definition) ⇒ Object
Performs check if this is valid as a container of a definition (class, define, node)
70 71 72 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 70 def top(o, definition) @@top_visitor.visit_this_1(self, o, definition) end |
#top_BlockExpression(o, definition) ⇒ Object
620 621 622 623 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 620 def top_BlockExpression(o, definition) # ok, if this is a block representing the body of a class, or is top level top o.eContainer, definition end |
#top_HostClassDefinition(o, definition) ⇒ Object
625 626 627 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 625 def top_HostClassDefinition(o, definition) # ok, stop scanning parents end |
#top_LambdaExpression(o, definition) ⇒ Object
A LambdaExpression is a BlockExpression, and this method is needed to prevent the polymorph method for BlockExpression to accept a lambda. A lambda can not iteratively create classes, nodes or defines as the lambda does not have a closure.
637 638 639 640 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 637 def top_LambdaExpression(o, definition) # fail, stop scanning parents acceptor.accept(Issues::NOT_TOP_LEVEL, definition) end |
#top_NilClass(o, definition) ⇒ Object
—TOP CHECK
611 612 613 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 611 def top_NilClass(o, definition) # ok, reached the top, no more parents end |
#top_Object(o, definition) ⇒ Object
615 616 617 618 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 615 def top_Object(o, definition) # fail, reached a container that is not top level acceptor.accept(Issues::NOT_TOP_LEVEL, definition) end |
#top_Program(o, definition) ⇒ Object
629 630 631 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 629 def top_Program(o, definition) # ok end |
#validate(model) ⇒ 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.
37 38 39 40 41 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 37 def validate(model) # tree iterate the model, and call check for each element check(model) model.eAllContents.each {|m| check(m) } end |
#varname_to_s(o) ⇒ Object
Produces string part of something named, or nil if not a QualifiedName or QualifiedReference
750 751 752 753 754 755 756 757 758 759 |
# File 'lib/puppet/pops/validation/checker4_0.rb', line 750 def varname_to_s(o) case o when Model::QualifiedName o.value when Model::QualifiedReference o.value else nil end end |