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
18 def initialize(access_expression)
19   @@access_visitor ||= Visitor.new(self, "access", 2, nil)
20   @semantic = access_expression
21 end

Public Instance Methods

access(o, scope, *keys) click to toggle source
   # File lib/puppet/pops/evaluator/access_operator.rb
23 def access(o, scope, *keys)
24   @@access_visitor.visit_this_2(self, o, scope, keys)
25 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
 93 def access_Array(o, scope, keys)
 94   keys.flatten!
 95   case keys.size
 96   when 0
 97     fail(Issues::BAD_ARRAY_SLICE_ARITY, @semantic.left_expr, {:actual => keys.size})
 98   when 1
 99     key = coerce_numeric(keys[0], @semantic.keys[0], scope)
100     unless key.is_a?(Integer)
101       bad_access_key_type(o, 0, key, Integer)
102     end
103     o[key]
104   when 2
105     # A slice [from, to] with support for -1 to mean start, or end respectively.
106     k1 = coerce_numeric(keys[0], @semantic.keys[0], scope)
107     k2 = coerce_numeric(keys[1], @semantic.keys[1], scope)
108 
109     [k1, k2].each_with_index { |k,i| bad_access_key_type(o, i, k, Integer) unless k.is_a?(Integer) }
110 
111     # Help confused Ruby do the right thing (it truncates to the right, but negative index + length can never overlap
112     # the available range.
113     k1 = k1 < 0 ? o.length + k1 : k1           # abs pos (negative is count from end)
114     k2 = k2 < 0 ? o.length - k1 + k2 + 1 : k2  # abs length (negative k2 is length from pos to end count)
115     # if k1 is outside, adjust to first position, and adjust length
116     if k1 < 0
117       k2 = k2 + k1
118       k1 = 0
119     end
120     # Help ruby always return empty array when asking for a sub array
121     result = o[ k1, k2 ]
122     result.nil? ? [] : result
123   else
124     fail(Issues::BAD_ARRAY_SLICE_ARITY, @semantic.left_expr, {:actual => keys.size})
125   end
126 end
access_Binary(o, scope, keys) click to toggle source
   # File lib/puppet/pops/evaluator/access_operator.rb
38 def access_Binary(o, scope, keys)
39   Puppet::Pops::Types::PBinaryType::Binary.from_binary_string(access_String(o.binary_buffer, scope, keys))
40 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
134 def access_Hash(o, scope, keys)
135   # Look up key in hash, if key is nil, try alternate form (:undef) before giving up.
136   # This is done because the hash may have been produced by 3x logic and may thus contain :undef.
137   result = keys.collect do |k|
138     o.fetch(k) { |key| key.nil? ? o[:undef] : nil }
139   end
140   case result.size
141   when 0
142     fail(Issues::BAD_HASH_SLICE_ARITY, @semantic.left_expr, {:actual => keys.size})
143   when 1
144     result.pop
145   else
146     # remove nil elements and return
147     result.compact!
148     result
149   end
150 end
access_Object(o, scope, keys) click to toggle source
   # File lib/puppet/pops/evaluator/access_operator.rb
29 def access_Object(o, scope, keys)
30   type = Puppet::Pops::Types::TypeCalculator.infer_callable_methods_t(o)
31   if type.is_a?(Puppet::Pops::Types::TypeWithMembers)
32     access_func = type['[]']
33     return access_func.invoke(o, scope, keys) unless access_func.nil?
34   end
35   fail(Issues::OPERATOR_NOT_APPLICABLE, @semantic.left_expr, :operator=>'[]', :left_value => o)
36 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
509 def access_PArrayType(o, scope, keys)
510   keys.flatten!
511   case keys.size
512   when 1
513     unless keys[0].is_a?(Types::PAnyType)
514       fail(Issues::BAD_TYPE_SLICE_TYPE, @semantic.keys[0], {:base_type => 'Array-Type', :actual => keys[0].class})
515     end
516     type = keys[0]
517     size_t = nil
518   when 2
519     if keys[0].is_a?(Types::PAnyType)
520       size_t = collection_size_t(1, keys[1])
521       type = keys[0]
522     else
523       size_t = collection_size_t(0, keys[0], keys[1])
524       type = nil
525     end
526   when 3
527     if keys[0].is_a?(Types::PAnyType)
528       size_t = collection_size_t(1, keys[1], keys[2])
529       type = keys[0]
530     else
531       fail(Issues::BAD_TYPE_SLICE_TYPE, @semantic.keys[0], {:base_type => 'Array-Type', :actual => keys[0].class})
532     end
533   else
534     fail(Issues::BAD_TYPE_SLICE_ARITY, @semantic,
535       {:base_type => 'Array-Type', :min => 1, :max => 3, :actual => keys.size})
536   end
537   Types::PArrayType.new(type, size_t)
538 end
access_PBooleanType(o, scope, keys) click to toggle source
    # File lib/puppet/pops/evaluator/access_operator.rb
