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, #create, #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.



2628
2629
2630
# File 'lib/puppet/pops/types/types.rb', line 2628

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

Instance Attribute Details

#typesObject (readonly)



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

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.



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

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

.register_ptype(loader, ir) ⇒ Object



2609
2610
2611
# File 'lib/puppet/pops/types/types.rb', line 2609

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

Instance Method Details

#accept(visitor, guard) ⇒ Object



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

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

#eachObject



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

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

#eql?(o) ⇒ Boolean



2728
2729
2730
2731
# File 'lib/puppet/pops/types/types.rb', line 2728

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



2645
2646
2647
2648
2649
2650
2651
# File 'lib/puppet/pops/types/types.rb', line 2645

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

#hashObject



2703
2704
2705
# File 'lib/puppet/pops/types/types.rb', line 2703

def hash
  @types.hash
end

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



2707
2708
2709
2710
# File 'lib/puppet/pops/types/types.rb', line 2707

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



2720
2721
2722
# File 'lib/puppet/pops/types/types.rb', line 2720

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

#normalize(guard = nil) ⇒ Object



2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
# File 'lib/puppet/pops/types/types.rb', line 2653

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



2712
2713
2714
2715
2716
2717
2718
# File 'lib/puppet/pops/types/types.rb', line 2712

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



2724
2725
2726
# File 'lib/puppet/pops/types/types.rb', line 2724

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