class Puppet::Pops::Evaluator::AccessOperator

AccessOperator handles operator [] This operator is part of evaluation.

Constants

NS

Attributes

semantic[R]

Public Class Methods

new(access_expression) click to toggle source

Initialize with AccessExpression to enable reporting issues @param access_expression [Model::AccessExpression] the semantic object being evaluated @return [void]

   # File lib/puppet/pops/evaluator/access_operator.rb
19 def initialize(access_expression)
20   @@access_visitor ||= Visitor.new(self, "access", 2, nil)
21   @semantic = access_expression
22 end

Public Instance Methods

access(o, scope, *keys) click to toggle source
   # File lib/puppet/pops/evaluator/access_operator.rb
24 def access(o, scope, *keys)
25   @@access_visitor.visit_this_2(self, o, scope, keys)
26 end

Protected Instance Methods

access_Array(o, scope, keys) click to toggle source

Evaluates <ary>[] with 1 or 2 arguments. One argument is an index lookup, two arguments is a slice from/to.

    # File lib/puppet/pops/evaluator/access_operator.rb
 94 def access_Array(o, scope, keys)
 95   keys.flatten!
 96   case keys.size
 97   when 0
 98     fail(Issues::BAD_ARRAY_SLICE_ARITY, @semantic.left_expr, {:actual => keys.size})
 99   when 1
100     key = coerce_numeric(keys[0], @semantic.keys[0], scope)
101     unless key.is_a?(Integer)
102       bad_access_key_type(o, 0, key, Integer)
103     end
104     o[key]
105   when 2
106     # A slice [from, to] with support for -1 to mean start, or end respectively.
107     k1 = coerce_numeric(keys[0], @semantic.keys[0], scope)
108     k2 = coerce_numeric(keys[1], @semantic.keys[1], scope)
109 
110     [k1, k2].each_with_index { |k,i| bad_access_key_type(o, i, k, Integer) unless k.is_a?(Integer) }
111 
112     # Help confused Ruby do the right thing (it truncates to the right, but negative index + length can never overlap
113     # the available range.
114     k1 = k1 < 0 ? o.length + k1 : k1           # abs pos (negative is count from end)
115     k2 = k2 < 0 ? o.length - k1 + k2 + 1 : k2  # abs length (negative k2 is length from pos to end count)
116     # if k1 is outside, adjust to first position, and adjust length
117     if k1 < 0
118       k2 = k2 + k1
119       k1 = 0
120     end
121     # Help ruby always return empty array when asking for a sub array
122     result = o[ k1, k2 ]
123     result.nil? ? [] : result
124   else
125     fail(Issues::BAD_ARRAY_SLICE_ARITY, @semantic.left_expr, {:actual => keys.size})
126   end
127 end
access_Binary(o, scope, keys) click to toggle source
   # File lib/puppet/pops/evaluator/access_operator.rb
39 def access_Binary(o, scope, keys)
40   Puppet::Pops::Types::PBinaryType::Binary.from_binary_string(access_String(o.binary_buffer, scope, keys))
41 end
access_Hash(o, scope, keys) click to toggle source

Evaluates <hsh>[] with support for one or more arguments. If more than one argument is used, the result is an array with each lookup. @note

Does not flatten its keys to enable looking up with a structure
    # File lib/puppet/pops/evaluator/access_operator.rb
135 def access_Hash(o, scope, keys)
136   # Look up key in hash, if key is nil, try alternate form (:undef) before giving up.
137   # This is done because the hash may have been produced by 3x logic and may thus contain :undef.
138   result = keys.collect do |k|
139     o.fetch(k) { |key| key.nil? ? o[:undef] : nil }
140   end
141   case result.size
142   when 0
143     fail(Issues::BAD_HASH_SLICE_ARITY, @semantic.left_expr, {:actual => keys.size})
144   when 1
145     result.pop
146   else
147     # remove nil elements and return
148     result.compact!
149     result
150   end
151 end
access_Object(o, scope, keys) click to toggle source
   # File lib/puppet/pops/evaluator/access_operator.rb
30 def access_Object(o, scope, keys)
31   type = Puppet::Pops::Types::TypeCalculator.infer_callable_methods_t(o)
32   if type.is_a?(Puppet::Pops::Types::TypeWithMembers)
33     access_func = type['[]']
34     return access_func.invoke(o, scope, keys) unless access_func.nil?
35   end
36   fail(Issues::OPERATOR_NOT_APPLICABLE, @semantic.left_expr, :operator=>'[]', :left_value => o)
37 end
access_PArrayType(o, scope, keys) click to toggle source