152 def access_PBooleanType(o, scope, keys)
153   keys.flatten!
154   assert_keys(keys, o, 1, 1, TrueClass, FalseClass)
155   Types::TypeFactory.boolean(keys[0])
156 end
access_PCallableType(o, scope, keys) click to toggle source
    # File lib/puppet/pops/evaluator/access_operator.rb
207 def access_PCallableType(o, scope, keys)
208   if keys.size > 0 && keys[0].is_a?(Array)
209     unless keys.size == 2
210       fail(Issues::BAD_TYPE_SLICE_ARITY, @semantic, :base_type => o, :min=>2, :max => 2, :actual => keys.size)
211     end
212     unless keys[1].is_a?(Types::PAnyType)
213       bad_type_specialization_key_type(o, 1, k, Types::PAnyType)
214     end
215   end
216   Types::TypeFactory.callable(*keys)
217 end
access_PClassType(o, scope, keys) click to toggle source
    # File lib/puppet/pops/evaluator/access_operator.rb
662 def access_PClassType(o, scope, keys)
663   blamed = keys.size == 0 ? @semantic : @semantic.keys[0]
664   keys_orig_size = keys.size
665 
666   if keys_orig_size == 0
667     fail(Issues::BAD_TYPE_SLICE_ARITY, blamed,
668       :base_type => o.to_s, :min => 1, :max => -1, :actual => 0)
669   end
670 
671   # The result is an array if multiple classnames are given, or if classnames are specified with an array
672   # (possibly multiple arrays, and nested arrays).
673   result_type_array = keys.size > 1 || keys[0].is_a?(Array)
674 
675   keys.flatten!
676   keys.compact!
677 
678   # If given keys  that were just a mix of empty/nil with empty array as a result.
679   # As opposed to calling the function the wrong way (without any arguments), (configurable issue),
680   # Return an empty array
681   #
682   if keys.empty? && keys_orig_size > 0
683     optionally_fail(Issues::EMPTY_RESOURCE_SPECIALIZATION, blamed)
684     return result_type_array ? [] : nil
685   end
686 
687   if o.class_name.nil?
688     result = keys.each_with_index.map do |c, i|
689       fail(Issues::ILLEGAL_HOSTCLASS_NAME, @semantic.keys[i], {:name => c}) unless c.is_a?(String)
690       name = c.downcase
691       # Remove leading '::' since all references are global, and 3x runtime does the wrong thing
692       name = name[2..-1] if name[0,2] == NS
693 
694       fail(Issues::ILLEGAL_NAME, @semantic.keys[i], {:name=>c}) unless name =~ Patterns::NAME
695       Types::PClassType.new(name)
696     end
697   else
698     # lookup class resource and return one or more parameter values
699     resource = find_resource(scope, 'class', o.class_name)
700     if resource
701       result = keys.map do |k|
702         if is_parameter_of_resource?(scope, resource, k)
703           get_resource_parameter_value(scope, resource, k)
704         else
705           fail(Issues::UNKNOWN_RESOURCE_PARAMETER, @semantic,
706             {:type_name => 'Class', :title => o.class_name, :param_name=>k})
707         end
708       end
709     else
710       fail(Issues::UNKNOWN_RESOURCE, @semantic, {:type_name => 'Class', :title => o.class_name})
711     end
712   end
713 
714   # returns single type as type, else an array of types
715   return result_type_array ? result : result.pop
716 end
access_PCollectionType(o, scope, keys) click to toggle source

