Class: Solargraph::TypeChecker

Inherits:
Object
  • Object
show all
Defined in:
lib/solargraph/type_checker.rb,
lib/solargraph/type_checker/problem.rb,
lib/solargraph/type_checker/param_def.rb

Overview

A static analysis tool for validating data types.

Defined Under Namespace

Classes: ParamDef, Problem

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(filename, api_map: nil) ⇒ TypeChecker


13
14
15
16
17
# File 'lib/solargraph/type_checker.rb', line 13

def initialize filename, api_map: nil
  @filename = filename
  # @todo Smarter directory resolution
  @api_map = api_map || Solargraph::ApiMap.load(File.dirname(filename))
end

Instance Attribute Details

#filenameString (readonly)


9
10
11
# File 'lib/solargraph/type_checker.rb', line 9

def filename
  @filename
end

Class Method Details

.load(filename) ⇒ self


268
269
270
271
272
273
# File 'lib/solargraph/type_checker.rb', line 268

def load filename
  source = Solargraph::Source.load(filename)
  api_map = Solargraph::ApiMap.new
  api_map.map(source)
  new(filename, api_map: api_map)
end

.load_string(code, filename = nil) ⇒ self


278
279
280
281
282
283
# File 'lib/solargraph/type_checker.rb', line 278

def load_string code, filename = nil
  source = Solargraph::Source.load_string(code, filename)
  api_map = Solargraph::ApiMap.new
  api_map.map(source)
  new(filename, api_map: api_map)
end

Instance Method Details

#param_type_problemsArray<Problem>

Param type problems indicate that a method does not specify a type in a `@param` tag for one or more of its parameters, a `@param` tag is defined that does not correlate with the method signature, or the specified type could not be resolved to a known type.


38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/solargraph/type_checker.rb', line 38

def param_type_problems
  result = []
  smap = api_map.source_map(filename)
  smap.locals.select { |pin| pin.is_a?(Solargraph::Pin::Parameter) }.each do |par|
    next unless par.closure.is_a?(Solargraph::Pin::Method)
    result.concat check_param_tags(par.closure)
    type = par.typify(api_map)
    pdefs = ParamDef.from(par.closure)
    if type.undefined?
      if par.return_type.undefined? && !pdefs.any? { |pd| pd.name == par.name && [:restarg, :kwrestarg].include?(pd.type) }
        result.push Problem.new(par.location, "#{par.closure.name} has undefined @param type for #{par.name}")
      elsif !pdefs.any? { |pd| [:restarg, :kwrestarg].include?(pd.type) }
        result.push Problem.new(par.location, "#{par.closure.name} has unresolved @param type for #{par.name}")
      end
    end
  end
  result
end

#return_type_problemsArray<Problem>

Return type problems indicate that a method does not specify a type in a `@return` tag or the specified type could not be resolved to a known type.


24
25
26
27
28
29
30
# File 'lib/solargraph/type_checker.rb', line 24

def return_type_problems
  result = []
  smap = api_map.source_map(filename)
  pins = smap.pins.select { |pin| pin.is_a?(Solargraph::Pin::BaseMethod) }
  pins.each { |pin| result.concat check_return_type(pin) }
  result
end

#strict_type_problemsArray<Problem>

Strict type problems indicate that a `@return` type or a `@param` type does not match the type inferred from code analysis; or that an argument sent to a method does not match the type specified in the corresponding `@param` tag.


63
64
65
66
67
68
69
70
71
72
# File 'lib/solargraph/type_checker.rb', line 63

def strict_type_problems
  result = []
  smap = api_map.source_map(filename)
  smap.pins.select { |pin| pin.is_a?(Pin::BaseMethod) }.each do |pin|
    result.concat confirm_return_type(pin)
  end
  return result if smap.source.node.nil?
  result.concat check_send_args smap.source.node
  result
end