class Puppet::Pops::Types::TypeMismatch

@api private

Public Instance Methods

label(o) click to toggle source
    # File lib/puppet/pops/types/type_mismatch_describer.rb
323 def label(o)
324   o.to_s
325 end
merge(path, o) click to toggle source

@return A new instance with the least restrictive respective boundaries

    # File lib/puppet/pops/types/type_mismatch_describer.rb
267 def merge(path, o)
268   self.class.new(path, [expected, o.expected].flatten.uniq, actual)
269 end
message(variant, position) click to toggle source
    # File lib/puppet/pops/types/type_mismatch_describer.rb
271 def message(variant, position)
272   e = expected
273   a = actual
274   multi = false
275   if e.is_a?(POptionalType)
276     e = e.optional_type
277     optional = true
278   end
279 
280   if e.is_a?(PVariantType)
281     e = e.types
282   end
283 
284   if e.is_a?(Array)
285     if report_detailed?(e, a)
286       a = detailed_actual_to_s(e, a)
287       e = e.map { |t| t.to_alias_expanded_s }
288     else
289       e = e.map { |t| short_name(t) }.uniq
290       a = short_name(a)
291     end
292     e.insert(0, 'Undef') if optional
293     case e.size
294     when 1
295       e = e[0]
296     when 2
297       e = "#{e[0]} or #{e[1]}"
298       multi = true
299     else
300       e = "#{e[0..e.size-2].join(', ')}, or #{e[e.size-1]}"
301       multi = true
302     end
303   else
304     if report_detailed?(e, a)
305       a = detailed_actual_to_s(e, a)
306       e = e.to_alias_expanded_s
307     else
308       e = short_name(e)
309       a = short_name(a)
310     end
311     if optional
312       e = "Undef or #{e}"
313       multi = true
314     end
315   end
316   if multi
317     "#{variant}#{position} expects a value of type #{e}, got #{label(a)}"
318   else
319     "#{variant}#{position} expects #{a_an(e)} value, got #{label(a)}"
320   end
321 end

Private Instance Methods

all_resolved(e) click to toggle source

Returns its argument with all type aliases resolved @param e [PAnyType,Array] the expected type or array of expected types @return [PAnyType,Array] the resolved result

    # File lib/puppet/pops/types/type_mismatch_describer.rb
402 def all_resolved(e)
403   if e.is_a?(Array)
404     e.map { |t| all_resolved(t) }
405   else
406     e.is_a?(PTypeAliasType) ? all_resolved(e.resolved_type) : e
407   end
408 end
always_fully_detailed?(e, a) click to toggle source

Decides whether or not the report must be fully detailed, or if generalization can be permitted in the mismatch report. All comparisons are made using resolved aliases rather than the alias itself.

@param e [PAnyType,Array] the expected type or array of expected types @param a [PAnyType] the actual type @return [Boolean] `true` when the class of a equals the class e or,

in case _e_ is an `Array`, the class of at least one element of _e_
    # File lib/puppet/pops/types/type_mismatch_describer.rb
363 def always_fully_detailed?(e, a)
364   if e.is_a?(Array)
365     e.any? { |t| always_fully_detailed?(t, a) }
366   else
367     e.class == a.class || e.is_a?(PTypeAliasType) || a.is_a?(PTypeAliasType) || specialization(e, a)
368   end
369 end
any_assignable?(e, a) click to toggle source

@param e [PAnyType,Array] the expected type or array of expected types @param a [PAnyType] the actual type @return [Boolean] `true` when a is assignable to e or, in case e is an `Array`,

to at least one element of _e_
    # File lib/puppet/pops/types/type_mismatch_describer.rb
375 def any_assignable?(e, a)
376   e.is_a?(Array) ? e.any? { |t| t.assignable?(a) } : e.assignable?(a)
377 end
assignable_to_default?(e, a) click to toggle source

@param e [PAnyType,Array] the expected type or array of expected types @param a [PAnyType] the actual type @return [Boolean] `true` when a is assignable to the default generalization of e or,

in case _e_ is an `Array`, to the default generalization of at least one element of _e_
    # File lib/puppet/pops/types/type_mismatch_describer.rb
383 def assignable_to_default?(e, a)
384   if e.is_a?(Array)
385     e.any? { |t| assignable_to_default?(t, a) }
386   else
387     e = e.resolved_type if e.is_a?(PTypeAliasType)
388     e.class::DEFAULT.assignable?(a)
389   end
390 end
detailed_actual_to_s(e, a) click to toggle source

Returns a string that either represents the generalized type a or the type a verbatim. The latter form is used when at least one of the following conditions are met:

  • always_fully_detailed returns `true` for the resolved type of e and a

  • any_assignable? returns `true` for the resolved type of e and the generalized type of a.

@param e [PAnyType,Array] the expected type or array of expected types @param a [PAnyType] the actual type @return [String] The string representation of the type a or generalized type a

    # File lib/puppet/pops/types/type_mismatch_describer.rb
419 def detailed_actual_to_s(e, a)
420   e = all_resolved(e)
421   if always_fully_detailed?(e, a)
422     a.to_alias_expanded_s
423   else
424     any_assignable?(e, a.generalize) ? a.to_alias_expanded_s : a.simple_name
425   end
426 end
report_detailed?(e, a) click to toggle source

@param e [PAnyType,Array] the expected type or array of expected types @param a [PAnyType] the actual type @return [Boolean] `true` when either always_fully_detailed or assignable_to_default returns `true`

    # File lib/puppet/pops/types/type_mismatch_describer.rb
395 def report_detailed?(e, a)
396   always_fully_detailed?(e, a) || assignable_to_default?(e, a)
397 end
short_name(t) click to toggle source
    # File lib/puppet/pops/types/type_mismatch_describer.rb
329 def short_name(t)
330   # Ensure that Optional, NotUndef, Sensitive, and Type are reported with included
331   # type parameter.
332   if t.is_a?(PTypeWithContainedType) && !(t.type.nil? || t.type.class == PAnyType)
333     "#{t.name}[#{t.type.name}]"
334   else
335     t.name.nil? ? t.simple_name : t.name
336   end
337 end
specialization(e, a) click to toggle source

Answers the question if `e` is a specialized type of `a` @param e [PAnyType] the expected type @param a [PAnyType] the actual type @return [Boolean] `true` when the e is a specialization of a

    # File lib/puppet/pops/types/type_mismatch_describer.rb
344 def specialization(e, a)
345   case e
346   when PStructType
347     a.is_a?(PHashType)
348   when PTupleType
349     a.is_a?(PArrayType)
350   else
351     false
352   end
353 end