class Puppet::Pops::Types::TypeMismatchDescriber

@api private

Public Class Methods

describe_signatures(closure, signatures, args_tuple) click to toggle source
    # File lib/puppet/pops/types/type_mismatch_describer.rb
507 def self.describe_signatures(closure, signatures, args_tuple)
508   singleton.describe_signatures(closure, signatures, args_tuple)
509 end
singleton() click to toggle source
    # File lib/puppet/pops/types/type_mismatch_describer.rb
511 def self.singleton
512   @singleton ||= new
513 end
validate_default_parameter(subject, param_name, param_type, value) click to toggle source
    # File lib/puppet/pops/types/type_mismatch_describer.rb
503 def self.validate_default_parameter(subject, param_name, param_type, value)
504   singleton.validate_default_parameter(subject, param_name, param_type, value)
505 end
validate_parameters(subject, params_struct, given_hash, missing_ok = false) click to toggle source
    # File lib/puppet/pops/types/type_mismatch_describer.rb
499 def self.validate_parameters(subject, params_struct, given_hash, missing_ok = false)
500   singleton.validate_parameters(subject, params_struct, given_hash, missing_ok)
501 end

Public Instance Methods

describe(expected, actual, path) click to toggle source
     # File lib/puppet/pops/types/type_mismatch_describer.rb
 991 def describe(expected, actual, path)
 992   ures_finder = UnresolvedTypeFinder.new
 993   expected.accept(ures_finder, nil)
 994   unresolved = ures_finder.unresolved
 995   if unresolved
 996     [UnresolvedTypeReference.new(path, unresolved)]
 997   else
 998     internal_describe(expected.normalize, expected, actual, path)
 999   end
1000 end
describe_PAnyType(expected, original, actual, path) click to toggle source
    # File lib/puppet/pops/types/type_mismatch_describer.rb
971 def describe_PAnyType(expected, original, actual, path)
972   expected.assignable?(actual) ? EMPTY_ARRAY : [TypeMismatch.new(path, original, actual)]
973 end
describe_PArrayType(expected, original, actual, path) click to toggle source
    # File lib/puppet/pops/types/type_mismatch_describer.rb
794 def describe_PArrayType(expected, original, actual, path)
795   descriptions = []
796   element_type = expected.element_type || PAnyType::DEFAULT
797   if actual.is_a?(PTupleType)
798     types = actual.types
799     expected_size = expected.size_type || PCollectionType::DEFAULT_SIZE
800     actual_size = actual.size_type || PIntegerType.new(types.size, types.size)
801     if expected_size.assignable?(actual_size)
802       types.each_with_index do |type, idx|
803         descriptions.concat(describe(element_type, type, path + [ArrayPathElement.new(idx)])) unless element_type.assignable?(type)
804       end
805     else
806       descriptions << SizeMismatch.new(path, expected_size, actual_size)
807     end
808   elsif actual.is_a?(PArrayType)
809     expected_size = expected.size_type
810     actual_size = actual.size_type || PCollectionType::DEFAULT_SIZE
811     if expected_size.nil? || expected_size.assignable?(actual_size)
812       descriptions << TypeMismatch.new(path, original, PArrayType.new(actual.element_type))
813     else
814       descriptions << SizeMismatch.new(path, expected_size, actual_size)
815     end
816   else
817     descriptions << TypeMismatch.new(path, original, actual)
818   end
819   descriptions
820 end
describe_PCallableType(expected, original, actual, path) click to toggle source
    # File lib/puppet/pops/types/type_mismatch_describer.rb
