Class: Typeguard::Resolution::Resolver

Inherits:
Object
  • Object
show all
Includes:
TypeModel::Definitions
Defined in:
lib/typeguard/resolver.rb

Instance Method Summary collapse

Constructor Details

#initialize(definitions, config) ⇒ Resolver

Returns a new instance of Resolver.



8
9
10
11
# File 'lib/typeguard/resolver.rb', line 8

def initialize(definitions, config)
  @definitions = definitions
  @config = config
end

Instance Method Details

#resolve!Object



13
14
15
16
17
18
19
20
21
22
23
24
25
26
# File 'lib/typeguard/resolver.rb', line 13

def resolve!
  if @config.raise_on_name_error
    @definitions.each do |definition|
      resolve_definition(definition)
    rescue NameError => e
      raise(e.class,
            Metrics.format_log(Metrics.report(Object, definition, :unresolved, 'resolution', e.message)),
            [])
    end
  else
    # Create compact array of resolved definitions
    resolve_prune_definitions!
  end
end

#resolve_definition(definition) ⇒ Object



28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/typeguard/resolver.rb', line 28

def resolve_definition(definition)
  case definition
  when ModuleDefinition, ClassDefinition
    Object.const_get(definition.name.to_s, true)
    definition.children.each { |child| resolve_definition(child) }
  when MethodDefinition
    definition.parameters.each { |param| param.types.each { |node| resolve_type(node) } }
    return if definition.name == :initialize # Ignore YARD default tag

    definition.returns.types.each { |node| resolve_type(node) }
  else raise "Unexpected definition for '#{definition}'"
  end
end

#resolve_prune_definitions!(definitions = @definitions, parent = Object) ⇒ Object



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/typeguard/resolver.rb', line 42

def resolve_prune_definitions!(definitions = @definitions, parent = Object)
  definitions.grep_v(MethodDefinition) do |definition|
    definition.children = resolve_prune_definitions!(definition.children, definition)
  end
  definitions.reject do |definition|
    case definition
    when ModuleDefinition, ClassDefinition
      Object.const_get(definition.name.to_s, true)
    when MethodDefinition
      definition.parameters.each { |param| param.types.each { |node| resolve_type(node) } }
      next if definition.name == :initialize # Ignore YARD default tag

      definition.returns.types.each { |node| resolve_type(node) }
    end
    false
  rescue NameError => e
    Metrics.report(parent, definition, :unresolved, 'resolution', e)
    true
  end
end

#resolve_type(node) ⇒ Object

Raises a NameError if module names are not found



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/typeguard/resolver.rb', line 64

def resolve_type(node)
  case node.shape
  when :basic
    node.[:const] ||= Object.const_get(node.kind.to_s, true)
  when :generic, :fixed
    node.[:const] ||= Object.const_get(node.kind.to_s, true)
    node.children.each { |child_node| resolve_type(child_node) }
  when :hash, :fixed_hash
    node.[:const] ||= Object.const_get(node.kind.to_s, true)
    node.children.flatten.each { |child_node| resolve_type(child_node) }
  when :union
    node.children.each { |child_node| resolve_type(child_node) }
  when :literal
    # The mapper has already rejected invalid literals,
  when :duck
    # Resolving duck-types at this point is unreliable
    # and slow, leaving it up to runtime checks
  when :untyped
    # Always correct
  else raise "Unknown node shape: #{node.shape}"
  end
end