Class: Puppet::Pops::Types::PVariantType

Inherits:
PAnyType show all
Includes:
Enumerable
Defined in:
lib/puppet/pops/types/types.rb

Overview

A flexible type describing an any? of other types

Constant Summary collapse

DATA =

Variant compatible with the Data type.

PVariantType.new([PHashType::DATA, PArrayType::DATA, PScalarType::DEFAULT, PUndefType::DEFAULT, PTupleType::DATA])
DEFAULT =
PVariantType.new(EMPTY_ARRAY)

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from PAnyType

#==, #assignable?, #callable?, #callable_args?, #check_self_recursion, #iterable?, #iterable_type, #name, new_function, #new_function, #resolve, #simple_name, simple_name, #to_alias_expanded_s, #to_s

Methods inherited from TypedModelObject

_ptype, create_ptype, register_ptypes

Methods included from PuppetObject

#_ptype

Constructor Details

#initialize(types) ⇒ PVariantType

Returns a new instance of PVariantType.

Parameters:



2538
2539
2540
# File 'lib/puppet/pops/types/types.rb', line 2538

def initialize(types)
  @types = types.freeze
end

Instance Attribute Details

#typesObject (readonly)



2523
2524
2525
# File 'lib/puppet/pops/types/types.rb', line 2523

def types
  @types
end

Class Method Details

.maybe_create(types) ⇒ PAnyType

Checks if the number of unique types in the given array is greater than one, and if so creates a Variant with those types and returns it. If only one unique type is found, that type is instead returned.

Parameters:

Returns:



2532
2533
2534
2535
# File 'lib/puppet/pops/types/types.rb', line 2532

def self.maybe_create(types)
  types = types.uniq
  types.size == 1 ? types[0] : new(types)
end

.register_ptype(loader, ir) ⇒ Object



2519
2520
2521
# File 'lib/puppet/pops/types/types.rb', line 2519

def self.register_ptype(loader, ir)
  create_ptype(loader, ir, 'AnyType', 'types' => PArrayType.new(PType::DEFAULT))
end

Instance Method Details

#accept(visitor, guard) ⇒ Object



2542
2543
2544
2545
# File 'lib/puppet/pops/types/types.rb', line 2542

def accept(visitor, guard)
  super
  @types.each { |t| t.accept(visitor, guard) }
end

#eachObject



2547
2548
2549
2550
2551
2552
2553
# File 'lib/puppet/pops/types/types.rb', line 2547

def each
  if block_given?
    types.each { |t| yield t }
  else
    types.to_enum
  end
end

#eql?(o) ⇒ Boolean

Returns:

  • (Boolean)


2638
2639
2640
2641
# File 'lib/puppet/pops/types/types.rb', line 2638

def eql?(o)
  o = DATA if o.is_a?(PDataType)
  self.class == o.class && @types.size == o.types.size && (@types - o.types).empty?
end

#generalizeObject



2555
2556
2557
2558
2559
2560
2561
# File 'lib/puppet/pops/types/types.rb', line 2555

def generalize
  if self == DEFAULT || self == DATA
    self
  else
    alter_type_array(@types, :generalize) { |altered| PVariantType.maybe_create(altered) }
  end
end

#hashObject



2613
2614
2615
# File 'lib/puppet/pops/types/types.rb', line 2613

def hash
  @types.hash
end

#instance?(o, guard = nil) ⇒ Boolean

Returns:

  • (Boolean)


2617
2618
2619
2620
# File 'lib/puppet/pops/types/types.rb', line 2617

def instance?(o, guard = nil)
  # instance of variant if o is instance? of any of variant's types
  @types.any? { |type| type.instance?(o, guard) }
end

#kind_of_callable?(optional = true, guard = nil) ⇒ Boolean

Returns:

  • (Boolean)


2630
2631
2632
# File 'lib/puppet/pops/types/types.rb', line 2630

def kind_of_callable?(optional = true, guard = nil)
  @types.all? { |type| type.kind_of_callable?(optional, guard) }
end

#normalize(guard = nil) ⇒ Object



2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
# File 'lib/puppet/pops/types/types.rb', line 2563

def normalize(guard = nil)
  if self == DEFAULT || self == DATA || @types.empty?
    self
  else
    # Normalize all contained types
    modified = false
    types = alter_type_array(@types, :normalize, guard)
    if types == self
      types = @types
    else
      modified = true
    end

    if types.size == 1
      types[0]
    elsif types.any? { |t| t.is_a?(PUndefType) }
      # Undef entry present. Use an OptionalType with a normalized Variant of all types that are not Undef
      POptionalType.new(PVariantType.maybe_create(types.reject { |ot| ot.is_a?(PUndefType) }).normalize(guard)).normalize(guard)
    else
      # Merge all variants into this one
      types = types.map do |t|
        if t.is_a?(PVariantType)
          modified = true
          t.types
        else
          t
        end
      end
      types.flatten! if modified
      size_before_merge = types.size

      types = swap_not_undefs(types)
      types = swap_optionals(types)
      types = merge_enums(types)
      types = merge_patterns(types)
      types = merge_version_ranges(types)
      types = merge_numbers(PIntegerType, types)
      types = merge_numbers(PFloatType, types)
      types = merge_numbers(PTimespanType, types)
      types = merge_numbers(PTimestampType, types)

      if types.size == 1
        types[0]
      else
        modified || types.size != size_before_merge ? PVariantType.maybe_create(types) : self
      end
    end
  end
end

#really_instance?(o, guard = nil) ⇒ Boolean

Returns:

  • (Boolean)


2622
2623
2624
2625
2626
2627
2628
# File 'lib/puppet/pops/types/types.rb', line 2622

def really_instance?(o, guard = nil)
  @types.inject(-1) do |memo, type|
    ri = type.really_instance?(o, guard)
    memo = ri if ri > memo
    memo
  end
end

#resolved?Boolean

Returns:

  • (Boolean)


2634
2635
2636
# File 'lib/puppet/pops/types/types.rb', line 2634

def resolved?
  @types.all? { |type| type.resolved? }
end