937 def describe_PCallableType(expected, original, actual, path)
938   if actual.is_a?(PCallableType)
939     # nil param_types means, any other Callable is assignable
940     if expected.param_types.nil? && expected.return_type.nil?
941       EMPTY_ARRAY
942     else
943       # NOTE: these tests are made in reverse as it is calling the callable that is constrained
944       # (it's lower bound), not its upper bound
945       param_errors = describe_argument_tuple(expected.param_types, actual.param_types, path)
946       if param_errors.empty?
947         this_return_t = expected.return_type || PAnyType::DEFAULT
948         that_return_t = actual.return_type || PAnyType::DEFAULT
949         unless this_return_t.assignable?(that_return_t)
950           [TypeMismatch.new(path + [ReturnTypeElement.new], this_return_t, that_return_t)]
951         else
952           # names are ignored, they are just information
953           # Blocks must be compatible
954           this_block_t = expected.block_type || PUndefType::DEFAULT
955           that_block_t = actual.block_type || PUndefType::DEFAULT
956           if that_block_t.assignable?(this_block_t)
957             EMPTY_ARRAY
958           else
959             [TypeMismatch.new(path + [BlockPathElement.new], this_block_t, that_block_t)]
960           end
961         end
962       else
963         param_errors
964       end
965     end
966   else
967     [TypeMismatch.new(path, original, actual)]
968   end
969 end
describe_PEnumType(expected, original, actual, path) click to toggle source
    # File lib/puppet/pops/types/type_mismatch_describer.rb
782 def describe_PEnumType(expected, original, actual, path)
783   [PatternMismatch.new(path, original, actual)]
784 end
describe_PHashType(expected, original, actual, path) click to toggle source
    # File lib/puppet/pops/types/type_mismatch_describer.rb
822 def describe_PHashType(expected, original, actual, path)
823   descriptions = []
824   key_type = expected.key_type || PAnyType::DEFAULT
825   value_type = expected.value_type || PAnyType::DEFAULT
826   if actual.is_a?(PStructType)
827     elements = actual.elements
828     expected_size = expected.size_type || PCollectionType::DEFAULT_SIZE
829     actual_size = PIntegerType.new(elements.count { |a| !a.key_type.assignable?(PUndefType::DEFAULT) }, elements.size)
830     if expected_size.assignable?(actual_size)
831       elements.each do |a|
832         descriptions.concat(describe(key_type, a.key_type, path + [EntryKeyPathElement.new(a.name)])) unless key_type.assignable?(a.key_type)
833         descriptions.concat(describe(value_type, a.value_type, path + [EntryValuePathElement.new(a.name)])) unless value_type.assignable?(a.value_type)
834       end
835     else
836       descriptions << SizeMismatch.new(path, expected_size, actual_size)
837     end
838   elsif actual.is_a?(PHashType)
839     expected_size = expected.size_type
840     actual_size = actual.size_type || PCollectionType::DEFAULT_SIZE
841     if expected_size.nil? || expected_size.assignable?(actual_size)
842       descriptions << TypeMismatch.new(path, original, PHashType.new(actual.key_type, actual.value_type))
843     else
844       descriptions << SizeMismatch.new(path, expected_size, actual_size)
845     end
846   else
847     descriptions << TypeMismatch.new(path, original, actual)
848   end
849   descriptions
850 end
describe_POptionalType(expected, original, actual, path) click to toggle source
    # File lib/puppet/pops/types/type_mismatch_describer.rb
777 def describe_POptionalType(expected, original, actual, path)
778   return EMPTY_ARRAY if actual.is_a?(PUndefType) || expected.optional_type.nil?
779   internal_describe(expected.optional_type, original.is_a?(PTypeAliasType) ? original : expected, actual, path)
780 end
describe_PPatternType(expected, original, actual, path) click to toggle source
    # File lib/puppet/pops/types/type_mismatch_describer.rb
786 def describe_PPatternType(expected, original, actual, path)
787   [PatternMismatch.new(path, original, actual)]
788 end
describe_PStructType(expected, original, actual, path) click to toggle source
    # File lib/puppet/pops/types/type_mismatch_describer.rb