CollectionType is parameterized with a range

    # File lib/puppet/pops/evaluator/access_operator.rb
493 def access_PCollectionType(o, scope, keys)
494   keys.flatten!
495   case keys.size
496   when 1
497     size_t = collection_size_t(0, keys[0])
498   when 2
499     size_t = collection_size_t(0, keys[0], keys[1])
500   else
501     fail(Issues::BAD_TYPE_SLICE_ARITY, @semantic,
502       {:base_type => 'Collection-Type', :min => 1, :max => 2, :actual => keys.size})
503   end
504   Types::PCollectionType.new(size_t)
505 end
access_PEnumType(o, scope, keys) click to toggle source
    # File lib/puppet/pops/evaluator/access_operator.rb
158 def access_PEnumType(o, scope, keys)
159   keys.flatten!
160   last = keys.last
161   case_insensitive = false
162   if last == true || last == false
163     keys = keys[0...-1]
164     case_insensitive = last
165   end
166   assert_keys(keys, o, 1, Float::INFINITY, String)
167   Types::PEnumType.new(keys, case_insensitive)
168 end
access_PFloatType(o, scope, keys) click to toggle source
    # File lib/puppet/pops/evaluator/access_operator.rb
446 def access_PFloatType(o, scope, keys)
447   keys.flatten!
448   unless keys.size.between?(1, 2)
449     fail(Issues::BAD_FLOAT_SLICE_ARITY, @semantic, {:actual => keys.size})
450   end
451   keys.each_with_index do |x, index|
452     fail(Issues::BAD_FLOAT_SLICE_TYPE, @semantic.keys[index],
453       {:actual => x.class}) unless (x.is_a?(Float) || x.is_a?(Integer) || x == :default)
454   end
455   from, to = keys
456   from = from == :default || from.nil? ? nil : Float(from)
457   to = to == :default || to.nil? ? nil : Float(to)
458   Types::PFloatType.new(from, to)
459 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
465 def access_PHashType(o, scope, keys)
466   keys.flatten!
467   if keys.size == 2 && keys[0].is_a?(Integer) && keys[1].is_a?(Integer)
468     return Types::PHashType.new(nil, nil, Types::PIntegerType.new(*keys))
469   end
470 
471   keys[0,2].each_with_index do |k, index|
472     unless k.is_a?(Types::PAnyType)
473       fail(Issues::BAD_TYPE_SLICE_TYPE, @semantic.keys[index], {:base_type => 'Hash-Type', :actual => k.class})
474     end
475   end
476   case keys.size
477   when 2
478     size_t = nil
479   when 3
480     size_t = keys[2]
481     size_t = Types::PIntegerType.new(size_t) unless size_t.is_a?(Types::PIntegerType)
482   when 4
483     size_t = collection_size_t(2, keys[2], keys[3])
484   else
485     fail(Issues::BAD_TYPE_SLICE_ARITY, @semantic, {
486       :base_type => 'Hash-Type', :min => 2, :max => 4, :actual => keys.size
487     })
488   end
489   Types::PHashType.new(keys[0], keys[1], size_t)
490 end
access_PInitType(o, scope, keys) click to toggle source
    # File lib/puppet/pops/evaluator/access_operator.rb
396 def access_PInitType(o, scope, keys)
397   unless keys[0].is_a?(Types::PAnyType)
398     fail(Issues::BAD_TYPE_SLICE_TYPE, @semantic.keys[0], {:base_type => 'Init-Type', :actual => keys[0].class})
399   end
400   Types::TypeFactory.init(*keys)
401 end
access_PIntegerType(o, scope, keys) click to toggle source
    # File lib/puppet/pops/evaluator/access_operator.rb