An Array can create a new Array type. It is not possible to create a collection of Array types.

    # File lib/puppet/pops/evaluator/access_operator.rb
510 def access_PArrayType(o, scope, keys)
511   keys.flatten!
512   case keys.size
513   when 1
514     unless keys[0].is_a?(Types::PAnyType)
515       fail(Issues::BAD_TYPE_SLICE_TYPE, @semantic.keys[0], {:base_type => 'Array-Type', :actual => keys[0].class})
516     end
517     type = keys[0]
518     size_t = nil
519   when 2
520     if keys[0].is_a?(Types::PAnyType)
521       size_t = collection_size_t(1, keys[1])
522       type = keys[0]
523     else
524       size_t = collection_size_t(0, keys[0], keys[1])
525       type = nil
526     end
527   when 3
528     if keys[0].is_a?(Types::PAnyType)
529       size_t = collection_size_t(1, keys[1], keys[2])
530       type = keys[0]
531     else
532       fail(Issues::BAD_TYPE_SLICE_TYPE, @semantic.keys[0], {:base_type => 'Array-Type', :actual => keys[0].class})
533     end
534   else
535     fail(Issues::BAD_TYPE_SLICE_ARITY, @semantic,
536       {:base_type => 'Array-Type', :min => 1, :max => 3, :actual => keys.size})
537   end
538   Types::PArrayType.new(type, size_t)
539 end
access_PBooleanType(o, scope, keys) click to toggle source
    # File lib/puppet/pops/evaluator/access_operator.rb
153 def access_PBooleanType(o, scope, keys)
154   keys.flatten!
155   assert_keys(keys, o, 1, 1, TrueClass, FalseClass)
156   Types::TypeFactory.boolean(keys[0])
157 end
access_PCallableType(o, scope, keys) click to toggle source
    # File lib/puppet/pops/evaluator/access_operator.rb
208 def access_PCallableType(o, scope, keys)
209   if keys.size > 0 && keys[0].is_a?(Array)
210     unless keys.size == 2
211       fail(Issues::BAD_TYPE_SLICE_ARITY, @semantic, :base_type => o, :min=>2, :max => 2, :actual => keys.size)
212     end
213     unless keys[1].is_a?(Types::PAnyType)
214       bad_type_specialization_key_type(o, 1, k, Types::PAnyType)
215     end
216   end
217   Types::TypeFactory.callable(*keys)
218 end
access_PClassType(o, scope, keys) click to toggle source
    # File lib/puppet/pops/evaluator/access_operator.rb
663 def access_PClassType(o, scope, keys)
664   blamed = keys.size == 0 ? @semantic : @semantic.keys[0]
665   keys_orig_size = keys.size
666 
667   if keys_orig_size == 0
668     fail(Issues::BAD_TYPE_SLICE_ARITY, blamed,
669       :base_type => o.to_s, :min => 1, :max => -1, :actual => 0)
670   end
671 
672   # The result is an array if multiple classnames are given, or if classnames are specified with an array
673   # (possibly multiple arrays, and nested arrays).
674   result_type_array = keys.size > 1 || keys[0].is_a?(Array)
675 
676   keys.flatten!
677   keys.compact!
678 
679   # If given keys  that were just a mix of empty/nil with empty array as a result.
680   # As opposed to calling the function the wrong way (without any arguments), (configurable issue),
681   # Return an empty array
682   #
683   if keys.empty? && keys_orig_size > 0
684     optionally_fail(Issues::EMPTY_RESOURCE_SPECIALIZATION, blamed)
685     return result_type_array ? [] : nil
686   end
687 
688   if o.class_name.nil?
689     result = keys.each_with_index.map do |c, i|
690       fail(Issues::ILLEGAL_HOSTCLASS_NAME, @semantic.keys[i], {:name => c}) unless c.is_a?(String)
691       name = c.downcase
692       # Remove leading '::' since all references are global, and 3x runtime does the wrong thing
693       name = name[2..-1] if name[0,2] == NS
694 
695       fail(Issues::ILLEGAL_NAME, @semantic.keys[i], {:name=>c}) unless name =~ Patterns::NAME
696       Types::PClassType.new(name)
697     end
698   else
699     # lookup class resource and return one or more parameter values
700     resource = find_resource(scope, 'class', o.class_name)
701     if resource
702       result = keys.map do |k|
703         if is_parameter_of_resource?(scope, resource, k)
704           get_resource_parameter_value(scope, resource, k)
705         else
706           fail(Issues::UNKNOWN_RESOURCE_PARAMETER, @semantic,
707             {:type_name => 'Class', :title => o.class_name, :param_name=>k})
708         end
709       end
710     else
711       fail(Issues::UNKNOWN_RESOURCE, @semantic, {:type_name => 'Class', :title => o.class_name})
712     end
713   end
714 
715   # returns single type as type, else an array of types
716   return result_type_array ? result : result.pop
717 end
access_PCollectionType(o, scope, keys) click to toggle source