852 def describe_PStructType(expected, original, actual, path)
853   elements = expected.elements
854   descriptions = []
855   if actual.is_a?(PStructType)
856     h2 = actual.hashed_elements.clone
857     elements.each do |e1|
858       key = e1.name
859       e2 = h2.delete(key)
860       if e2.nil?
861         descriptions << MissingKey.new(path, key) unless e1.key_type.assignable?(PUndefType::DEFAULT)
862       else
863         descriptions.concat(describe(e1.key_type, e2.key_type, path + [EntryKeyPathElement.new(key)])) unless e1.key_type.assignable?(e2.key_type)
864         descriptions.concat(describe(e1.value_type, e2.value_type, path + [EntryValuePathElement.new(key)])) unless e1.value_type.assignable?(e2.value_type)
865       end
866     end
867     h2.each_key { |key| descriptions << ExtraneousKey.new(path, key) }
868   elsif actual.is_a?(PHashType)
869     actual_size = actual.size_type || PCollectionType::DEFAULT_SIZE
870     expected_size = PIntegerType.new(elements.count { |e| !e.key_type.assignable?(PUndefType::DEFAULT) }, elements.size)
871     if expected_size.assignable?(actual_size)
872       descriptions << TypeMismatch.new(path, original, PHashType.new(actual.key_type, actual.value_type))
873     else
874       descriptions << SizeMismatch.new(path, expected_size, actual_size)
875     end
876   else
877     descriptions << TypeMismatch.new(path, original, actual)
878   end
879   descriptions
880 end
describe_PTupleType(expected, original, actual, path) click to toggle source
    # File lib/puppet/pops/types/type_mismatch_describer.rb
882 def describe_PTupleType(expected, original, actual, path)
883   describe_tuple(expected, original, actual, path, SizeMismatch)
884 end
describe_PTypeAliasType(expected, original, actual, path) click to toggle source
    # File lib/puppet/pops/types/type_mismatch_describer.rb
790 def describe_PTypeAliasType(expected, original, actual, path)
791   internal_describe(expected.resolved_type.normalize, expected, actual, path)
792 end
describe_PVariantType(expected, original, actual, path) click to toggle source
    # File lib/puppet/pops/types/type_mismatch_describer.rb
737 def describe_PVariantType(expected, original, actual, path)
738   variant_descriptions = []
739   types = expected.types
740   types = [PUndefType::DEFAULT] + types if original.is_a?(POptionalType)
741   types.each_with_index do |vt, index|
742     d = describe(vt, actual, path + [VariantPathElement.new(index)])
743     return EMPTY_ARRAY if d.empty?
744     variant_descriptions << d
745   end
746   descriptions = merge_descriptions(path.length, SizeMismatch, variant_descriptions)
747   if original.is_a?(PTypeAliasType) && descriptions.size == 1
748     # All variants failed in this alias so we report it as a mismatch on the alias
749     # rather than reporting individual failures of the variants
750     [TypeMismatch.new(path, original, actual)]
751   else
752     descriptions
753   end
754 end
describe_argument_tuple(expected, actual, path) click to toggle source
    # File lib/puppet/pops/types/type_mismatch_describer.rb
886 def describe_argument_tuple(expected, actual, path)
887   describe_tuple(expected, expected, actual, path, CountMismatch)
888 end
describe_mismatch(name, expected, actual, tense = :ignored) click to toggle source

Describe a confirmed mismatch using present tense

@param name [String] name of mismatch @param expected [PAnyType] expected type @param actual [PAnyType] actual type @param tense [Symbol] deprecated and ignored

    # File lib/puppet/pops/types/type_mismatch_describer.rb
551 def describe_mismatch(name, expected, actual, tense = :ignored)
552   tense_deprecated unless tense == :ignored
553   errors = describe(expected, actual, [SubjectPathElement.new(name)])
554   case errors.size
555   when 0
556     ''
557   when 1
558     errors[0].format.strip
559   else
560     errors.map { |error| error.format }.join("\n ")
561   end
562 end
describe_no_block_arguments(signature, atypes, path, expected_size, actual_size, arg_count) click to toggle source
    # File lib/puppet/pops/types/type_mismatch_describer.rb