434 def access_PIntegerType(o, scope, keys)
435   keys.flatten!
436   unless keys.size.between?(1, 2)
437     fail(Issues::BAD_INTEGER_SLICE_ARITY, @semantic, {:actual => keys.size})
438   end
439   keys.each_with_index do |x, index|
440     fail(Issues::BAD_INTEGER_SLICE_TYPE, @semantic.keys[index],
441       {:actual => x.class}) unless (x.is_a?(Integer) || x == :default)
442   end
443   Types::PIntegerType.new(*keys)
444 end
access_PIterableType(o, scope, keys) click to toggle source
    # File lib/puppet/pops/evaluator/access_operator.rb
403 def access_PIterableType(o, scope, keys)
404   keys.flatten!
405   if keys.size == 1
406     unless keys[0].is_a?(Types::PAnyType)
407       fail(Issues::BAD_TYPE_SLICE_TYPE, @semantic.keys[0], {:base_type => 'Iterable-Type', :actual => keys[0].class})
408     end
409     Types::PIterableType.new(keys[0])
410   else
411     fail(Issues::BAD_TYPE_SLICE_ARITY, @semantic, {:base_type => 'Iterable-Type', :min => 1, :actual => keys.size})
412   end
413 end
access_PIteratorType(o, scope, keys) click to toggle source
    # File lib/puppet/pops/evaluator/access_operator.rb
415 def access_PIteratorType(o, scope, keys)
416   keys.flatten!
417   if keys.size == 1
418     unless keys[0].is_a?(Types::PAnyType)
419       fail(Issues::BAD_TYPE_SLICE_TYPE, @semantic.keys[0], {:base_type => 'Iterator-Type', :actual => keys[0].class})
420     end
421     Types::PIteratorType.new(keys[0])
422   else
423     fail(Issues::BAD_TYPE_SLICE_ARITY, @semantic, {:base_type => 'Iterator-Type', :min => 1, :actual => keys.size})
424   end
425 end
access_PNotUndefType(o, scope, keys) click to toggle source
    # File lib/puppet/pops/evaluator/access_operator.rb
363 def access_PNotUndefType(o, scope, keys)
364   keys.flatten!
365   case keys.size
366   when 0
367     Types::TypeFactory.not_undef
368   when 1
369     type = keys[0]
370     case type
371     when String
372       type = Types::TypeFactory.string(type)
373     when Types::PAnyType
374       type = nil if type.class == Types::PAnyType
375     else
376       fail(Issues::BAD_NOT_UNDEF_SLICE_TYPE, @semantic.keys[0], {:base_type => 'NotUndef-Type', :actual => type.class})
377     end
378     Types::TypeFactory.not_undef(type)
379   else
380     fail(Issues::BAD_TYPE_SLICE_ARITY, @semantic, {:base_type => 'NotUndef-Type', :min => 0, :max => 1, :actual => keys.size})
381   end
382 end
access_PObjectType(o, scope, keys) click to toggle source
    # File lib/puppet/pops/evaluator/access_operator.rb
341 def access_PObjectType(o, scope, keys)
342   keys.flatten!
343   if o.resolved? && !o.name.nil?
344     Types::PObjectTypeExtension.create(o, keys)
345   else
346     if keys.size == 1
347       Types::TypeFactory.object(keys[0])
348     else
349       fail(Issues::BAD_TYPE_SLICE_ARITY, @semantic, {:base_type => 'Object-Type', :min => 1, :actual => keys.size})
350     end
351   end
352 end
access_POptionalType(o, scope, keys) click to toggle source
    # File lib/puppet/pops/evaluator/access_operator.rb
311 def access_POptionalType(o, scope, keys)
312   keys.flatten!
313   if keys.size == 1
314     type = keys[0]
315     unless type.is_a?(Types::PAnyType)
316       if type.is_a?(String)
317         type = Types::TypeFactory.string(type)
318       else
319         fail(Issues::BAD_TYPE_SLICE_TYPE, @semantic.keys[0], {:base_type => 'Optional-Type', :actual => type.class})
320       end
321     end
322     Types::POptionalType.new(type)
323   else
324     fail(Issues::BAD_TYPE_SLICE_ARITY, @semantic, {:base_type => 'Optional-Type', :min => 1, :actual => keys.size})
325   end
326 end
access_PPatternType(o, scope, keys) click to toggle source
    # File lib/puppet/pops/evaluator/access_operator.rb
