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
324 def label(o)
325   o.to_s
326 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
268 def merge(path, o)
269   self.class.new(path, [expected, o.expected].flatten.uniq, actual)
270 end
message(variant, position) click to toggle source
    # File lib/puppet/pops/types/type_mismatch_describer.rb
272 def message(variant, position)
273   e = expected
274   a = actual
275   multi = false
276   if e.is_a?(POptionalType)
277     e = e.optional_type
278     optional = true
279   end
280 
281   if e.is_a?(PVariantType)
282     e = e.types
283   end
284 
285   if e.is_a?(Array)
286     if report_detailed?(e, a)
287       a = detailed_actual_to_s(e, a)
288       e = e.map { |t| t.to_alias_expanded_s }
289     else
290       e = e.map { |t| short_name(t) }.uniq
291       a = short_name(a)
292     end
293     e.insert(0, 'Undef') if optional
294     case e.size
295     when 1
296       e = e[0]
297     when 2
298       e = "#{e[0]} or #{e[1]}"
299       multi = true
300     else
301       e = "#{e[0..e.size-2].join(', ')}, or #{e[e.size-1]}"
302       multi = true
303     end
304   else
305     if report_detailed?(e, a)
306       a = detailed_actual_to_s(e, a)
307       e = e.to_alias_expanded_s
308     else
309       e = short_name(e)
310       a = short_name(a)
311     end
312     if optional
313       e = "Undef or #{e}"
314       multi = true
315     end
316   end
317   if multi
318     "#{variant}#{position} expects a value of type #{e}, got #{label(a)}"
319   else
320     "#{variant}#{position} expects #{a_an(e)} value, got #{label(a)}"
321   end
322 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
403 def all_resolved(e)
404   if e.is_a?(Array)
405     e.map { |t| all_resolved(t) }
406   else
407     e.is_a?(PTypeAliasType) ? all_resolved(e.resolved_type) : e
408   end
409 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
364 def always_fully_detailed?(e, a)
365   if e.is_a?(Array)
366     e.any? { |t| always_fully_detailed?(t, a) }
367   else
368     e.class == a.class || e.is_a?(PTypeAliasType) || a.is_a?(PTypeAliasType) || specialization(e, a)
369   end
370 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
376 def any_assignable?(e, a)
377   e.is_a?(Array) ? e.any? { |t| t.assignable?(a) } : e.assignable?(a)
378 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
384 def assignable_to_default?(e, a)
385   if e.is_a?(Array)
386     e.any? { |t| assignable_to_default?(t, a) }
387   else
388     e = e.resolved_type if e.is_a?(PTypeAliasType)
389     e.class::DEFAULT.assignable?(a)
390   end
391 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
420 def detailed_actual_to_s(e, a)
421   e = all_resolved(e)
422   if always_fully_detailed?(e, a)
423     a.to_alias_expanded_s
424   else
425     any_assignable?(e, a.generalize) ? a.to_alias_expanded_s : a.simple_name
426   end
427 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
396 def report_detailed?(e, a)
397   always_fully_detailed?(e, a) || assignable_to_default?(e, a)
398 end
short_name(t) click to toggle source
    # File lib/puppet/pops/types/type_mismatch_describer.rb
330 def short_name(t)
331   # Ensure that Optional, NotUndef, Sensitive, and Type are reported with included
332   # type parameter.
333   if t.is_a?(PTypeWithContainedType) && !(t.type.nil? || t.type.class == PAnyType)
334     "#{t.name}[#{t.type.name}]"
335   else
336     t.name.nil? ? t.simple_name : t.name
337   end
338 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
345 def specialization(e, a)
346   case e
347   when PStructType
348     a.is_a?(PHashType)
349   when PTupleType
350     a.is_a?(PArrayType)
351   else
352     false
353   end
354 end