718 def describe_no_block_arguments(signature, atypes, path, expected_size, actual_size, arg_count)
719   # not assignable if the number of types in actual is outside number of types in expected
720   if expected_size.assignable?(actual_size)
721     etypes = signature.type.param_types.types
722     enames = signature.parameter_names
723     arg_count.times do |index|
724       adx = index >= etypes.size ? etypes.size - 1 : index
725       etype = etypes[adx]
726       unless etype.assignable?(atypes[index])
727         descriptions = describe(etype, atypes[index], path + [ParameterPathElement.new(enames[adx])])
728         return descriptions unless descriptions.empty?
729       end
730     end
731     EMPTY_ARRAY
732   else
733     [CountMismatch.new(path, expected_size, actual_size)]
734   end
735 end
describe_signature_arguments(signature, args_tuple, path) click to toggle source
    # File lib/puppet/pops/types/type_mismatch_describer.rb
675 def describe_signature_arguments(signature, args_tuple, path)
676   params_tuple = signature.type.param_types
677   params_size_t = params_tuple.size_type || TypeFactory.range(*params_tuple.size_range)
678 
679   if args_tuple.is_a?(PTupleType)
680     arg_types = args_tuple.types
681   elsif args_tuple.is_a?(PArrayType)
682     arg_types = Array.new(params_tuple.types.size, args_tuple.element_type || PUndefType::DEFAULT)
683   else
684     return [TypeMismatch.new(path, params_tuple, args_tuple)]
685   end
686 
687   if arg_types.last.kind_of_callable?
688     # Check other arguments
689     arg_count = arg_types.size - 1
690     describe_no_block_arguments(signature, arg_types, path, params_size_t, TypeFactory.range(arg_count, arg_count), arg_count)
691   else
692     args_size_t = TypeFactory.range(*args_tuple.size_range)
693     describe_no_block_arguments(signature, arg_types, path, params_size_t, args_size_t, arg_types.size)
694   end
695 end
describe_signature_block(signature, args_tuple, path) click to toggle source
    # File lib/puppet/pops/types/type_mismatch_describer.rb
697 def describe_signature_block(signature, args_tuple, path)
698   param_block_t = signature.block_type
699   arg_block_t = args_tuple.is_a?(PTupleType) ? args_tuple.types.last : nil
700   if TypeCalculator.is_kind_of_callable?(arg_block_t)
701     # Can't pass a block to a callable that doesn't accept one
702     if param_block_t.nil?
703       [UnexpectedBlock.new(path)]
704     else
705       # Check that the block is of the right type
706       describe(param_block_t, arg_block_t, path + [BlockPathElement.new])
707     end
708   else
709     # Check that the block is optional
710     if param_block_t.nil? || param_block_t.assignable?(PUndefType::DEFAULT)
711       EMPTY_ARRAY
712     else
713       [MissingRequiredBlock.new(path)]
714     end
715   end
716 end
describe_signatures(closure, signatures, args_tuple, tense = :ignored) click to toggle source
    # File lib/puppet/pops/types/type_mismatch_describer.rb
631 def describe_signatures(closure, signatures, args_tuple, tense = :ignored)
632   tense_deprecated unless tense == :ignored
633   error_arrays = []
634   signatures.each_with_index do |signature, index|
635     error_arrays << describe_signature_arguments(signature, args_tuple, [SignaturePathElement.new(index)])
636   end
637 
638   # Skip block checks if all signatures have argument errors
639   unless error_arrays.all? { |a| !a.empty? }
640     block_arrays = []
641     signatures.each_with_index do |signature, index|
642       block_arrays << describe_signature_block(signature, args_tuple, [SignaturePathElement.new(index)])
643     end
644     bc_count = block_arrays.count { |a| !a.empty? }
645     if bc_count == block_arrays.size
646       # Skip argument errors when all alternatives have block errors
647       error_arrays = block_arrays
648     elsif bc_count > 0
649       # Merge errors giving argument errors precedence over block errors
650       error_arrays.each_with_index { |a, index| error_arrays[index] = block_arrays[index] if a.empty? }
651     end
652   end
653   return nil if error_arrays.empty?
654 
655   label = closure == 'lambda' ? 'block' : "'#{closure}'"
656   errors = merge_descriptions(0, CountMismatch, error_arrays)
657   if errors.size == 1
658     "#{label}#{errors[0].format}"
659   else
660     if signatures.size == 1
661       sig = signatures[0]
662       result = ["#{label} expects (#{signature_string(sig)})"]
663       result.concat(error_arrays[0].map { |e| "  rejected:#{e.chop_path(0).format}" })
664     else
665       result = ["The function #{label} was called with arguments it does not accept. It expects one of:"]
666       signatures.each_with_index do |sg, index|
667         result << "  (#{signature_string(sg)})"
668         result.concat(error_arrays[index].map { |e| "    rejected:#{e.chop_path(0).format}" })
669       end
670     end
671     result.join("\n")
672   end
673 end
describe_struct_signature(params_struct, param_hash, missing_ok = false) click to toggle source