292 def access_PPatternType(o, scope, keys)
293   keys.flatten!
294   assert_keys(keys, o, 1, Float::INFINITY, String, Regexp, Types::PPatternType, Types::PRegexpType)
295   Types::TypeFactory.pattern(*keys)
296 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
81 def access_PRegexpType(o, scope, keys)
82   keys.flatten!
83   unless keys.size == 1
84     blamed = keys.size == 0 ? @semantic : @semantic.keys[1]
85     fail(Issues::BAD_TYPE_SLICE_ARITY, blamed, :base_type => o, :min=>1, :actual => keys.size)
86   end
87   assert_keys(keys, o, 1, 1, String, Regexp)
88   Types::TypeFactory.regexp(*keys)
89 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
581 def access_PResourceType(o, scope, keys)
582   blamed = keys.size == 0 ? @semantic : @semantic.keys[0]
583 
584   if keys.size == 0
585     fail(Issues::BAD_TYPE_SLICE_ARITY, blamed,
586       :base_type => o.to_s, :min => 1, :max => -1, :actual => 0)
587   end
588 
589   # Must know which concrete resource type to operate on in all cases.
590   # It is not allowed to specify the type in an array arg - e.g. Resource[[File, 'foo']]
591   # type_name is LHS type_name if set, else the first given arg
592   type_name = o.type_name || Types::TypeFormatter.singleton.capitalize_segments(keys.shift)
593   type_name = case type_name
594   when Types::PResourceType
595     type_name.type_name
596   when String
597     type_name
598   else
599     # blame given left expression if it defined the type, else the first given key expression
600     blame = o.type_name.nil? ? @semantic.keys[0] : @semantic.left_expr
601     fail(Issues::ILLEGAL_RESOURCE_SPECIALIZATION, blame, {:actual => bad_key_type_name(type_name)})
602   end
603 
604   # type name must conform
605   if type_name !~ Patterns::CLASSREF_EXT
606     fail(Issues::ILLEGAL_CLASSREF, blamed, {:name=>type_name})
607   end
608 
609   # The result is an array if multiple titles are given, or if titles are specified with an array
610   # (possibly multiple arrays, and nested arrays).
611   result_type_array = keys.size > 1 || keys[0].is_a?(Array)
612   keys_orig_size = keys.size
613 
614   keys.flatten!
615   keys.compact!
616 
617   # If given keys  that were just a mix of empty/nil with empty array as a result.
618   # As opposed to calling the function the wrong way (without any arguments), (configurable issue),
619   # Return an empty array
620   #
621   if keys.empty? && keys_orig_size > 0
622     optionally_fail(Issues::EMPTY_RESOURCE_SPECIALIZATION, blamed)
623     return result_type_array ? [] : nil
624   end
625 
626   if !o.title.nil?
627     # lookup resource and return one or more parameter values
628     resource = find_resource(scope, o.type_name, o.title)
629     unless resource
630       fail(Issues::UNKNOWN_RESOURCE, @semantic, {:type_name => o.type_name, :title => o.title})
631     end
632 
633     result = keys.map do |k|
634       unless is_parameter_of_resource?(scope, resource, k)
635         fail(Issues::UNKNOWN_RESOURCE_PARAMETER, @semantic,
636           {:type_name => o.type_name, :title => o.title, :param_name=>k})
637       end
638       get_resource_parameter_value(scope, resource, k)
639     end
640     return result_type_array ? result : result.pop
641   end
642 
643 
644   keys = [:no_title] if keys.size < 1 # if there was only a type_name and it was consumed
645   result = keys.each_with_index.map do |t, i|
646     unless t.is_a?(String) || t == :no_title
647       index = keys_orig_size != keys.size ? i+1 : i
648       fail(Issues::BAD_TYPE_SPECIALIZATION, @semantic.keys[index], {
649         :type => o,
650         :message => "Cannot use #{bad_key_type_name(t)} where a resource title String is expected"
651       })
652     end
653 
654     Types::PResourceType.new(type_name, t == :no_title ? nil : t)
655   end
656   # returns single type if request was for a single entity, else an array of types (possibly empty)
657   return result_type_array ? result : result.pop
658 end
access_PRuntimeType(o, scope, keys) click to toggle source
    # File lib/puppet/pops/evaluator/access_operator.rb