CollectionType is parameterized with a range

    # File lib/puppet/pops/evaluator/access_operator.rb
494 def access_PCollectionType(o, scope, keys)
495   keys.flatten!
496   case keys.size
497   when 1
498     size_t = collection_size_t(0, keys[0])
499   when 2
500     size_t = collection_size_t(0, keys[0], keys[1])
501   else
502     fail(Issues::BAD_TYPE_SLICE_ARITY, @semantic,
503       {:base_type => 'Collection-Type', :min => 1, :max => 2, :actual => keys.size})
504   end
505   Types::PCollectionType.new(size_t)
506 end
access_PEnumType(o, scope, keys) click to toggle source
    # File lib/puppet/pops/evaluator/access_operator.rb
159 def access_PEnumType(o, scope, keys)
160   keys.flatten!
161   last = keys.last
162   case_insensitive = false
163   if last == true || last == false
164     keys = keys[0...-1]
165     case_insensitive = last
166   end
167   assert_keys(keys, o, 1, Float::INFINITY, String)
168   Types::PEnumType.new(keys, case_insensitive)
169 end
access_PFloatType(o, scope, keys) click to toggle source
    # File lib/puppet/pops/evaluator/access_operator.rb
447 def access_PFloatType(o, scope, keys)
448   keys.flatten!
449   unless keys.size.between?(1, 2)
450     fail(Issues::BAD_FLOAT_SLICE_ARITY, @semantic, {:actual => keys.size})
451   end
452   keys.each_with_index do |x, index|
453     fail(Issues::BAD_FLOAT_SLICE_TYPE, @semantic.keys[index],
454       {:actual => x.class}) unless (x.is_a?(Float) || x.is_a?(Integer) || x == :default)
455   end
456   from, to = keys
457   from = from == :default || from.nil? ? nil : Float(from)
458   to = to == :default || to.nil? ? nil : Float(to)
459   Types::PFloatType.new(from, to)
460 end
access_PHashType(o, scope, keys) click to toggle source

A Hash can create a new Hash type, one arg sets value type, two args sets key and value type in new type. With 3 or 4 arguments, these are used to create a size constraint. It is not possible to create a collection of Hash types directly.

    # File lib/puppet/pops/evaluator/access_operator.rb
466 def access_PHashType(o, scope, keys)
467   keys.flatten!
468   if keys.size == 2 && keys[0].is_a?(Integer) && keys[1].is_a?(Integer)
469     return Types::PHashType.new(nil, nil, Types::PIntegerType.new(*keys))
470   end
471 
472   keys[0,2].each_with_index do |k, index|
473     unless k.is_a?(Types::PAnyType)
474       fail(Issues::BAD_TYPE_SLICE_TYPE, @semantic.keys[index], {:base_type => 'Hash-Type', :actual => k.class})
475     end
476   end
477   case keys.size
478   when 2
479     size_t = nil
480   when 3
481     size_t = keys[2]
482     size_t = Types::PIntegerType.new(size_t) unless size_t.is_a?(Types::PIntegerType)
483   when 4
484     size_t = collection_size_t(2, keys[2], keys[3])
485   else
486     fail(Issues::BAD_TYPE_SLICE_ARITY, @semantic, {
487       :base_type => 'Hash-Type', :min => 2, :max => 4, :actual => keys.size
488     })
489   end
490   Types::PHashType.new(keys[0], keys[1], size_t)
491 end
access_PInitType(o, scope, keys) click to toggle source
    # File lib/puppet/pops/evaluator/access_operator.rb
397 def access_PInitType(o, scope, keys)
398   unless keys[0].is_a?(Types::PAnyType)
399     fail(Issues::BAD_TYPE_SLICE_TYPE, @semantic.keys[0], {:base_type => 'Init-Type', :actual => keys[0].class})
400   end
401   Types::TypeFactory.init(*keys)
402 end
access_PIntegerType(o, scope, keys) click to toggle source
    # File lib/puppet/pops/evaluator/access_operator.rb