Validates that all entries in the param_hash exists in the given param_struct, that their type conforms with the corresponding param_struct element and that all required values are provided. An error message is created for each problem found.

@param params_struct [PStructType] Struct to use for validation @param param_hash [Hash<String,Object>] The parameters to validate @param missing_ok [Boolean] Do not generate errors on missing parameters @return [Array<Mismatch>] An array of found errors. An empty array indicates no errors.

    # File lib/puppet/pops/types/type_mismatch_describer.rb
602 def describe_struct_signature(params_struct, param_hash, missing_ok = false)
603   param_type_hash = params_struct.hashed_elements
604   result =  param_hash.each_key.reject { |name| param_type_hash.include?(name) }.map { |name| InvalidParameter.new(nil, name) }
605 
606   params_struct.elements.each do |elem|
607     name = elem.name
608     value = param_hash[name]
609     value_type = elem.value_type
610     if param_hash.include?(name)
611       if Puppet::Pops::Types::TypeFactory.deferred.implementation_class == value.class
612         if (df_return_type = get_deferred_function_return_type(value))
613           result << describe(value_type, df_return_type, [ParameterPathElement.new(name)]) unless value_type.generalize.assignable?(df_return_type.generalize)
614         else
615           warning_text = _("Deferred function %{function_name} has no return_type, unable to guarantee value type during compilation.") %
616                          {function_name: value.name }
617           Puppet.warn_once('deprecations',
618                            "#{value.name}_deferred_warning",
619                            warning_text)
620         end
621       else
622         result << describe(value_type, TypeCalculator.singleton.infer_set(value), [ParameterPathElement.new(name)]) unless value_type.instance?(value)
623       end
624     else
625       result << MissingParameter.new(nil, name) unless missing_ok || elem.key_type.is_a?(POptionalType)
626     end
627   end
628   result
629 end
describe_tuple(expected, original, actual, path, size_mismatch_class) click to toggle source
    # File lib/puppet/pops/types/type_mismatch_describer.rb
890 def describe_tuple(expected, original, actual, path, size_mismatch_class)
891   return EMPTY_ARRAY if expected == actual || expected.types.empty? && (actual.is_a?(PArrayType))
892   expected_size = expected.size_type || TypeFactory.range(*expected.size_range)
893 
894   if actual.is_a?(PTupleType)
895     actual_size = actual.size_type || TypeFactory.range(*actual.size_range)
896 
897     # not assignable if the number of types in actual is outside number of types in expected
898     if expected_size.assignable?(actual_size)
899       etypes = expected.types
900       descriptions = []
901       unless etypes.empty?
902         actual.types.each_with_index do |atype, index|
903           adx = index >= etypes.size ? etypes.size - 1 : index
904           descriptions.concat(describe(etypes[adx], atype, path + [ArrayPathElement.new(adx)]))
905         end
906       end
907       descriptions
908     else
909       [size_mismatch_class.new(path, expected_size, actual_size)]
910     end
911   elsif actual.is_a?(PArrayType)
912     t2_entry = actual.element_type
913 
914     if t2_entry.nil?
915       # Array of anything can not be assigned (unless tuple is tuple of anything) - this case
916       # was handled at the top of this method.
917       #
918       [TypeMismatch.new(path, original, actual)]
919     else
920       expected_size = expected.size_type || TypeFactory.range(*expected.size_range)
921       actual_size = actual.size_type || PCollectionType::DEFAULT_SIZE
922       if expected_size.assignable?(actual_size)
923         descriptions = []
924         expected.types.each_with_index do |etype, index|
925           descriptions.concat(describe(etype, actual.element_type, path + [ArrayPathElement.new(index)]))
926         end
927         descriptions
928       else
929         [size_mismatch_class.new(path, expected_size, actual_size)]
930       end
931     end
932   else
933     [TypeMismatch.new(path, original, actual)]
934   end
935 end
max(a, b) click to toggle source

