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

DEFAULT =
PVariantType.new(EMPTY_ARRAY)

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Enumerable

#uniq

Methods inherited from PAnyType

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

Methods inherited from TypedModelObject

_pcore_type, create_ptype, register_ptypes

Methods included from PuppetObject

#_pcore_all_contents, #_pcore_contents, #_pcore_init_hash, #_pcore_type

Constructor Details

#initialize(types) ⇒ PVariantType

Returns a new instance of PVariantType.

Parameters:

  • types (Array[PAnyType])

    the variants



2814
2815
2816
# File 'lib/puppet/pops/types/types.rb', line 2814

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

Instance Attribute Details

#typesObject (readonly)



2799
2800
2801
# File 'lib/puppet/pops/types/types.rb', line 2799

def types
  @types
end

Class Method Details

.flatten_variants(types) ⇒ Object



2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
# File 'lib/puppet/pops/types/types.rb', line 2880

def self.flatten_variants(types)
  modified = false
  types = types.map do |t|
    if t.is_a?(PVariantType)
      modified = true
      t.types
    else
      t
    end
  end
  types.flatten! if modified
  types
end

.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:

  • types (Array<PAnyType>)

    the variants

Returns:



2808
2809
2810
2811
# File 'lib/puppet/pops/types/types.rb', line 2808

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

.register_ptype(loader, ir) ⇒ Object



2795
2796
2797
# File 'lib/puppet/pops/types/types.rb', line 2795

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

Instance Method Details

#accept(visitor, guard) ⇒ Object



2818
2819
2820
2821
# File 'lib/puppet/pops/types/types.rb', line 2818

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

#eachObject



2823
2824
2825
2826
2827
2828
2829
# File 'lib/puppet/pops/types/types.rb', line 2823

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

#eql?(o) ⇒ Boolean

Returns:

  • (Boolean)


2915
2916
2917
# File 'lib/puppet/pops/types/types.rb', line 2915

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

#generalizeObject



2831
2832
2833
2834
2835
2836
2837
# File 'lib/puppet/pops/types/types.rb', line 2831

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

#hashObject



2894
2895
2896
# File 'lib/puppet/pops/types/types.rb', line 2894

def hash
  @types.hash
end

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

Returns:

  • (Boolean)


2898
2899
2900
2901
# File 'lib/puppet/pops/types/types.rb', line 2898

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)


2911
2912
2913
# File 'lib/puppet/pops/types/types.rb', line 2911

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

#normalize(guard = nil) ⇒ Object



2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
# File 'lib/puppet/pops/types/types.rb', line 2839

def normalize(guard = nil)
  if self == DEFAULT || @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) || t.is_a?(POptionalType) }
      # Undef entry present. Use an OptionalType with a normalized Variant without Undefs and Optional wrappers
      POptionalType.new(PVariantType.maybe_create(types.reject { |t| t.is_a?(PUndefType) }.map { |t| t.is_a?(POptionalType) ? t.type : t })).normalize
    else
      # Merge all variants into this one
      types = PVariantType.flatten_variants(types)
      size_before_merge = types.size

      types = swap_not_undefs(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)


2903
2904
2905
2906
2907
2908
2909
# File 'lib/puppet/pops/types/types.rb', line 2903

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