427 def access_PRuntimeType(o, scope, keys)
428   keys.flatten!
429   assert_keys(keys, o, 2, 2, String, String)
430   # create runtime type based on runtime and name of class, (not inference of key's type)
431   Types::TypeFactory.runtime(*keys)
432 end
access_PSemVerType(o, scope, keys) click to toggle source
    # File lib/puppet/pops/evaluator/access_operator.rb
176 def access_PSemVerType(o, scope, keys)
177   keys.flatten!
178   assert_keys(keys, o, 1, Float::INFINITY, String, SemanticPuppet::VersionRange)
179   Types::TypeFactory.sem_ver(*keys)
180 end
access_PSensitiveType(o, scope, keys) click to toggle source
    # File lib/puppet/pops/evaluator/access_operator.rb
328 def access_PSensitiveType(o, scope, keys)
329   keys.flatten!
330   if keys.size == 1
331     type = keys[0]
332     unless type.is_a?(Types::PAnyType)
333       fail(Issues::BAD_TYPE_SLICE_TYPE, @semantic.keys[0], {:base_type => 'Sensitive-Type', :actual => type.class})
334     end
335     Types::PSensitiveType.new(type)
336   else
337     fail(Issues::BAD_TYPE_SLICE_ARITY, @semantic, {:base_type => 'Sensitive-Type', :min => 1, :actual => keys.size})
338   end
339 end
access_PStringType(o, scope, keys) click to toggle source
    # File lib/puppet/pops/evaluator/access_operator.rb
224 def access_PStringType(o, scope, keys)
225   keys.flatten!
226   case keys.size
227   when 1
228     size_t = collection_size_t(0, keys[0])
229   when 2
230     size_t = collection_size_t(0, keys[0], keys[1])
231   else
232     fail(Issues::BAD_STRING_SLICE_ARITY, @semantic, {:actual => keys.size})
233   end
234   Types::TypeFactory.string(size_t)
235 end
access_PStructType(o, scope, keys) click to toggle source
    # File lib/puppet/pops/evaluator/access_operator.rb
219 def access_PStructType(o, scope, keys)
220   assert_keys(keys, o, 1, 1, Hash)
221   Types::TypeFactory.struct(keys[0])
222 end
access_PTimespanType(o, scope, keys) click to toggle source
    # File lib/puppet/pops/evaluator/access_operator.rb
188 def access_PTimespanType(o, scope, keys)
189   keys.flatten!
190   fail(Issues::BAD_TYPE_SLICE_ARITY, @semantic, :base_type => o, :min=>0, :max => 2, :actual => keys.size) if keys.size > 2
191   Types::TypeFactory.timespan(*keys)
192 end
access_PTimestampType(o, scope, keys) click to toggle source
    # File lib/puppet/pops/evaluator/access_operator.rb
182 def access_PTimestampType(o, scope, keys)
183   keys.flatten!
184   fail(Issues::BAD_TYPE_SLICE_ARITY, @semantic, :base_type => o, :min=>0, :max => 2, :actual => keys.size) if keys.size > 2
185   Types::TypeFactory.timestamp(*keys)
186 end
access_PTupleType(o, scope, keys) click to toggle source
    # File lib/puppet/pops/evaluator/access_operator.rb