Why oh why Ruby do you not have a standard Math.max ? @api private

     # File lib/puppet/pops/types/type_mismatch_describer.rb
1086 def max(a, b)
1087   a >= b ? a : b
1088 end
merge_descriptions(varying_path_position, size_mismatch_class, variant_descriptions) click to toggle source
    # File lib/puppet/pops/types/type_mismatch_describer.rb
756 def merge_descriptions(varying_path_position, size_mismatch_class, variant_descriptions)
757   descriptions = variant_descriptions.flatten
758   [size_mismatch_class, MissingRequiredBlock, UnexpectedBlock, TypeMismatch].each do |mismatch_class|
759     mismatches = descriptions.select { |desc| desc.is_a?(mismatch_class) }
760     if mismatches.size == variant_descriptions.size
761       # If they all have the same canonical path, then we can compact this into one
762       generic_mismatch = mismatches.inject do |prev, curr|
763         break nil unless prev.canonical_path == curr.canonical_path
764         prev.merge(prev.path, curr)
765       end
766       unless generic_mismatch.nil?
767         # Report the generic mismatch and skip the rest
768         descriptions = [generic_mismatch]
769         break
770       end
771     end
772   end
773   descriptions = descriptions.uniq
774   descriptions.size == 1 ? [descriptions[0].chop_path(varying_path_position)] : descriptions
775 end
optional(index, required_count) click to toggle source

@api private

     # File lib/puppet/pops/types/type_mismatch_describer.rb
1091 def optional(index, required_count)
1092   count = index + 1
1093   count > required_count
1094 end
signature_string(signature) click to toggle source

Produces a string for the signature(s)

@api private

     # File lib/puppet/pops/types/type_mismatch_describer.rb
1033 def signature_string(signature)
1034   param_types = signature.type.param_types
1035   param_names = signature.parameter_names
1036 
1037   from, to = param_types.size_range
1038   if from == 0 && to == 0
1039     # No parameters function
1040     return ''
1041   end
1042 
1043   required_count = from
1044   types =
1045     case param_types
1046     when PTupleType
1047       param_types.types
1048     when PArrayType
1049       [param_types.element_type]
1050     end
1051 
1052   # join type with names (types are always present, names are optional)
1053   # separate entries with comma
1054   #
1055   param_names = Array.new(types.size, '') if param_names.empty?
1056   limit = param_names.size
1057   result = param_names.each_with_index.map do |name, index|
1058     type = types[index] || types[-1]
1059     indicator = ''
1060     if to == Float::INFINITY && index == limit - 1
1061       # Last is a repeated_param.
1062       indicator = from == param_names.size ? '+' : '*'
1063     elsif optional(index, required_count)
1064       indicator = '?'
1065       type = type.optional_type if type.is_a?(POptionalType)
1066     end
1067     "#{type} #{name}#{indicator}"
1068   end.join(', ')
1069 
1070   # If there is a block, include it
1071   case signature.type.block_type
1072   when POptionalType
1073     result << ', ' unless result == ''
1074     result << "#{signature.type.block_type.optional_type} #{signature.block_name}?"
1075   when PCallableType
1076     result << ', ' unless result == ''
1077     result << "#{signature.type.block_type} #{signature.block_name}"
1078   when NilClass
1079     # nothing
1080   end
1081   result
1082 end
tense_deprecated() click to toggle source
    # File lib/puppet/pops/types/type_mismatch_describer.rb