435 def access_PIntegerType(o, scope, keys)
436   keys.flatten!
437   unless keys.size.between?(1, 2)
438     fail(Issues::BAD_INTEGER_SLICE_ARITY, @semantic, {:actual => keys.size})
439   end
440   keys.each_with_index do |x, index|
441     fail(Issues::BAD_INTEGER_SLICE_TYPE, @semantic.keys[index],
442       {:actual => x.class}) unless (x.is_a?(Integer) || x == :default)
443   end
444   Types::PIntegerType.new(*keys)
445 end
access_PIterableType(o, scope, keys) click to toggle source
    # File lib/puppet/pops/evaluator/access_operator.rb
404 def access_PIterableType(o, scope, keys)
405   keys.flatten!
406   if keys.size == 1
407     unless keys[0].is_a?(Types::PAnyType)
408       fail(Issues::BAD_TYPE_SLICE_TYPE, @semantic.keys[0], {:base_type => 'Iterable-Type', :actual => keys[0].class})
409     end
410     Types::PIterableType.new(keys[0])
411   else
412     fail(Issues::BAD_TYPE_SLICE_ARITY, @semantic, {:base_type => 'Iterable-Type', :min => 1, :actual => keys.size})
413   end
414 end
access_PIteratorType(o, scope, keys) click to toggle source
    # File lib/puppet/pops/evaluator/access_operator.rb
416 def access_PIteratorType(o, scope, keys)
417   keys.flatten!
418   if keys.size == 1
419     unless keys[0].is_a?(Types::PAnyType)
420       fail(Issues::BAD_TYPE_SLICE_TYPE, @semantic.keys[0], {:base_type => 'Iterator-Type', :actual => keys[0].class})
421     end
422     Types::PIteratorType.new(keys[0])
423   else
424     fail(Issues::BAD_TYPE_SLICE_ARITY, @semantic, {:base_type => 'Iterator-Type', :min => 1, :actual => keys.size})
425   end
426 end
access_PNotUndefType(o, scope, keys) click to toggle source
    # File lib/puppet/pops/evaluator/access_operator.rb
364 def access_PNotUndefType(o, scope, keys)
365   keys.flatten!
366   case keys.size
367   when 0
368     Types::TypeFactory.not_undef
369   when 1
370     type = keys[0]
371     case type
372     when String
373       type = Types::TypeFactory.string(type)
374     when Types::PAnyType
375       type = nil if type.class == Types::PAnyType
376     else
377       fail(Issues::BAD_NOT_UNDEF_SLICE_TYPE, @semantic.keys[0], {:base_type => 'NotUndef-Type', :actual => type.class})
378     end
379     Types::TypeFactory.not_undef(type)
380   else
381     fail(Issues::BAD_TYPE_SLICE_ARITY, @semantic, {:base_type => 'NotUndef-Type', :min => 0, :max => 1, :actual => keys.size})
382   end
383 end
access_PObjectType(o, scope, keys) click to toggle source
    # File lib/puppet/pops/evaluator/access_operator.rb
342 def access_PObjectType(o, scope, keys)
343   keys.flatten!
344   if o.resolved? && !o.name.nil?
345     Types::PObjectTypeExtension.create(o, keys)
346   else
347     if keys.size == 1
348       Types::TypeFactory.object(keys[0])
349     else
350       fail(Issues::BAD_TYPE_SLICE_ARITY, @semantic, {:base_type => 'Object-Type', :min => 1, :actual => keys.size})
351     end
352   end
353 end
access_POptionalType(o, scope, keys) click to toggle source
    # File lib/puppet/pops/evaluator/access_operator.rb
312 def access_POptionalType(o, scope, keys)
313   keys.flatten!
314   if keys.size == 1
315     type = keys[0]
316     unless type.is_a?(Types::PAnyType)
317       if type.is_a?(String)
318         type = Types::TypeFactory.string(type)
319       else
320         fail(Issues::BAD_TYPE_SLICE_TYPE, @semantic.keys[0], {:base_type => 'Optional-Type', :actual => type.class})
321       end
322     end
323     Types::POptionalType.new(type)
324   else
325     fail(Issues::BAD_TYPE_SLICE_ARITY, @semantic, {:base_type => 'Optional-Type', :min => 1, :actual => keys.size})
326   end
327 end
access_PPatternType(o, scope, keys) click to toggle source
    # File lib/puppet/pops/evaluator/access_operator.rb
