class Puppet::Pops::Validation::Checker4_0

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

Constants

BAD_MODULE_FILE
FUTURE_RESERVED_WORDS
NO_NAMESPACE
NO_PATH
RESERVED_PARAMETERS
RESERVED_TYPE_NAMES

Attributes

acceptor[R]
migration_checker[R]

Public Class Methods

check_visitor() click to toggle source
   # File lib/puppet/pops/validation/checker4_0.rb
23 def self.check_visitor
24   # Class instance variable rather than Class variable because methods visited
25   # may be overridden in subclass
26   @check_visitor ||= Visitor.new(nil, 'check', 0, 0)
27 end
new(diagnostics_producer) click to toggle source

Initializes the validator with a diagnostics producer. This object must respond to `:will_accept?` and `:accept`.

   # File lib/puppet/pops/validation/checker4_0.rb
32 def initialize(diagnostics_producer)
33   super()
34   @@rvalue_visitor      ||= Visitor.new(nil, "rvalue", 0, 0)
35   @@hostname_visitor    ||= Visitor.new(nil, "hostname", 1, 2)
36   @@assignment_visitor  ||= Visitor.new(nil, "assign", 0, 1)
37   @@query_visitor       ||= Visitor.new(nil, "query", 0, 0)
38   @@relation_visitor    ||= Visitor.new(nil, "relation", 0, 0)
39   @@idem_visitor        ||= Visitor.new(nil, "idem", 0, 0)
40 
41   @check_visitor = self.class.check_visitor
42   @acceptor = diagnostics_producer
43 
44   # Use null migration checker unless given in context
45   @migration_checker = (Puppet.lookup(:migration_checker) { Migration::MigrationChecker.new() })
46 end

Public Instance Methods

assign(o, via_index = false) click to toggle source

Checks the LHS of an assignment (is it assignable?). If args is true, assignment via index is checked.

    # File lib/puppet/pops/validation/checker4_0.rb
123 def assign(o, via_index = false)
124   @@assignment_visitor.visit_this_1(self, o, via_index)
125 end
assign_AccessExpression(o, via_index) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
164 def assign_AccessExpression(o, via_index)
165   # Are indexed assignments allowed at all ? $x[x] = '...'
166   if acceptor.will_accept? Issues::ILLEGAL_INDEXED_ASSIGNMENT
167     acceptor.accept(Issues::ILLEGAL_INDEXED_ASSIGNMENT, o)
168   else
169     # Then the left expression must be assignable-via-index
170     assign(o.left_expr, true)
171   end
172 end
assign_LiteralList(o, via_index) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
174 def assign_LiteralList(o, via_index)
175   o.values.each {|x| assign(x) }
176 end
assign_Object(o, via_index) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
178 def assign_Object(o, via_index)
179   # Can not assign to anything else (differentiate if this is via index or not)
180   # i.e. 10 = 'hello' vs. 10['x'] = 'hello' (the root is reported as being in error in both cases)
181   #
182   acceptor.accept(via_index ? Issues::ILLEGAL_ASSIGNMENT_VIA_INDEX : Issues::ILLEGAL_ASSIGNMENT, o)
183 end
assign_VariableExpression(o, via_index) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
148 def assign_VariableExpression(o, via_index)
149   varname_string = varname_to_s(o.expr)
150   if varname_string =~ Patterns::NUMERIC_VAR_NAME
151     acceptor.accept(Issues::ILLEGAL_NUMERIC_ASSIGNMENT, o, :varname => varname_string)
152   end
153   # Can not assign to something in another namespace (i.e. a '::' in the name is not legal)
154   if acceptor.will_accept? Issues::CROSS_SCOPE_ASSIGNMENT
155     if varname_string =~ /::/
156       acceptor.accept(Issues::CROSS_SCOPE_ASSIGNMENT, o, :name => varname_string)
157     end
158   end
159 
160   # TODO: Could scan for reassignment of the same variable if done earlier in the same container
161   #       Or if assigning to a parameter (more work).
162 end
check(o) click to toggle source

Performs regular validity check

   # File lib/puppet/pops/validation/checker4_0.rb