194 def access_PTupleType(o, scope, keys)
195   keys.flatten!
196   if Types::TypeFactory.is_range_parameter?(keys[-2]) && Types::TypeFactory.is_range_parameter?(keys[-1])
197     size_type = Types::TypeFactory.range(keys[-2], keys[-1])
198     keys = keys[0, keys.size - 2]
199   elsif Types::TypeFactory.is_range_parameter?(keys[-1])
200     size_type = Types::TypeFactory.range(keys[-1], :default)
201     keys = keys[0, keys.size - 1]
202   end
203   assert_keys(keys, o, 1, Float::INFINITY, Types::PAnyType)
204   Types::TypeFactory.tuple(keys, size_type)
205 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
565 def access_PTypeReferenceType(o, scope, keys)
566   fail(Issues::UNKNOWN_RESOURCE_TYPE, @semantic, {:type_name => o.type_string })
567 end
access_PTypeSetType(o, scope, keys) click to toggle source
    # File lib/puppet/pops/evaluator/access_operator.rb
354 def access_PTypeSetType(o, scope, keys)
355   keys.flatten!
356   if keys.size == 1
357     Types::TypeFactory.type_set(keys[0])
358   else
359     fail(Issues::BAD_TYPE_SLICE_ARITY, @semantic, {:base_type => 'TypeSet-Type', :min => 1, :actual => keys.size})
360   end
361 end
access_PTypeType(o, scope, keys) click to toggle source
    # File lib/puppet/pops/evaluator/access_operator.rb
384 def access_PTypeType(o, scope, keys)
385   keys.flatten!
386   if keys.size == 1
387     unless keys[0].is_a?(Types::PAnyType)
388       fail(Issues::BAD_TYPE_SLICE_TYPE, @semantic.keys[0], {:base_type => 'Type-Type', :actual => keys[0].class})
389     end
390     Types::PTypeType.new(keys[0])
391   else
392     fail(Issues::BAD_TYPE_SLICE_ARITY, @semantic, {:base_type => 'Type-Type', :min => 1, :actual => keys.size})
393   end
394 end
access_PURIType(o, scope, keys) click to toggle source
    # File lib/puppet/pops/evaluator/access_operator.rb
298 def access_PURIType(o, scope, keys)
299   keys.flatten!
300   if keys.size == 1
301     param = keys[0]
302     unless Types::PURIType::TYPE_URI_PARAM_TYPE.instance?(param)
303       fail(Issues::BAD_TYPE_SLICE_TYPE, @semantic.keys[0], {:base_type => 'URI-Type', :actual => param.class})
304     end
305     Types::PURIType.new(param)
306   else
307     fail(Issues::BAD_TYPE_SLICE_ARITY, @semantic, {:base_type => 'URI-Type', :min => 1, :actual => keys.size})
308   end
309 end
access_PVariantType(o, scope, keys) click to toggle source
    # File lib/puppet/pops/evaluator/access_operator.rb
170 def access_PVariantType(o, scope, keys)
171   keys.flatten!
172   assert_keys(keys, o, 1, Float::INFINITY, Types::PAnyType)
173   Types::TypeFactory.variant(*keys)
174 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
555 def access_Resource(o, scope, keys)
556   # To access a Puppet::Resource as if it was a PResourceType, simply infer it, and take the type of
557   # the parameterized meta type (i.e. Type[Resource[the_resource_type, the_resource_title]])
558   t = Types::TypeCalculator.infer(o).type
559   # must map "undefined title" from resource to nil
560   t.title = nil if t.title == EMPTY_STRING
561   access(t, scope, *keys)
562 end
access_String(o, scope, keys) click to toggle source
   # File lib/puppet/pops/evaluator/access_operator.rb
