class Puppet::Pops::Evaluator::AccessOperator
AccessOperator handles operator [] This operator is part of evaluation.
Constants
- NS
Attributes
Public Class Methods
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
# 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
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
# 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
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
# 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
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
# 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
# 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
# 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
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
# 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
# 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
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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
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
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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
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
# 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
# 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
# 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
# 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
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
# 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
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
# 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
# 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
# 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
# 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
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