65 def check(o)
66   @check_visitor.visit_this_0(self, o)
67 end
check_AccessExpression(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
194 def check_AccessExpression(o)
195   # Only min range is checked, all other checks are RT checks as they depend on the resulting type
196   # of the LHS.
197   if o.keys.size < 1
198     acceptor.accept(Issues::MISSING_INDEX, o)
199   end
200 end
check_AssignmentExpression(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
202 def check_AssignmentExpression(o)
203   case o.operator
204   when '='
205     assign(o.left_expr)
206     rvalue(o.right_expr)
207   when '+=', '-='
208     acceptor.accept(Issues::APPENDS_DELETES_NO_LONGER_SUPPORTED, o, {:operator => o.operator})
209   else
210     acceptor.accept(Issues::UNSUPPORTED_OPERATOR, o, {:operator => o.operator})
211   end
212 end
check_AttributeOperation(o) click to toggle source

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)

    # File lib/puppet/pops/validation/checker4_0.rb
222 def check_AttributeOperation(o)
223   if o.operator == '+>'
224     # Append operator use is constrained
225     p = container
226     unless p.is_a?(Model::CollectExpression) || p.is_a?(Model::ResourceOverrideExpression)
227       acceptor.accept(Issues::ILLEGAL_ATTRIBUTE_APPEND, o, {:name=>o.attribute_name, :parent=>p})
228     end
229   end
230   rvalue(o.value_expr)
231 end
check_AttributesOperation(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
233 def check_AttributesOperation(o)
234   # Append operator use is constrained
235   p = container
236   case p
237   when Model::AbstractResource
238   when Model::CollectExpression
239   else
240     # protect against just testing a snippet that has no parent, error message will be a bit strange
241     # but it is not for a real program.
242     parent2 = p.nil? ? o : container(-2)
243     unless parent2.is_a?(Model::AbstractResource)
244       acceptor.accept(Issues::UNSUPPORTED_OPERATOR_IN_CONTEXT, parent2, :operator=>'* =>')
245     end
246   end
247   rvalue(o.expr)
248 end
check_BinaryExpression(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
250 def check_BinaryExpression(o)
251   rvalue(o.left_expr)
252   rvalue(o.right_expr)
253 end
check_BlockExpression(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
264 def check_BlockExpression(o)
265   if resource_without_title?(o)
266     acceptor.accept(Issues::RESOURCE_WITHOUT_TITLE, o, :name => o.statements[0].value)
267   else
268     o.statements[0..-2].each do |statement|
269       if idem(statement)
270         acceptor.accept(Issues::IDEM_EXPRESSION_NOT_LAST, statement)
271         break # only flag the first
272       end
273     end
274   end
275 end
check_CallNamedFunctionExpression(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
277 def check_CallNamedFunctionExpression(o)
278   functor = o.functor_expr
279   if functor.is_a?(Model::QualifiedReference) ||
280     functor.is_a?(Model::AccessExpression) && functor.left_expr.is_a?(Model::QualifiedReference)
281     # ok (a call to a type)
282     return nil
283   end
284   case functor
285   when Model::QualifiedName
286     # ok
287     nil
288   when Model::RenderStringExpression
289     # helpful to point out this easy to make Epp error
290     acceptor.accept(Issues::ILLEGAL_EPP_PARAMETERS, o)
291   else
292     acceptor.accept(Issues::ILLEGAL_EXPRESSION, o.functor_expr, {:feature=>'function name', :container => o})
293   end
294 end
check_CaseExpression(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
318 def check_CaseExpression(o)
319   rvalue(o.test)
320   # There can only be one LiteralDefault case option value
321   found_default = false
322   o.options.each do |option|
323     option.values.each do |value|
324       if value.is_a?(Model::LiteralDefault)
325         # Flag the second default as 'unreachable'
326         acceptor.accept(Issues::DUPLICATE_DEFAULT, value, :container => o) if found_default
327         found_default = true
328       end
329     end
330   end
331 end
check_CaseOption(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
333 def check_CaseOption(o)
334   o.values.each { |v| rvalue(v) }
335 end
check_CollectExpression(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
337 def check_CollectExpression(o)
338   unless o.type_expr.is_a? Model::QualifiedReference
339     acceptor.accept(Issues::ILLEGAL_EXPRESSION, o.type_expr, :feature=> 'type name', :container => o)
340   end
341 end
check_EppExpression(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
296 def check_EppExpression(o)
297   p = container
298   if p.is_a?(Model::LambdaExpression)
299     internal_check_no_capture(p, o)
300     internal_check_parameter_name_uniqueness(p)
301   end
302 end
check_Factory(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
190 def check_Factory(o)
191   check(o.model)
192 end
check_FunctionDefinition(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
459 def check_FunctionDefinition(o)
460   check_NamedDefinition(o)
461   internal_check_return_type(o)
462   internal_check_parameter_name_uniqueness(o)
463 end
check_HeredocExpression(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
304 def check_HeredocExpression(o)
305   # Only syntax check static text in heredoc during validation - dynamic text is validated by the evaluator.
306   expr = o.text_expr
307   if expr.is_a?(Model::LiteralString)
308     assert_external_syntax(nil, expr.value, o.syntax, o.text_expr)
309   end
310 end
check_HostClassDefinition(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
465 def check_HostClassDefinition(o)
466   check_NamedDefinition(o)
467   internal_check_no_capture(o)
468   internal_check_parameter_name_uniqueness(o)
469   internal_check_reserved_params(o)
470   internal_check_no_idem_last(o)
471 end
check_IfExpression(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
678 def check_IfExpression(o)
679   rvalue(o.test)
680 end
check_KeyedEntry(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
682 def check_KeyedEntry(o)
683   rvalue(o.key)
684   rvalue(o.value)
685   # In case there are additional things to forbid than non-rvalues
686   # acceptor.accept(Issues::ILLEGAL_EXPRESSION, o.key, :feature => 'hash key', :container => container)
687 end
check_LambdaExpression(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
689 def check_LambdaExpression(o)
690   internal_check_capture_last(o)
691   internal_check_return_type(o)
692 end
check_LiteralHash(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
705 def check_LiteralHash(o)
706   # the keys of a literal hash may be non-literal expressions. They cannot be checked.
707   unique = Set.new
708   o.entries.each do |entry|
709     catch(:not_literal) do
710       literal_key = literal(entry.key)
711       acceptor.accept(Issues::DUPLICATE_KEY, entry, {:key => literal_key}) if unique.add?(literal_key).nil?
712     end
713   end
714 end
check_LiteralInteger(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
698 def check_LiteralInteger(o)
699   v = o.value
700   if v < MIN_INTEGER || v > MAX_INTEGER
701     acceptor.accept(Issues::NUMERIC_OVERFLOW, o, {:value => v})
702   end
703 end
check_LiteralList(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
694 def check_LiteralList(o)
695   o.values.each {|v| rvalue(v) }
696 end
check_MethodCallExpression(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
312 def check_MethodCallExpression(o)
313   unless o.functor_expr.is_a? Model::QualifiedName
314     acceptor.accept(Issues::ILLEGAL_EXPRESSION, o.functor_expr, :feature => 'function name', :container => o)
315   end
316 end
check_NamedAccessExpression(o) click to toggle source

Only used for function names, grammar should not be able to produce something faulty, but check anyway if model is created programmatically (it will fail in transformation to AST for sure).

    # File lib/puppet/pops/validation/checker4_0.rb
345 def check_NamedAccessExpression(o)
346   name = o.right_expr
347   unless name.is_a? Model::QualifiedName
348     acceptor.accept(Issues::ILLEGAL_EXPRESSION, name, :feature=> 'function name', :container => container)
349   end
350 end
check_NamedDefinition(o) click to toggle source

for 'class', 'define', and function

    # File lib/puppet/pops/validation/checker4_0.rb
388 def check_NamedDefinition(o)
389   top(o)
390   if o.name !~ Patterns::CLASSREF_DECL
391     acceptor.accept(Issues::ILLEGAL_DEFINITION_NAME, o, {:name=>o.name})
392   end
393 
394   internal_check_file_namespace(o)
395   internal_check_reserved_type_name(o, o.name)
396   internal_check_future_reserved_word(o, o.name)
397 end
check_NodeDefinition(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
716 def check_NodeDefinition(o)
717   # Check that hostnames are valid hostnames (or regular expressions)
718   hostname(o.host_matches, o)
719   top(o)
720   violator = ends_with_idem(o.body)
721   if violator
722     acceptor.accept(Issues::IDEM_NOT_ALLOWED_LAST, violator, {:container => o}) unless resource_without_title?(violator)
723   end
724   unless o.parent.nil?
725     acceptor.accept(Issues::ILLEGAL_NODE_INHERITANCE, o.parent)
726   end
727 end
check_Object(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
187 def check_Object(o)
188 end
check_Parameter(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
758 def check_Parameter(o)
759   if o.name =~ /^(?:0x)?[0-9]+$/
760     acceptor.accept(Issues::ILLEGAL_NUMERIC_PARAMETER, o, :name => o.name)
761   end
762 
763   unless o.name =~ Patterns::PARAM_NAME
764     acceptor.accept(Issues::ILLEGAL_PARAM_NAME, o, :name => o.name)
765   end
766   return unless o.value
767 
768   internal_check_illegal_assignment(o.value)
769 end
check_QualifiedName(o) click to toggle source

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.

    # File lib/puppet/pops/validation/checker4_0.rb
734 def check_QualifiedName(o)
735 end
check_QualifiedReference(o) click to toggle source

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

    # File lib/puppet/pops/validation/checker4_0.rb
739 def check_QualifiedReference(o)
740   # Is this a valid qualified name?
741   if o.cased_value !~ Patterns::CLASSREF_EXT
742     acceptor.accept(Issues::ILLEGAL_CLASSREF, o, {:name=>o.cased_value})
743   end
744 end
check_QueryExpression(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
746 def check_QueryExpression(o)
747   query(o.expr) if o.expr  # is optional
748 end
check_RelationshipExpression(o) click to toggle source

relationship_side: resource

| resourceref
| collection
| variable
| quotedtext
| selector
| casestatement
| hasharrayaccesses
    # File lib/puppet/pops/validation/checker4_0.rb
790 def check_RelationshipExpression(o)
791   relation(o.left_expr)
792   relation(o.right_expr)
793 end
check_ReservedWord(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
831 def check_ReservedWord(o)
832   if o.future
833     acceptor.accept(Issues::FUTURE_RESERVED_WORD, o, :word => o.word)
834   else
835     acceptor.accept(Issues::RESERVED_WORD, o, :word => o.word)
836   end
837 end
check_ResourceBody(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
806 def check_ResourceBody(o)
807   seenUnfolding = false
808   o.operations.each do |ao|
809     if ao.is_a?(Model::AttributesOperation)
810       if seenUnfolding
811         acceptor.accept(Issues::MULTIPLE_ATTRIBUTES_UNFOLD, ao)
812       else
813         seenUnfolding = true
814       end
815     end
816   end
817 end
check_ResourceDefaultsExpression(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
819 def check_ResourceDefaultsExpression(o)
820   if o.form != 'regular'
821     acceptor.accept(Issues::NOT_VIRTUALIZEABLE, o)
822   end
823 end
check_ResourceExpression(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
795 def check_ResourceExpression(o)
796   # The expression for type name cannot be statically checked - this is instead done at runtime
797   # to enable better error message of the result of the expression rather than the static instruction.
798   # (This can be revised as there are static constructs that are illegal, but require updating many
799   # tests that expect the detailed reporting).
800   type_name_expr = o.type_name
801   if o.form && o.form != 'regular' && type_name_expr.is_a?(Model::QualifiedName) && type_name_expr.value == 'class'
802     acceptor.accept(Issues::CLASS_NOT_VIRTUALIZABLE, o)
803   end
804 end
check_ResourceOverrideExpression(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
825 def check_ResourceOverrideExpression(o)
826   if o.form != 'regular'
827     acceptor.accept(Issues::NOT_VIRTUALIZEABLE, o)
828   end
829 end
check_ResourceTypeDefinition(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
473 def check_ResourceTypeDefinition(o)
474   check_NamedDefinition(o)
475   internal_check_no_capture(o)
476   internal_check_parameter_name_uniqueness(o)
477   internal_check_reserved_params(o)
478   internal_check_no_idem_last(o)
479 end
check_SelectorEntry(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
849 def check_SelectorEntry(o)
850   rvalue(o.matching_expr)
851 end
check_SelectorExpression(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
839 def check_SelectorExpression(o)
840   rvalue(o.left_expr)
841   # There can only be one LiteralDefault case option value
842   defaults = o.selectors.select {|v| v.matching_expr.is_a?(Model::LiteralDefault) }
843   unless defaults.size <= 1
844     # Flag the second default as 'unreachable'
845     acceptor.accept(Issues::DUPLICATE_DEFAULT, defaults[1].matching_expr, :container => o)
846   end
847 end
check_TypeAlias(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
399 def check_TypeAlias(o)
400   top(o)
401   if o.name !~ Patterns::CLASSREF_EXT_DECL
402     acceptor.accept(Issues::ILLEGAL_DEFINITION_NAME, o, {:name=>o.name})
403   end
404   internal_check_reserved_type_name(o, o.name)
405   internal_check_type_ref(o, o.type_expr)
406 end
check_TypeDefinition(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
452 def check_TypeDefinition(o)
453   top(o)
454   internal_check_reserved_type_name(o, o.name)
455   # TODO: Check TypeDefinition body. For now, just error out
456   acceptor.accept(Issues::UNSUPPORTED_EXPRESSION, o)
457 end
check_TypeMapping(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
408 def check_TypeMapping(o)
409   top(o)
410   lhs = o.type_expr
411   lhs_type = 0 # Not Runtime
412   if lhs.is_a?(Model::AccessExpression)
413     left = lhs.left_expr
414     if left.is_a?(Model::QualifiedReference) && left.cased_value == 'Runtime'
415       lhs_type = 1 # Runtime
416       keys = lhs.keys
417 
418       # Must be a literal string or pattern replacement
419       lhs_type = 2 if keys.size == 2 && pattern_with_replacement?(keys[1])
420     end
421   end
422 
423   if lhs_type == 0
424     # This is not a TypeMapping. Something other than Runtime[] on LHS
425     acceptor.accept(Issues::UNSUPPORTED_EXPRESSION, o)
426   else
427     rhs = o.mapping_expr
428     if pattern_with_replacement?(rhs)
429       acceptor.accept(Issues::ILLEGAL_SINGLE_TYPE_MAPPING, o) if lhs_type == 1
430     elsif type_ref?(rhs)
431       acceptor.accept(Issues::ILLEGAL_REGEXP_TYPE_MAPPING, o) if lhs_type == 2
432     else
433       acceptor.accept(lhs_type == 1 ? Issues::ILLEGAL_SINGLE_TYPE_MAPPING : Issues::ILLEGAL_REGEXP_TYPE_MAPPING, o)
434     end
435   end
436 end
check_UnaryExpression(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
853 def check_UnaryExpression(o)
854   rvalue(o.expr)
855 end
check_UnlessExpression(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
857 def check_UnlessExpression(o)
858   rvalue(o.test)
859   # TODO: Unless may not have an else part that is an IfExpression (grammar denies this though)
860 end
check_VariableExpression(o) click to toggle source

Checks that variable is either strictly 0, or a non 0 starting decimal number, or a valid VAR_NAME

    # File lib/puppet/pops/validation/checker4_0.rb
863 def check_VariableExpression(o)
864   # The expression must be a qualified name or an integer
865   name_expr = o.expr
866   return if name_expr.is_a?(Model::LiteralInteger)
867   if !name_expr.is_a?(Model::QualifiedName)
868     acceptor.accept(Issues::ILLEGAL_EXPRESSION, o, :feature => 'name', :container => o)
869   else
870     # name must be either a decimal string value, or a valid NAME
871     name = o.expr.value
872     if name[0,1] =~ /[0-9]/
873       unless name =~ Patterns::NUMERIC_VAR_NAME
874         acceptor.accept(Issues::ILLEGAL_NUMERIC_VAR_NAME, o, :name => name)
875       end
876     else
877       unless name =~ Patterns::VAR_NAME
878         acceptor.accept(Issues::ILLEGAL_VAR_NAME, o, :name => name)
879       end
880     end
881   end
882 end
container(index = -1) click to toggle source
   # File lib/puppet/pops/validation/checker4_0.rb
60 def container(index = -1)
61   @path[index]
62 end
dir_to_names(relative_path) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
632 def dir_to_names(relative_path)
633   # Downcasing here because check is case-insensitive
634   path_components = relative_path.to_s.downcase.split(File::SEPARATOR)
635 
636   # Example definition dir: manifests in this path:
637   # <module name>/manifests/<module subdir>/<classfile>.pp
638   dir = path_components[1]
639 
640   # How can we get this result?
641   # If it is not an initial manifest, it must come from a module,
642   # and from the manifests dir there.  This may never get used...
643   return BAD_MODULE_FILE unless dir == 'manifests' || dir == 'functions' || dir == 'types' || dir == 'plans'
644 
645   names = path_components[2 .. -2] # Directories inside module
646   names.unshift(path_components[0]) # Name of the module itself
647 
648   # Do not include name of module init file at top level of module
649   # e.g. <module name>/manifests/init.pp
650   filename = path_components[-1]
651   if !(path_components.length == 3 && filename == 'init.pp')
652     names.push(filename[0 .. -4]) # Remove .pp from filename
653   end
654 
655   names
656 end
ends_with_idem(o) click to toggle source

Returns the last expression in a block, or the expression, if that expression is idem

    # File lib/puppet/pops/validation/checker4_0.rb
137 def ends_with_idem(o)
138   if o.is_a?(Model::BlockExpression)
139     last = o.statements[-1]
140     idem(last) ? last : nil
141   else
142     idem(o) ? o : nil
143   end
144 end
get_module_relative_path(file_path, modulepath_directories) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
617 def get_module_relative_path(file_path, modulepath_directories)
618   clean_file = file_path.cleanpath
619   parent_path = modulepath_directories.find { |path_dir| is_parent_dir_of(path_dir, clean_file) }
620   return NO_PATH if parent_path.nil?
621 
622   file_path.relative_path_from(Pathname.new(parent_path))
623 end
hostname(o, semantic) click to toggle source

Performs check if this is a vaid hostname expression @param single_feature_name [String, nil] the name of a single valued hostname feature of the value's container. e.g. 'parent'

   # File lib/puppet/pops/validation/checker4_0.rb
71 def hostname(o, semantic)
72   @@hostname_visitor.visit_this_1(self, o, semantic)
73 end
hostname_Array(o, semantic) click to toggle source

Transforms Array of host matching expressions into a (Ruby) array of AST::HostName

    # File lib/puppet/pops/validation/checker4_0.rb
887 def hostname_Array(o, semantic)
888   o.each {|x| hostname(x, semantic) }
889 end
hostname_ConcatenatedString(o, semantic) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
905 def hostname_ConcatenatedString(o, semantic)
906   # Puppet 3.1. only accepts a concatenated string without interpolated expressions
907   the_expr = o.segments.index {|s| s.is_a?(Model::TextExpression) }
908   if the_expr
909     acceptor.accept(Issues::ILLEGAL_HOSTNAME_INTERPOLATION, o.segments[the_expr].expr)
910   elsif o.segments.size() != 1
911     # corner case, bad model, concatenation of several plain strings
912     acceptor.accept(Issues::ILLEGAL_HOSTNAME_INTERPOLATION, o)
913   else
914     # corner case, may be ok, but lexer may have replaced with plain string, this is
915     # here if it does not
916     hostname_String(o.segments[0], o.segments[0])
917   end
918 end
hostname_LiteralDefault(o, semantic) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
932 def hostname_LiteralDefault(o, semantic)
933   # always ok
934 end
hostname_LiteralNumber(o, semantic) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
928 def hostname_LiteralNumber(o, semantic)
929   # always ok
930 end
hostname_LiteralRegularExpression(o, semantic) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
936 def hostname_LiteralRegularExpression(o, semantic)
937   # always ok
938 end
hostname_LiteralValue(o, semantic) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
901 def hostname_LiteralValue(o, semantic)
902   hostname_String(o.value.to_s, o)
903 end
hostname_Object(o, semantic) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
940 def hostname_Object(o, semantic)
941   acceptor.accept(Issues::ILLEGAL_EXPRESSION, o, {:feature => 'hostname', :container => semantic})
942 end
hostname_QualifiedName(o, semantic) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
920 def hostname_QualifiedName(o, semantic)
921   hostname_String(o.value.to_s, o)
922 end
hostname_QualifiedReference(o, semantic) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
924 def hostname_QualifiedReference(o, semantic)
925   hostname_String(o.value.to_s, o)
926 end
hostname_String(o, semantic) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
891 def hostname_String(o, semantic)
892   # The 3.x checker only checks for illegal characters - if matching /[^-\w.]/ the name is invalid,
893   # but this allows pathological names like "a..b......c", "----"
894   # TODO: Investigate if more illegal hostnames should be flagged.
895   #
896   if o =~ Patterns::ILLEGAL_HOSTNAME_CHARS
897     acceptor.accept(Issues::ILLEGAL_HOSTNAME_CHARS, semantic, :hostname => o)
898   end
899 end
idem(o) click to toggle source

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. @return [Boolean] true if expression is known to have no effect on evaluation state

    # File lib/puppet/pops/validation/checker4_0.rb
132 def idem(o)
133   @@idem_visitor.visit_this_0(self, o)
134 end
idem_AccessExpression(o) click to toggle source
     # File lib/puppet/pops/validation/checker4_0.rb
1029 def idem_AccessExpression(o)
1030   true
1031 end
idem_ApplyExpression(o) click to toggle source

An apply expression exists purely for the side effect of applying a catalog somewhere, so it always has side effects

     # File lib/puppet/pops/validation/checker4_0.rb
1094 def idem_ApplyExpression(o)
1095   false
1096 end
idem_AssignmentExpression(o) click to toggle source
     # File lib/puppet/pops/validation/checker4_0.rb
1046 def idem_AssignmentExpression(o)
1047   # Always side effect
1048   false
1049 end
idem_BinaryExpression(o) click to toggle source
     # File lib/puppet/pops/validation/checker4_0.rb
1033 def idem_BinaryExpression(o)
1034   true
1035 end
idem_BlockExpression(o) click to toggle source
     # File lib/puppet/pops/validation/checker4_0.rb
1069 def idem_BlockExpression(o)
1070   # productive if there is at least one productive expression
1071   ! o.statements.any? {|expr| !idem(expr) }
1072 end
idem_CaseExpression(o) click to toggle source

Case expression is idem, if test, and all options are idem

     # File lib/puppet/pops/validation/checker4_0.rb
1103 def idem_CaseExpression(o)
1104   return false if !idem(o.test)
1105   ! o.options.any? {|opt| !idem(opt) }
1106 end
idem_CaseOption(o) click to toggle source

An option is idem if values and the then_expression are idem

     # File lib/puppet/pops/validation/checker4_0.rb
1109 def idem_CaseOption(o)
1110   return false if o.values.any? { |value| !idem(value) }
1111   idem(o.then_expr)
1112 end
idem_ConcatenatedString(o) click to toggle source

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.

     # File lib/puppet/pops/validation/checker4_0.rb
1077 def idem_ConcatenatedString(o)
1078   true
1079 end
idem_Factory(o) click to toggle source
     # File lib/puppet/pops/validation/checker4_0.rb
1025 def idem_Factory(o)
1026   idem(o.model)
1027 end
idem_HeredocExpression(o) click to toggle source

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.

     # File lib/puppet/pops/validation/checker4_0.rb
1083 def idem_HeredocExpression(o)
1084   true
1085 end
idem_IfExpression(o) click to toggle source
     # File lib/puppet/pops/validation/checker4_0.rb
1098 def idem_IfExpression(o)
1099   [o.test, o.then_expr, o.else_expr].all? {|e| idem(e) }
1100 end
idem_Literal(o) click to toggle source
     # File lib/puppet/pops/validation/checker4_0.rb
1013 def idem_Literal(o)
1014   true
1015 end
idem_LiteralHash(o) click to toggle source
     # File lib/puppet/pops/validation/checker4_0.rb
1021 def idem_LiteralHash(o)
1022   true
1023 end
idem_LiteralList(o) click to toggle source
     # File lib/puppet/pops/validation/checker4_0.rb
1017 def idem_LiteralList(o)
1018   true
1019 end
idem_MatchExpression(o) click to toggle source
     # File lib/puppet/pops/validation/checker4_0.rb
1037 def idem_MatchExpression(o)
1038   false # can have side effect of setting $n match variables
1039 end
idem_NilClass(o) click to toggle source
     # File lib/puppet/pops/validation/checker4_0.rb
1009 def idem_NilClass(o)
1010   true
1011 end
idem_Nop(o) click to toggle source
     # File lib/puppet/pops/validation/checker4_0.rb
1005 def idem_Nop(o)
1006   true
1007 end
idem_Object(o) click to toggle source
     # File lib/puppet/pops/validation/checker4_0.rb
1001 def idem_Object(o)
1002   false
1003 end
idem_ParenthesizedExpression(o) click to toggle source

Allow (no-effect parentheses) to be used around a productive expression

     # File lib/puppet/pops/validation/checker4_0.rb
1057 def idem_ParenthesizedExpression(o)
1058   idem(o.expr)
1059 end
idem_RelationshipExpression(o) click to toggle source
     # File lib/puppet/pops/validation/checker4_0.rb
1041 def idem_RelationshipExpression(o)
1042   # Always side effect
1043   false
1044 end
idem_RenderExpression(o) click to toggle source
     # File lib/puppet/pops/validation/checker4_0.rb
1061 def idem_RenderExpression(o)
1062   false
1063 end
idem_RenderStringExpression(o) click to toggle source
     # File lib/puppet/pops/validation/checker4_0.rb
1065 def idem_RenderStringExpression(o)
1066   false
1067 end
idem_SelectorExpression(o) click to toggle source

May technically have side effects inside the Selector, but this is bad design - treat as idem

     # File lib/puppet/pops/validation/checker4_0.rb
1088 def idem_SelectorExpression(o)
1089   true
1090 end
idem_UnaryExpression(o) click to toggle source

Handles UnaryMinusExpression, NotExpression, VariableExpression

     # File lib/puppet/pops/validation/checker4_0.rb
1052 def idem_UnaryExpression(o)
1053   true
1054 end
initial_manifest?(path, manifest_setting) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
609 def initial_manifest?(path, manifest_setting)
610   return false if manifest_setting.nil? || manifest_setting == :no_manifest
611 
612   string_path = path.to_s
613 
614   string_path == manifest_setting || string_path.start_with?(manifest_setting)
615 end
internal_check_capture_last(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
502 def internal_check_capture_last(o)
503   accepted_index = o.parameters.size() -1
504   o.parameters.each_with_index do |p, index|
505     if p.captures_rest && index != accepted_index
506       acceptor.accept(Issues::CAPTURES_REST_NOT_LAST, p, {:param_name => p.name})
507     end
508   end
509 end
internal_check_file_namespace(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
535 def internal_check_file_namespace(o)
536   file = o.locator.file
537   return if file.nil? || file == '' #e.g. puppet apply -e '...'
538 
539   file_namespace = namespace_for_file(file)
540   return if file_namespace == NO_NAMESPACE
541 
542   # Downcasing here because check is case-insensitive
543   if file_namespace == BAD_MODULE_FILE || !o.name.downcase.start_with?(file_namespace)
544     acceptor.accept(Issues::ILLEGAL_DEFINITION_LOCATION, o, {:name => o.name, :file => file})
545   end
546 end
internal_check_future_reserved_word(o, name) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
525 def internal_check_future_reserved_word(o, name)
526   if FUTURE_RESERVED_WORDS[name]
527     acceptor.accept(Issues::FUTURE_RESERVED_WORD, o, {:word => name})
528   end
529 end
internal_check_illegal_assignment(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
771 def internal_check_illegal_assignment(o)
772   if o.is_a?(Model::AssignmentExpression)
773     acceptor.accept(Issues::ILLEGAL_ASSIGNMENT_CONTEXT, o)
774   else
775     # recursively check all contents unless it's a lambda expression. A lambda may contain
776     # local assignments
777     o._pcore_contents {|model| internal_check_illegal_assignment(model) } unless o.is_a?(Model::LambdaExpression)
778   end
779 end
internal_check_no_capture(o, container = o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
511 def internal_check_no_capture(o, container = o)
512   o.parameters.each do |p|
513     if p.captures_rest
514       acceptor.accept(Issues::CAPTURES_REST_NOT_SUPPORTED, p, {:container => container, :param_name => p.name})
515     end
516   end
517 end
internal_check_no_idem_last(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
495 def internal_check_no_idem_last(o)
496   violator = ends_with_idem(o.body)
497   if violator
498     acceptor.accept(Issues::IDEM_NOT_ALLOWED_LAST, violator, {:container => o}) unless resource_without_title?(violator)
499   end
500 end
internal_check_parameter_name_uniqueness(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
671 def internal_check_parameter_name_uniqueness(o)
672   unique = Set.new
673   o.parameters.each do |p|
674     acceptor.accept(Issues::DUPLICATE_PARAMETER, p, {:param_name => p.name}) unless unique.add?(p.name)
675   end
676 end
internal_check_reserved_params(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
663 def internal_check_reserved_params(o)
664   o.parameters.each do |p|
665     if RESERVED_PARAMETERS[p.name]
666       acceptor.accept(Issues::RESERVED_PARAMETER, p, {:container => o, :param_name => p.name})
667     end
668   end
669 end
internal_check_reserved_type_name(o, name) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
519 def internal_check_reserved_type_name(o, name)
520   if RESERVED_TYPE_NAMES[name]
521     acceptor.accept(Issues::RESERVED_TYPE_NAME, o, {:name => name})
522   end
523 end
internal_check_return_type(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
481 def internal_check_return_type(o)
482   r = o.return_type
483   internal_check_type_ref(o, r) unless r.nil?
484 end
internal_check_top_construct_in_module(prog) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
548 def internal_check_top_construct_in_module(prog)
549   return unless prog.is_a?(Model::Program) && !prog.body.nil?
550 
551   #Check that this is a module autoloaded file
552   file = prog.locator.file
553   return if file.nil?
554   return if namespace_for_file(file) == NO_NAMESPACE
555 
556   body = prog.body
557   return if prog.body.is_a?(Model::Nop) #Ignore empty or comment-only files
558 
559   if(body.is_a?(Model::BlockExpression))
560     body.statements.each { |s| acceptor.accept(Issues::ILLEGAL_TOP_CONSTRUCT_LOCATION, s) unless valid_top_construct?(s) }
561   else
562     acceptor.accept(Issues::ILLEGAL_TOP_CONSTRUCT_LOCATION, body) unless valid_top_construct?(body)
563   end
564 end
internal_check_type_ref(o, r) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
486 def internal_check_type_ref(o, r)
487   n = r.is_a?(Model::AccessExpression) ? r.left_expr : r
488   if n.is_a? Model::QualifiedReference
489     internal_check_future_reserved_word(r, n.value)
490   else
491     acceptor.accept(Issues::ILLEGAL_EXPRESSION, r, :feature => 'a type reference', :container => o)
492   end
493 end
is_parent_dir_of(parent_dir, child_dir) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
625 def is_parent_dir_of(parent_dir, child_dir)
626   parent_dir_path = Pathname.new(parent_dir)
627   clean_parent = parent_dir_path.cleanpath.to_s + File::SEPARATOR
628 
629   return child_dir.to_s.start_with?(clean_parent)
630 end
namespace_for_file(file) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
581 def namespace_for_file(file)
582   env = Puppet.lookup(:current_environment)
583   return NO_NAMESPACE if env.nil?
584 
585   adapter = Puppet::Util::FileNamespaceAdapter.adapt(env)
586 
587   file_namespace = adapter.file_to_namespace[file]
588   return file_namespace unless file_namespace.nil? # No cache entry, so we do the calculation
589 
590   path = Pathname.new(file)
591 
592   return adapter.file_to_namespace[file] = NO_NAMESPACE if path.extname != ".pp"
593 
594   path = path.expand_path
595 
596   return adapter.file_to_namespace[file] = NO_NAMESPACE if initial_manifest?(path, env.manifest)
597 
598   #All auto-loaded files from modules come from a module search path dir
599   relative_path = get_module_relative_path(path, env.full_modulepath)
600 
601   return adapter.file_to_namespace[file] = NO_NAMESPACE if relative_path == NO_PATH
602 
603   #If a file comes from a module, but isn't in the right place, always error
604   names = dir_to_names(relative_path)
605 
606   return adapter.file_to_namespace[file] = (names == BAD_MODULE_FILE ? BAD_MODULE_FILE : names.join("::").freeze)
607 end
pattern_with_replacement?(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
438 def pattern_with_replacement?(o)
439   if o.is_a?(Model::LiteralList)
440     v = o.values
441     v.size == 2 && v[0].is_a?(Model::LiteralRegularExpression) && v[1].is_a?(Model::LiteralString)
442   else
443     false
444   end
445 end
query(o) click to toggle source

Performs check if this is valid as a query

   # File lib/puppet/pops/validation/checker4_0.rb
76 def query(o)
77   @@query_visitor.visit_this_0(self, o)
78 end
query_BooleanExpression(o) click to toggle source

Allows AND, OR, and checks if left/right are allowed in query.

    # File lib/puppet/pops/validation/checker4_0.rb
958 def query_BooleanExpression(o)
959   query o.left_expr
960   query o.right_expr
961 end
query_ComparisonExpression(o) click to toggle source

Puppet AST only allows == and !=

    # File lib/puppet/pops/validation/checker4_0.rb
953 def query_ComparisonExpression(o)
954   acceptor.accept(Issues::ILLEGAL_QUERY_EXPRESSION, o) unless ['==', '!='].include? o.operator
955 end
query_LiteralBoolean(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
975 def query_LiteralBoolean(o); end
query_LiteralNumber(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
971 def query_LiteralNumber(o); end
query_LiteralString(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
973 def query_LiteralString(o); end
query_Object(o) click to toggle source

Anything not explicitly allowed is flagged as error.

    # File lib/puppet/pops/validation/checker4_0.rb
947 def query_Object(o)
948   acceptor.accept(Issues::ILLEGAL_QUERY_EXPRESSION, o)
949 end
query_ParenthesizedExpression(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
963 def query_ParenthesizedExpression(o)
964   query(o.expr)
965 end
query_QualifiedName(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
969 def query_QualifiedName(o); end
query_VariableExpression(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
967 def query_VariableExpression(o); end
relation(o) click to toggle source

Performs check if this is valid as a relationship side

   # File lib/puppet/pops/validation/checker4_0.rb
81 def relation(o)
82   @@relation_visitor.visit_this_0(self, o)
83 end
relation_CollectExpression(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
754 def relation_CollectExpression(o); end
relation_Object(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
750 def relation_Object(o)
751   rvalue(o)
752 end
relation_RelationshipExpression(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
756 def relation_RelationshipExpression(o); end
resource_without_title?(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
255 def resource_without_title?(o)
256   if o.instance_of?(Model::BlockExpression)
257     statements = o.statements
258     statements.length == 2 && statements[0].instance_of?(Model::QualifiedName) && statements[1].instance_of?(Model::LiteralHash)
259   else
260     false
261   end
262 end
rvalue(o) click to toggle source

Performs check if this is valid as a rvalue

   # File lib/puppet/pops/validation/checker4_0.rb
86 def rvalue(o)
87   @@rvalue_visitor.visit_this_0(self, o)
88 end
rvalue_CollectExpression(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
984 def rvalue_CollectExpression(o)
985   acceptor.accept(Issues::NOT_RVALUE, o)
986 end
rvalue_Definition(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
988 def rvalue_Definition(o)
989   acceptor.accept(Issues::NOT_RVALUE, o)
990 end
rvalue_Expression(o) click to toggle source

By default, all expressions are reported as being rvalues Implement specific rvalue checks for those that are not.

    # File lib/puppet/pops/validation/checker4_0.rb
982 def rvalue_Expression(o); end
rvalue_NodeDefinition(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
992 def rvalue_NodeDefinition(o)
993   acceptor.accept(Issues::NOT_RVALUE, o)
994 end
rvalue_UnaryExpression(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
996 def rvalue_UnaryExpression(o)
997   rvalue o.expr
998 end
top(definition, idx = -1) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
 92 def top(definition, idx = -1)
 93   o = container(idx)
 94   idx -= 1
 95   case o
 96   when NilClass, Model::ApplyExpression, Model::HostClassDefinition, Model::Program
 97     # ok, stop scanning parents
 98   when Model::BlockExpression
 99     c = container(idx)
100     if !c.is_a?(Model::Program) &&
101       (definition.is_a?(Model::FunctionDefinition) || definition.is_a?(Model::TypeAlias) || definition.is_a?(Model::TypeDefinition))
102 
103       # not ok. These can never be nested in a block
104       acceptor.accept(Issues::NOT_ABSOLUTE_TOP_LEVEL, definition)
105     else
106       # ok, if this is a block representing the body of a class, or is top level
107       top(definition, idx)
108     end
109   when Model::LambdaExpression
110     # A LambdaExpression is a BlockExpression, and this check is needed to prevent the polymorph method for BlockExpression
111     # to accept a lambda.
112     # A lambda can not iteratively create classes, nodes or defines as the lambda does not have a closure.
113     acceptor.accept(Issues::NOT_TOP_LEVEL, definition)
114   else
115     # fail, reached a container that is not top level
116     acceptor.accept(Issues::NOT_TOP_LEVEL, definition)
117   end
118 end
type_ref?(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
447 def type_ref?(o)
448   o = o.left_expr if o.is_a?(Model::AccessExpression)
449   o.is_a?(Model::QualifiedReference)
450 end
valid_top_construct?(o) click to toggle source
    # File lib/puppet/pops/validation/checker4_0.rb
566 def valid_top_construct?(o)
567   o.is_a?(Model::Definition) && !o.is_a?(Model::NodeDefinition)
568 end
validate(model) click to toggle source

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.

   # File lib/puppet/pops/validation/checker4_0.rb
52 def validate(model)
53   # tree iterate the model, and call check for each element
54   @path = []
55   check(model)
56   internal_check_top_construct_in_module(model)
57   model._pcore_all_contents(@path) { |element| check(element) }
58 end
varname_to_s(o) click to toggle source

Produces string part of something named, or nil if not a QualifiedName or QualifiedReference

     # File lib/puppet/pops/validation/checker4_0.rb
1118 def varname_to_s(o)
1119   case o
1120   when Model::QualifiedName
1121     o.value
1122   when Model::QualifiedReference
1123     o.value
1124   else
1125     nil
1126   end
1127 end