Class: Steep::Typing

Inherits:
Object
  • Object
show all
Defined in:
lib/steep/typing.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(parent: nil, parent_last_update: parent&.last_update) ⇒ Typing

Returns a new instance of Typing.



11
12
13
14
15
16
17
18
19
20
# File 'lib/steep/typing.rb', line 11

def initialize(parent: nil, parent_last_update: parent&.last_update)
  @parent = parent
  @parent_last_update = parent_last_update
  @last_update = parent&.last_update || 0
  @should_update = false

  @errors = []
  @typing = {}.compare_by_identity
  @contexts = {}.compare_by_identity
end

Instance Attribute Details

#contextsObject (readonly)

Returns the value of attribute contexts.



9
10
11
# File 'lib/steep/typing.rb', line 9

def contexts
  @contexts
end

#errorsObject (readonly)

Returns the value of attribute errors.



3
4
5
# File 'lib/steep/typing.rb', line 3

def errors
  @errors
end

#last_updateObject (readonly)

Returns the value of attribute last_update.



7
8
9
# File 'lib/steep/typing.rb', line 7

def last_update
  @last_update
end

#parentObject (readonly)

Returns the value of attribute parent.



5
6
7
# File 'lib/steep/typing.rb', line 5

def parent
  @parent
end

#parent_last_updateObject (readonly)

Returns the value of attribute parent_last_update.



6
7
8
# File 'lib/steep/typing.rb', line 6

def parent_last_update
  @parent_last_update
end

#should_updateObject (readonly)

Returns the value of attribute should_update.



8
9
10
# File 'lib/steep/typing.rb', line 8

def should_update
  @should_update
end

#typingObject (readonly)

Returns the value of attribute typing.



4
5
6
# File 'lib/steep/typing.rb', line 4

def typing
  @typing
end

Class Method Details

.summary(node) ⇒ Object



82
83
84
85
86
87
88
# File 'lib/steep/typing.rb', line 82

def self.summary(node)
  src = node.loc.expression.source.split(/\n/).first
  line = node.loc.first_line
  col = node.loc.column

  "#{line}:#{col}:#{src}"
end

Instance Method Details

#add_error(error) ⇒ Object



22
23
24
# File 'lib/steep/typing.rb', line 22

def add_error(error)
  errors << error
end

#add_typing(node, type, context) ⇒ Object



26
27
28
29
30
31
32
33
34
35
36
# File 'lib/steep/typing.rb', line 26

def add_typing(node, type, context)
  typing[node] = type
  contexts[node] = context

  if should_update
    @last_update += 1
    @should_update = false
  end

  type
end

#context_of(node:) ⇒ Object



56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/steep/typing.rb', line 56

def context_of(node:)
  ctx = contexts[node]

  if ctx
    ctx
  else
    if parent
      parent.context_of(node: node)
    else
      raise "Unknown node for context: #{node.inspect}"
    end
  end
end

#dump(io) ⇒ Object



70
71
72
73
74
75
76
77
78
79
80
# File 'lib/steep/typing.rb', line 70

def dump(io)
  io.puts "Typing: "
  nodes.each_value do |node|
    io.puts "  #{Typing.summary(node)} => #{type_of(node: node).inspect}"
  end

  io.puts "Errors: "
  errors.each do |error|
    io.puts "  #{Typing.summary(error.node)} => #{error.inspect}"
  end
end

#each_typing(&block) ⇒ Object



101
102
103
# File 'lib/steep/typing.rb', line 101

def each_typing(&block)
  typing.each(&block)
end

#has_type?(node) ⇒ Boolean

Returns:

  • (Boolean)


38
39
40
# File 'lib/steep/typing.rb', line 38

def has_type?(node)
  typing.key?(node)
end

#new_childObject



90
91
92
93
94
95
96
97
98
99
# File 'lib/steep/typing.rb', line 90

def new_child
  child = self.class.new(parent: self)
  @should_update = true

  if block_given?
    yield child
  else
    child
  end
end

#save!Object



105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/steep/typing.rb', line 105

def save!
  raise "Unexpected save!" unless parent
  raise "Parent modified since new_child" unless parent.last_update == parent_last_update

  each_typing do |node, type|
    parent.add_typing(node, type, contexts[node])
  end

  errors.each do |error|
    parent.add_error error
  end
end

#type_of(node:) ⇒ Object



42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/steep/typing.rb', line 42

def type_of(node:)
  type = typing[node]

  if type
    type
  else
    if parent
      parent.type_of(node: node)
    else
      raise "Unknown node for typing: #{node.inspect}"
    end
  end
end