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?, #callable_with?, #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.

Parameters:



2692
2693
2694
# File 'lib/puppet/pops/types/types.rb', line 2692

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

Instance Attribute Details

#typesObject (readonly)



2677
2678
2679
# File 'lib/puppet/pops/types/types.rb', line 2677

def types
  @types
end

Class Method Details

.flatten_variants(types) ⇒ Object



2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
# File 'lib/puppet/pops/types/types.rb', line 2758

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:

Returns:



2686
2687
2688
2689
# File 'lib/puppet/pops/types/types.rb', line 2686

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

.register_ptype(loader, ir) ⇒ Object



2673
2674
2675
# File 'lib/puppet/pops/types/types.rb', line 2673

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

Instance Method Details

#accept(visitor, guard) ⇒ Object



2696
2697
2698
2699
# File 'lib/puppet/pops/types/types.rb', line 2696

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

#eachObject



2701
2702
2703
2704
2705
2706
2707
# File 'lib/puppet/pops/types/types.rb', line 2701

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

#eql?(o) ⇒ Boolean

Returns:

  • (Boolean)


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

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



2709
2710
2711
2712
2713
2714
2715
# File 'lib/puppet/pops/types/types.rb', line 2709

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

#hashObject



2772
2773
2774
# File 'lib/puppet/pops/types/types.rb', line 2772

def hash
  @types.hash
end

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

Returns:

  • (Boolean)


2776
2777
2778
2779
# File 'lib/puppet/pops/types/types.rb', line 2776

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)


2788
2789
2790
# File 'lib/puppet/pops/types/types.rb', line 2788

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

#normalize(guard = nil) ⇒ Object



2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
# File 'lib/puppet/pops/types/types.rb', line 2717

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) || 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)


2781
2782
2783
2784
2785
2786
# File 'lib/puppet/pops/types/types.rb', line 2781

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

#resolved?Boolean

Returns:

  • (Boolean)


2792
2793
2794
# File 'lib/puppet/pops/types/types.rb', line 2792

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