293 def access_PPatternType(o, scope, keys)
294   keys.flatten!
295   assert_keys(keys, o, 1, Float::INFINITY, String, Regexp, Types::PPatternType, Types::PRegexpType)
296   Types::TypeFactory.pattern(*keys)
297 end
access_PRegexpType(o, scope, keys) click to toggle source

Parameterizes a PRegexp Type with a pattern string or r ruby egexp

   # File lib/puppet/pops/evaluator/access_operator.rb
82 def access_PRegexpType(o, scope, keys)
83   keys.flatten!
84   unless keys.size == 1
85     blamed = keys.size == 0 ? @semantic : @semantic.keys[1]
86     fail(Issues::BAD_TYPE_SLICE_ARITY, blamed, :base_type => o, :min=>1, :actual => keys.size)
87   end
88   assert_keys(keys, o, 1, 1, String, Regexp)
89   Types::TypeFactory.regexp(*keys)
90 end
access_PResourceType(o, scope, keys) click to toggle source

A Resource can create a new more specific Resource type, and/or an array of resource types If the given type has title set, it can not be specified further. @example

Resource[File]               # => File
Resource[File, 'foo']        # => File[foo]
Resource[File. 'foo', 'bar'] # => [File[foo], File[bar]]
File['foo', 'bar']           # => [File[foo], File[bar]]
File['foo']['bar']           # => Value of the 'bar' parameter in the File['foo'] resource
Resource[File]['foo', 'bar'] # => [File[Foo], File[bar]]
Resource[File, 'foo', 'bar'] # => [File[foo], File[bar]]
Resource[File, 'foo']['bar'] # => Value of the 'bar' parameter in the File['foo'] resource
    # File lib/puppet/pops/evaluator/access_operator.rb
582 def access_PResourceType(o, scope, keys)
583   blamed = keys.size == 0 ? @semantic : @semantic.keys[0]
584 
585   if keys.size == 0
586     fail(Issues::BAD_TYPE_SLICE_ARITY, blamed,
587       :base_type => o.to_s, :min => 1, :max => -1, :actual => 0)
588   end
589 
590   # Must know which concrete resource type to operate on in all cases.
591   # It is not allowed to specify the type in an array arg - e.g. Resource[[File, 'foo']]
592   # type_name is LHS type_name if set, else the first given arg
593   type_name = o.type_name || Types::TypeFormatter.singleton.capitalize_segments(keys.shift)
594   type_name = case type_name
595   when Types::PResourceType
596     type_name.type_name
597   when String
598     type_name
599   else
600     # blame given left expression if it defined the type, else the first given key expression
601     blame = o.type_name.nil? ? @semantic.keys[0] : @semantic.left_expr
602     fail(Issues::ILLEGAL_RESOURCE_SPECIALIZATION, blame, {:actual => bad_key_type_name(type_name)})
603   end
604 
605   # type name must conform
606   if type_name !~ Patterns::CLASSREF_EXT
607     fail(Issues::ILLEGAL_CLASSREF, blamed, {:name=>type_name})
608   end
609 
610   # The result is an array if multiple titles are given, or if titles are specified with an array
611   # (possibly multiple arrays, and nested arrays).
612   result_type_array = keys.size > 1 || keys[0].is_a?(Array)
613   keys_orig_size = keys.size
614 
615   keys.flatten!
616   keys.compact!
617 
618   # If given keys  that were just a mix of empty/nil with empty array as a result.
619   # As opposed to calling the function the wrong way (without any arguments), (configurable issue),
620   # Return an empty array
621   #
622   if keys.empty? && keys_orig_size > 0
623     optionally_fail(Issues::EMPTY_RESOURCE_SPECIALIZATION, blamed)
624     return result_type_array ? [] : nil
625   end
626 
627   if !o.title.nil?
628     # lookup resource and return one or more parameter values
629     resource = find_resource(scope, o.type_name, o.title)
630     unless resource
631       fail(Issues::UNKNOWN_RESOURCE, @semantic, {:type_name => o.type_name, :title => o.title})
632     end
633 
634     result = keys.map do |k|
635       unless is_parameter_of_resource?(scope, resource, k)
636         fail(Issues::UNKNOWN_RESOURCE_PARAMETER, @semantic,
637           {:type_name => o.type_name, :title => o.title, :param_name=>k})
638       end
639       get_resource_parameter_value(scope, resource, k)
640     end
641     return result_type_array ? result : result.pop
642   end
643 
644 
645   keys = [:no_title] if keys.size < 1 # if there was only a type_name and it was consumed
646   result = keys.each_with_index.map do |t, i|
647     unless t.is_a?(String) || t == :no_title
648       index = keys_orig_size != keys.size ? i+1 : i
649       fail(Issues::BAD_TYPE_SPECIALIZATION, @semantic.keys[index], {
650         :type => o,
651         :message => "Cannot use #{bad_key_type_name(t)} where a resource title String is expected"
652       })
653     end
654 
655     Types::PResourceType.new(type_name, t == :no_title ? nil : t)
656   end
657   # returns single type if request was for a single entity, else an array of types (possibly empty)
658   return result_type_array ? result : result.pop
659 end
access_PRuntimeType(o, scope, keys) click to toggle source
    # File lib/puppet/pops/evaluator/access_operator.rb
