Module: Solargraph::TypeChecker::Checks

Included in:
Solargraph::TypeChecker
Defined in:
lib/solargraph/type_checker/checks.rb

Overview

Helper methods for performing type checks

Class Method Summary collapse

Class Method Details

.all_types_match?(api_map, inferred, expected) ⇒ Boolean

Parameters:

Returns:

  • (Boolean)


68
69
70
71
72
73
74
75
# File 'lib/solargraph/type_checker/checks.rb', line 68

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

.any_types_match?(api_map, expected, inferred) ⇒ Boolean

Parameters:

Returns:

  • (Boolean)


52
53
54
55
56
57
58
59
60
61
62
# File 'lib/solargraph/type_checker/checks.rb', line 52

def any_types_match? api_map, expected, inferred
  return duck_types_match?(api_map, expected, inferred) if expected.duck_type?
  expected.each do |exp|
    next if exp.duck_type?
    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

.duck_types_match?(api_map, expected, inferred) ⇒ Boolean

Parameters:

Returns:

  • (Boolean)

Raises:

  • (ArgumentError)


81
82
83
84
85
86
87
88
89
# File 'lib/solargraph/type_checker/checks.rb', line 81

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

.either_way?(api_map, cls1, cls2) ⇒ Boolean

Parameters:

Returns:

  • (Boolean)


105
106
107
108
109
# File 'lib/solargraph/type_checker/checks.rb', line 105

def either_way?(api_map, cls1, cls2)
  f1 = fuzz(cls1)
  f2 = fuzz(cls2)
  api_map.type_include?(f1, f2) || api_map.super_and_sub?(f1, f2) || api_map.super_and_sub?(f2, f1)
end

.fuzz(type) ⇒ String

Parameters:

Returns:

  • (String)


93
94
95
96
97
98
99
# File 'lib/solargraph/type_checker/checks.rb', line 93

def fuzz type
  if type.parameters?
    type.name
  else
    type.tag
  end
end

.types_match?(api_map, expected, inferred) ⇒ Boolean

Compare an expected type with an inferred type. Common usage is to check if the type declared in a method’s @return tag matches the type inferred from static analysis of the code.

Parameters:

Returns:

  • (Boolean)


18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/solargraph/type_checker/checks.rb', line 18

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