515 def tense_deprecated
516   #TRANSLATORS TypeMismatchDescriber is a class name and 'tense' is a method name and should not be translated
517   message = _("Passing a 'tense' argument to the TypeMismatchDescriber is deprecated and ignored.")
518   message += ' ' + _("Everything is now reported using present tense")
519   Puppet.warn_once('deprecations', 'typemismatch#tense', message)
520 end
validate_default_parameter(subject, param_name, param_type, value, tense = :ignored) click to toggle source

@param subject [String] string to be prepended to the exception message @param param_name [String] parameter name @param param_type [PAnyType] parameter type @param value [Object] value to be validated against the given type @param tense [Symbol] deprecated and ignored

    # File lib/puppet/pops/types/type_mismatch_describer.rb
570 def validate_default_parameter(subject, param_name, param_type, value, tense = :ignored)
571   tense_deprecated unless tense == :ignored
572   unless param_type.instance?(value)
573     errors = describe(param_type, TypeCalculator.singleton.infer_set(value).generalize, [ParameterPathElement.new(param_name)])
574     case errors.size
575     when 0
576     when 1
577       raise Puppet::ParseError.new("#{subject}:#{errors[0].format}")
578     else
579       errors_str = errors.map { |error| error.format }.join("\n ")
580       raise Puppet::ParseError.new("#{subject}:\n #{errors_str}")
581     end
582   end
583 end
validate_parameters(subject, params_struct, given_hash, missing_ok = false, tense = :ignored) click to toggle source

Validates that all entries in the give_hash exists in the given param_struct, that their type conforms with the corresponding param_struct element and that all required values are provided.

@param subject [String] string to be prepended to the exception message @param params_struct [PStructType] Struct to use for validation @param given_hash [Hash<String,Object>] the parameters to validate @param missing_ok [Boolean] Do not generate errors on missing parameters @param tense [Symbol] deprecated and ignored

    # File lib/puppet/pops/types/type_mismatch_describer.rb
531 def validate_parameters(subject, params_struct, given_hash, missing_ok = false, tense = :ignored)
532   tense_deprecated unless tense == :ignored
533   errors = describe_struct_signature(params_struct, given_hash, missing_ok).flatten
534   case errors.size
535   when 0
536   when 1
537     raise Puppet::ParseError.new("#{subject}:#{errors[0].format}")
538   else
539     errors_str = errors.map { |error| error.format }.join("\n ")
540     raise Puppet::ParseError.new("#{subject}:\n #{errors_str}")
541   end
542 end

Private Instance Methods

get_deferred_function_return_type(value) click to toggle source
    # File lib/puppet/pops/types/type_mismatch_describer.rb
585 def get_deferred_function_return_type(value)
586   func = Puppet.lookup(:loaders).private_environment_loader.
587            load(:function, value.name)
588   dispatcher = func.class.dispatcher.find_matching_dispatcher(value.arguments)
589   raise ArgumentError, "No matching arity found for #{func.class.name} with arguments #{value.arguments}" unless dispatcher
590   dispatcher.type.return_type
591 end
internal_describe(expected, original, actual, path) click to toggle source
     # File lib/puppet/pops/types/type_mismatch_describer.rb
1002 def internal_describe(expected, original, actual, path)
1003   case expected
1004   when PVariantType
1005     describe_PVariantType(expected, original, actual, path)
1006   when PStructType
1007     describe_PStructType(expected, original, actual, path)
1008   when PHashType
1009     describe_PHashType(expected, original, actual, path)
1010   when PTupleType
1011     describe_PTupleType(expected, original, actual, path)
1012   when PArrayType
1013     describe_PArrayType(expected, original, actual, path)
1014   when PCallableType
1015     describe_PCallableType(expected, original, actual, path)
1016   when POptionalType
1017     describe_POptionalType(expected, original, actual, path)
1018   when PPatternType
1019     describe_PPatternType(expected, original, actual, path)
1020   when PEnumType
1021     describe_PEnumType(expected, original, actual, path)
1022   when PTypeAliasType
1023     describe_PTypeAliasType(expected, original, actual, path)
1024   else
1025     describe_PAnyType(expected, original, actual, path)
1026   end
1027 end