428 def access_PRuntimeType(o, scope, keys)
429   keys.flatten!
430   assert_keys(keys, o, 2, 2, String, String)
431   # create runtime type based on runtime and name of class, (not inference of key's type)
432   Types::TypeFactory.runtime(*keys)
433 end
access_PSemVerType(o, scope, keys) click to toggle source
    # File lib/puppet/pops/evaluator/access_operator.rb
177 def access_PSemVerType(o, scope, keys)
178   keys.flatten!
179   assert_keys(keys, o, 1, Float::INFINITY, String, SemanticPuppet::VersionRange)
180   Types::TypeFactory.sem_ver(*keys)
181 end
access_PSensitiveType(o, scope, keys) click to toggle source
    # File lib/puppet/pops/evaluator/access_operator.rb
329 def access_PSensitiveType(o, scope, keys)
330   keys.flatten!
331   if keys.size == 1
332     type = keys[0]
333     unless type.is_a?(Types::PAnyType)
334       fail(Issues::BAD_TYPE_SLICE_TYPE, @semantic.keys[0], {:base_type => 'Sensitive-Type', :actual => type.class})
335     end
336     Types::PSensitiveType.new(type)
337   else
338     fail(Issues::BAD_TYPE_SLICE_ARITY, @semantic, {:base_type => 'Sensitive-Type', :min => 1, :actual => keys.size})
339   end
340 end
access_PStringType(o, scope, keys) click to toggle source
    # File lib/puppet/pops/evaluator/access_operator.rb
225 def access_PStringType(o, scope, keys)
226   keys.flatten!
227   case keys.size
228   when 1
229     size_t = collection_size_t(0, keys[0])
230   when 2
231     size_t = collection_size_t(0, keys[0], keys[1])
232   else
233     fail(Issues::BAD_STRING_SLICE_ARITY, @semantic, {:actual => keys.size})
234   end
235   Types::TypeFactory.string(size_t)
236 end
access_PStructType(o, scope, keys) click to toggle source
    # File lib/puppet/pops/evaluator/access_operator.rb
220 def access_PStructType(o, scope, keys)
221   assert_keys(keys, o, 1, 1, Hash)
222   Types::TypeFactory.struct(keys[0])
223 end
access_PTimespanType(o, scope, keys) click to toggle source
    # File lib/puppet/pops/evaluator/access_operator.rb
189 def access_PTimespanType(o, scope, keys)
190   keys.flatten!
191   fail(Issues::BAD_TYPE_SLICE_ARITY, @semantic, :base_type => o, :min=>0, :max => 2, :actual => keys.size) if keys.size > 2
192   Types::TypeFactory.timespan(*keys)
193 end
access_PTimestampType(o, scope, keys) click to toggle source
    # File lib/puppet/pops/evaluator/access_operator.rb
183 def access_PTimestampType(o, scope, keys)
184   keys.flatten!
185   fail(Issues::BAD_TYPE_SLICE_ARITY, @semantic, :base_type => o, :min=>0, :max => 2, :actual => keys.size) if keys.size > 2
186   Types::TypeFactory.timestamp(*keys)
187 end
access_PTupleType(o, scope, keys) click to toggle source
    # File lib/puppet/pops/evaluator/access_operator.rb
195 def access_PTupleType(o, scope, keys)
196   keys.flatten!
197   if Types::TypeFactory.is_range_parameter?(keys[-2]) && Types::TypeFactory.is_range_parameter?(keys[-1])
198     size_type = Types::TypeFactory.range(keys[-2], keys[-1])
199     keys = keys[0, keys.size - 2]
200   elsif Types::TypeFactory.is_range_parameter?(keys[-1])
201     size_type = Types::TypeFactory.range(keys[-1], :default)
202     keys = keys[0, keys.size - 1]
203   end
204   assert_keys(keys, o, 1, Float::INFINITY, Types::PAnyType)
205   Types::TypeFactory.tuple(keys, size_type)
206 end
access_PTypeReferenceType(o, scope, keys) click to toggle source