42 def access_String(o, scope, keys)
43   keys.flatten!
44   result = case keys.size
45   when 0
46     fail(Issues::BAD_STRING_SLICE_ARITY, @semantic.left_expr, {:actual => keys.size})
47   when 1
48     # Note that Ruby 1.8.7 requires a length of 1 to produce a String
49     k1 = Utils.to_n(keys[0])
50     bad_string_access_key_type(o, 0, k1.nil? ? keys[0] : k1) unless k1.is_a?(Integer)
51     k2 = 1
52     k1 = k1 < 0 ? o.length + k1 : k1           # abs pos
53     # if k1 is outside, a length of 1 always produces an empty string
54     if k1 < 0
55       EMPTY_STRING
56     else
57       o[ k1, k2 ]
58     end
59   when 2
60     k1 = Utils.to_n(keys[0])
61     k2 = Utils.to_n(keys[1])
62     [k1, k2].each_with_index { |k,i| bad_string_access_key_type(o, i, k.nil? ? keys[i] : k) unless k.is_a?(Integer) }
63 
64     k1 = k1 < 0 ? o.length + k1 : k1           # abs pos (negative is count from end)
65     k2 = k2 < 0 ? o.length - k1 + k2 + 1 : k2  # abs length (negative k2 is length from pos to end count)
66     # if k1 is outside, adjust to first position, and adjust length
67     if k1 < 0
68       k2 = k2 + k1
69       k1 = 0
70     end
71     o[ k1, k2 ]
72   else
73     fail(Issues::BAD_STRING_SLICE_ARITY, @semantic.left_expr, {:actual => keys.size})
74   end
75   # Specified as: an index outside of range, or empty result == empty string
76   (result.nil? || result.empty?) ? EMPTY_STRING : result
77 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
245 def assert_keys(keys, o, min, max, *allowed_classes)
246   size = keys.size
247   unless size.between?(min, max || Float::INFINITY)
248     fail(Issues::BAD_TYPE_SLICE_ARITY, @semantic, :base_type => o, :min=>1, :max => max, :actual => keys.size)
249   end
250   keys.each_with_index do |k, i|
251     unless allowed_classes.any? {|clazz| k.is_a?(clazz) }
252       bad_type_specialization_key_type(o, i, k, *allowed_classes)
253     end
254   end
255 end
bad_access_key_type(lhs, key_index, actual, *expected_classes) click to toggle source
    # File lib/puppet/pops/evaluator/access_operator.rb
257 def bad_access_key_type(lhs, key_index, actual, *expected_classes)
258   fail(Issues::BAD_SLICE_KEY_TYPE, @semantic.keys[key_index], {
259     :left_value => lhs,
260     :actual => bad_key_type_name(actual),
261     :expected_classes => expected_classes
262   })
263 end
bad_key_type_name(actual) click to toggle source
    # File lib/puppet/pops/evaluator/access_operator.rb
272 def bad_key_type_name(actual)
273   case actual
274   when nil
275     'Undef'
276   when :default
277     'Default'
278   else
279     Types::TypeCalculator.generalize(Types::TypeCalculator.infer(actual)).to_s
280   end
281 end
bad_string_access_key_type(lhs, key_index, actual) click to toggle source
    # File lib/puppet/pops/evaluator/access_operator.rb
265 def bad_string_access_key_type(lhs, key_index, actual)
266   fail(Issues::BAD_STRING_SLICE_KEY_TYPE, @semantic.keys[key_index], {
267     :left_value => lhs,
268     :actual_type => bad_key_type_name(actual),
269   })
270 end
bad_type_specialization_key_type(type, key_index, actual, *expected_classes) click to toggle source
    # File lib/puppet/pops/evaluator/access_operator.rb
283 def bad_type_specialization_key_type(type, key_index, actual, *expected_classes)
284   label_provider = Model::ModelLabelProvider.new()
285   expected = expected_classes.map {|c| label_provider.label(c) }.join(' or ')
286   fail(Issues::BAD_TYPE_SPECIALIZATION, @semantic.keys[key_index], {
287     :type => type,
288     :message => _("Cannot use %{key} where %{expected} is expected") % { key: bad_key_type_name(actual), expected: expected }
289   })
290 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
541 def collection_size_t(start_index, *keys)
542   if keys.size == 1 && keys[0].is_a?(Types::PIntegerType)
543     keys[0]
544   else
545     keys.each_with_index do |x, index|
546       fail(Issues::BAD_COLLECTION_SLICE_TYPE, @semantic.keys[start_index + index],
547         {:actual => x.class}) unless (x.is_a?(Integer) || x == :default)
548     end
549     Types::PIntegerType.new(*keys)
550   end
551 end