module Solargraph::TypeChecker::Checks

def all_types_match? api_map, inferred, expected

Returns:
  • (Boolean) -

Parameters:
  • expected (ComplexType) --
  • inferred (ComplexType) --
  • api_map (ApiMap) --
def all_types_match? api_map, inferred, expected
  return duck_types_match?(api_map, expected, inferred) if expected.duck_type?
  inferred.each do |inf|
    next if inf.duck_type?
    return false unless expected.any? { |exp| exp == inf || either_way?(api_map, inf, exp) }
  end
  true
end

def any_types_match? api_map, expected, inferred

Returns:
  • (Boolean) -

Parameters:
  • inferred (ComplexType) --
  • expected (ComplexType) --
  • api_map (ApiMap) --
def any_types_match? api_map, expected, inferred
  return duck_types_match?(api_map, expected, inferred) if expected.duck_type?
  # walk through the union expected type and see if any members

  # of the union match the inferred type

  expected.each do |exp|
    next if exp.duck_type?
    # @todo: there should be a level of typechecking where all

    #   unique types in the inferred must match one of the

    #   expected unique types

    inferred.each do |inf|
      # return true if exp == inf || api_map.super_and_sub?(fuzz(inf), fuzz(exp))

      return true if exp == inf || either_way?(api_map, inf, exp)
    end
  end
  false
end

def duck_types_match? api_map, expected, inferred

Returns:
  • (Boolean) -

Parameters:
  • inferred (ComplexType) --
  • expected (ComplexType) --
  • api_map (ApiMap) --
def duck_types_match? api_map, expected, inferred
  raise ArgumentError, 'Expected type must be duck type' unless expected.duck_type?
  expected.each do |exp|
    next unless exp.duck_type?
    quack = exp.to_s[1..-1]
    return false if api_map.get_method_stack(inferred.namespace, quack, scope: inferred.scope).empty?
  end
  true
end

def either_way?(api_map, cls1, cls2)

Returns:
  • (Boolean) -

Parameters:
  • cls2 (ComplexType::UniqueType) --
  • cls1 (ComplexType::UniqueType) --
  • api_map (ApiMap) --
def either_way?(api_map, cls1, cls2)
  # @todo there should be a level of typechecking which uses the

  #   full tag with parameters to determine compatibility

  f1 = cls1.name
  f2 = cls2.name
  api_map.type_include?(f1, f2) || api_map.super_and_sub?(f1, f2) || api_map.super_and_sub?(f2, f1)
  # api_map.type_include?(f1, f2) || api_map.super_and_sub?(f1, f2) || api_map.super_and_sub?(f2, f1)

end

def fuzz type

Returns:
  • (String) -

Parameters:
  • type (ComplexType::UniqueType) --
def fuzz type
  if type.parameters?
    type.name
  else
    type.tag
  end
end

def types_match? api_map, expected, inferred

Returns:
  • (Boolean) -

Parameters:
  • inferred (ComplexType) --
  • expected (ComplexType) --
  • api_map (ApiMap) --
def types_match? api_map, expected, inferred
  return true if expected.to_s == inferred.to_s
  matches = []
  expected.each do |exp|
    found = false
    inferred.each do |inf|
      # if api_map.super_and_sub?(fuzz(inf), fuzz(exp))

      if either_way?(api_map, inf, exp)
        found = true
        matches.push inf
        break
      end
    end
    return false unless found
  end
  inferred.each do |inf|
    next if matches.include?(inf)
    found = false
    expected.each do |exp|
      # if api_map.super_and_sub?(fuzz(inf), fuzz(exp))

      if either_way?(api_map, inf, exp)
        found = true
        break
      end
    end
    return false unless found
  end
  true
end