If a type reference is encountered here, it's an error

    # File lib/puppet/pops/evaluator/access_operator.rb
566 def access_PTypeReferenceType(o, scope, keys)
567   fail(Issues::UNKNOWN_RESOURCE_TYPE, @semantic, {:type_name => o.type_string })
568 end
access_PTypeSetType(o, scope, keys) click to toggle source
    # File lib/puppet/pops/evaluator/access_operator.rb
355 def access_PTypeSetType(o, scope, keys)
356   keys.flatten!
357   if keys.size == 1
358     Types::TypeFactory.type_set(keys[0])
359   else
360     fail(Issues::BAD_TYPE_SLICE_ARITY, @semantic, {:base_type => 'TypeSet-Type', :min => 1, :actual => keys.size})
361   end
362 end
access_PTypeType(o, scope, keys) click to toggle source
    # File lib/puppet/pops/evaluator/access_operator.rb
385 def access_PTypeType(o, scope, keys)
386   keys.flatten!
387   if keys.size == 1
388     unless keys[0].is_a?(Types::PAnyType)
389       fail(Issues::BAD_TYPE_SLICE_TYPE, @semantic.keys[0], {:base_type => 'Type-Type', :actual => keys[0].class})
390     end
391     Types::PTypeType.new(keys[0])
392   else
393     fail(Issues::BAD_TYPE_SLICE_ARITY, @semantic, {:base_type => 'Type-Type', :min => 1, :actual => keys.size})
394   end
395 end
access_PURIType(o, scope, keys) click to toggle source
    # File lib/puppet/pops/evaluator/access_operator.rb
299 def access_PURIType(o, scope, keys)
300   keys.flatten!
301   if keys.size == 1
302     param = keys[0]
303     unless Types::PURIType::TYPE_URI_PARAM_TYPE.instance?(param)
304       fail(Issues::BAD_TYPE_SLICE_TYPE, @semantic.keys[0], {:base_type => 'URI-Type', :actual => param.class})
305     end
306     Types::PURIType.new(param)
307   else
308     fail(Issues::BAD_TYPE_SLICE_ARITY, @semantic, {:base_type => 'URI-Type', :min => 1, :actual => keys.size})
309   end
310 end
access_PVariantType(o, scope, keys) click to toggle source
    # File lib/puppet/pops/evaluator/access_operator.rb
171 def access_PVariantType(o, scope, keys)
172   keys.flatten!
173   assert_keys(keys, o, 1, Float::INFINITY, Types::PAnyType)
174   Types::TypeFactory.variant(*keys)
175 end
access_Resource(o, scope, keys) click to toggle source

A Puppet::Resource represents either just a type (no title), or is a fully qualified type/title.

    # File lib/puppet/pops/evaluator/access_operator.rb
556 def access_Resource(o, scope, keys)
557   # To access a Puppet::Resource as if it was a PResourceType, simply infer it, and take the type of
558   # the parameterized meta type (i.e. Type[Resource[the_resource_type, the_resource_title]])
559   t = Types::TypeCalculator.infer(o).type
560   # must map "undefined title" from resource to nil
561   t.title = nil if t.title == EMPTY_STRING
562   access(t, scope, *keys)
563 end
access_String(o, scope, keys) click to toggle source
   # File lib/puppet/pops/evaluator/access_operator.rb
43 def access_String(o, scope, keys)
44   keys.flatten!
45   result = case keys.size
46   when 0
47     fail(Issues::BAD_STRING_SLICE_ARITY, @semantic.left_expr, {:actual => keys.size})
48   when 1
49     # Note that Ruby 1.8.7 requires a length of 1 to produce a String
50     k1 = Utils.to_n(keys[0])
51     bad_string_access_key_type(o, 0, k1.nil? ? keys[0] : k1) unless k1.is_a?(Integer)
52     k2 = 1
53     k1 = k1 < 0 ? o.length + k1 : k1           # abs pos
54     # if k1 is outside, a length of 1 always produces an empty string
55     if k1 < 0
56       EMPTY_STRING
57     else
58       o[ k1, k2 ]
59     end
60   when 2
61     k1 = Utils.to_n(keys[0])
62     k2 = Utils.to_n(keys[1])
63     [k1, k2].each_with_index { |k,i| bad_string_access_key_type(o, i, k.nil? ? keys[i] : k) unless k.is_a?(Integer) }
64 
65     k1 = k1 < 0 ? o.length + k1 : k1           # abs pos (negative is count from end)
66     k2 = k2 < 0 ? o.length - k1 + k2 + 1 : k2  # abs length (negative k2 is length from pos to end count)
67     # if k1 is outside, adjust to first position, and adjust length
68     if k1 < 0
69       k2 = k2 + k1
70       k1 = 0
71     end
72     o[ k1, k2 ]
73   else
74     fail(Issues::BAD_STRING_SLICE_ARITY, @semantic.left_expr, {:actual => keys.size})
75   end
76   # Specified as: an index outside of range, or empty result == empty string
77   (result.nil? || result.empty?) ? EMPTY_STRING : result
78 end
assert_keys(keys, o, min, max, *allowed_classes) click to toggle source

Asserts type of each key and calls fail with BAD_TYPE_SPECIFICATION @param keys [Array<Object>] the evaluated keys @param o [Object] evaluated LHS reported as :base_type @param min [Integer] the minimum number of keys (typically 1) @param max [Numeric] the maximum number of keys (use same as min, specific number, or Float::INFINITY) @param allowed_classes [Class] a variable number of classes that each key must be an instance of (any) @api private

    # File lib/puppet/pops/evaluator/access_operator.rb
246 def assert_keys(keys, o, min, max, *allowed_classes)
247   size = keys.size
248   unless size.between?(min, max || Float::INFINITY)
249     fail(Issues::BAD_TYPE_SLICE_ARITY, @semantic, :base_type => o, :min=>1, :max => max, :actual => keys.size)
250   end
251   keys.each_with_index do |k, i|
252     unless allowed_classes.any? {|clazz| k.is_a?(clazz) }
253       bad_type_specialization_key_type(o, i, k, *allowed_classes)
254     end
255   end
256 end
bad_access_key_type(lhs, key_index, actual, *expected_classes) click to toggle source
    # File lib/puppet/pops/evaluator/access_operator.rb
258 def bad_access_key_type(lhs, key_index, actual, *expected_classes)
259   fail(Issues::BAD_SLICE_KEY_TYPE, @semantic.keys[key_index], {
260     :left_value => lhs,
261     :actual => bad_key_type_name(actual),
262     :expected_classes => expected_classes
263   })
264 end
bad_key_type_name(actual) click to toggle source
    # File lib/puppet/pops/evaluator/access_operator.rb
273 def bad_key_type_name(actual)
274   case actual
275   when nil
276     'Undef'
277   when :default
278     'Default'
279   else
280     Types::TypeCalculator.generalize(Types::TypeCalculator.infer(actual)).to_s
281   end
282 end
bad_string_access_key_type(lhs, key_index, actual) click to toggle source
    # File lib/puppet/pops/evaluator/access_operator.rb
266 def bad_string_access_key_type(lhs, key_index, actual)
267   fail(Issues::BAD_STRING_SLICE_KEY_TYPE, @semantic.keys[key_index], {
268     :left_value => lhs,
269     :actual_type => bad_key_type_name(actual),
270   })
271 end
bad_type_specialization_key_type(type, key_index, actual, *expected_classes) click to toggle source
    # File lib/puppet/pops/evaluator/access_operator.rb
284 def bad_type_specialization_key_type(type, key_index, actual, *expected_classes)
285   label_provider = Model::ModelLabelProvider.new()
286   expected = expected_classes.map {|c| label_provider.label(c) }.join(' or ')
287   fail(Issues::BAD_TYPE_SPECIALIZATION, @semantic.keys[key_index], {
288     :type => type,
289     :message => _("Cannot use %{key} where %{expected} is expected") % { key: bad_key_type_name(actual), expected: expected }
290   })
291 end
collection_size_t(start_index, *keys) click to toggle source

Produces an PIntegerType (range) given one or two keys.

    # File lib/puppet/pops/evaluator/access_operator.rb
542 def collection_size_t(start_index, *keys)
543   if keys.size == 1 && keys[0].is_a?(Types::PIntegerType)
544     keys[0]
545   else
546     keys.each_with_index do |x, index|
547       fail(Issues::BAD_COLLECTION_SLICE_TYPE, @semantic.keys[start_index + index],
548         {:actual => x.class}) unless (x.is_a?(Integer) || x == :default)
549     end
550     Types::PIntegerType.new(*keys)
551   end
552 end