Class: TypeProf::Core::ChangeSet

Inherits:
Object
  • Object
show all
Defined in:
lib/typeprof/core/graph/change_set.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(node, target) ⇒ ChangeSet

Returns a new instance of ChangeSet.



3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# File 'lib/typeprof/core/graph/change_set.rb', line 3

def initialize(node, target)
  @node = node
  @target = target
  @diagnostics = []
  @new_diagnostics = []
  if target
    @depended_value_entities = []
    @new_depended_value_entities = []
    @depended_method_entities = []
    @new_depended_method_entities = []
    @depended_static_reads = []
    @new_depended_static_reads = []
    @depended_superclasses = []
    @new_depended_superclasses = []
  end
end

Instance Attribute Details

#diagnosticsObject (readonly)

Returns the value of attribute diagnostics.



20
21
22
# File 'lib/typeprof/core/graph/change_set.rb', line 20

def diagnostics
  @diagnostics
end

#nodeObject (readonly)

Returns the value of attribute node.



20
21
22
# File 'lib/typeprof/core/graph/change_set.rb', line 20

def node
  @node
end

#targetObject (readonly)

Returns the value of attribute target.



20
21
22
# File 'lib/typeprof/core/graph/change_set.rb', line 20

def target
  @target
end

Instance Method Details

#add_const_read_box(genv, static_ret) ⇒ Object



119
120
121
122
# File 'lib/typeprof/core/graph/change_set.rb', line 119

def add_const_read_box(genv, static_ret)
  key = [:cread, static_ret]
  new_boxes[key] ||= ConstReadBox.new(@node, genv, static_ret)
end

#add_cvar_read_box(genv, cpath, name) ⇒ Object



134
135
136
137
# File 'lib/typeprof/core/graph/change_set.rb', line 134

def add_cvar_read_box(genv, cpath, name)
  key = [:cvar_read, cpath, name]
  new_boxes[key] ||= CVarReadBox.new(@node, genv, cpath, name)
end

#add_depended_method_entity(me) ⇒ Object



157
158
159
# File 'lib/typeprof/core/graph/change_set.rb', line 157

def add_depended_method_entity(me)
  @new_depended_method_entities << me
end

#add_depended_static_read(static_read) ⇒ Object



161
162
163
# File 'lib/typeprof/core/graph/change_set.rb', line 161

def add_depended_static_read(static_read)
  @new_depended_static_reads << static_read
end

#add_depended_superclass(mod) ⇒ Object



165
166
167
# File 'lib/typeprof/core/graph/change_set.rb', line 165

def add_depended_superclass(mod)
  @new_depended_superclasses << mod
end

#add_depended_value_entity(ve) ⇒ Object



153
154
155
# File 'lib/typeprof/core/graph/change_set.rb', line 153

def add_depended_value_entity(ve)
  @new_depended_value_entities << ve
end

#add_diagnostic(meth, msg, node = @node) ⇒ Object



149
150
151
# File 'lib/typeprof/core/graph/change_set.rb', line 149

def add_diagnostic(meth, msg, node = @node)
  @new_diagnostics << TypeProf::Diagnostic.new(node, meth, msg)
end

#add_edge(genv, src, dst) ⇒ Object



68
69
70
# File 'lib/typeprof/core/graph/change_set.rb', line 68

def add_edge(genv, src, dst)
  (new_edges[src] ||= {})[dst] = true
end

#add_escape_box(genv, a_ret) ⇒ Object



79
80
81
82
# File 'lib/typeprof/core/graph/change_set.rb', line 79

def add_escape_box(genv, a_ret)
  key = [:return, a_ret]
  new_boxes[key] ||= EscapeBox.new(@node, genv, a_ret)
end

#add_gvar_read_box(genv, var) ⇒ Object



124
125
126
127
# File 'lib/typeprof/core/graph/change_set.rb', line 124

def add_gvar_read_box(genv, var)
  key = [:gvar_read, var]
  new_boxes[key] ||= GVarReadBox.new(@node, genv, var)
end

#add_hash_splat_box(genv, arg, unified_key, unified_val) ⇒ Object



94
95
96
97
# File 'lib/typeprof/core/graph/change_set.rb', line 94

def add_hash_splat_box(genv, arg, unified_key, unified_val)
  key = [:hash_splat, arg, unified_key, unified_val]
  new_boxes[key] ||= HashSplatBox.new(@node, genv, arg, unified_key, unified_val)
end

#add_instance_type_box(genv, singleton_ty_vtx) ⇒ Object



144
145
146
147
# File 'lib/typeprof/core/graph/change_set.rb', line 144

def add_instance_type_box(genv, singleton_ty_vtx)
  key = [:instance_type, singleton_ty_vtx]
  new_boxes[key] ||= InstanceTypeBox.new(@node, genv, singleton_ty_vtx)
end

#add_ivar_read_box(genv, cpath, singleton, name) ⇒ Object



129
130
131
132
# File 'lib/typeprof/core/graph/change_set.rb', line 129

def add_ivar_read_box(genv, cpath, singleton, name)
  key = [:ivar_read, cpath, singleton, name]
  new_boxes[key] ||= IVarReadBox.new(@node, genv, cpath, singleton, name)
end

#add_keyword_merge_box(genv, rest, literal_pairs, fallback) ⇒ Object



89
90
91
92
# File 'lib/typeprof/core/graph/change_set.rb', line 89

def add_keyword_merge_box(genv, rest, literal_pairs, fallback)
  key = [:kw_merge, rest, literal_pairs, fallback]
  new_boxes[key] ||= KeywordMergeBox.new(@node, genv, rest, literal_pairs, fallback)
end

#add_masgn_box(genv, value, lefts, rest_elem, rights) ⇒ Object



99
100
101
102
# File 'lib/typeprof/core/graph/change_set.rb', line 99

def add_masgn_box(genv, value, lefts, rest_elem, rights)
  key = [:masgn, value, lefts, rest_elem, rights]
  new_boxes[key] ||= MAsgnBox.new(@node, genv, value, lefts, rest_elem, rights)
end

#add_method_alias_box(genv, cpath, singleton, new_mid, old_mid) ⇒ Object



114
115
116
117
# File 'lib/typeprof/core/graph/change_set.rb', line 114

def add_method_alias_box(genv, cpath, singleton, new_mid, old_mid)
  key = [:mdecl, cpath, singleton, new_mid, old_mid]
  new_boxes[key] ||= MethodAliasBox.new(@node, genv, cpath, singleton, new_mid, old_mid)
end

#add_method_call_box(genv, recv, mid, a_args, subclasses, suppress_errors: false, unresolved_recv: nil) ⇒ Object

TODO: if an edge is removed during one analysis, we may need to remove sub-boxes?



74
75
76
77
# File 'lib/typeprof/core/graph/change_set.rb', line 74

def add_method_call_box(genv, recv, mid, a_args, subclasses, suppress_errors: false, unresolved_recv: nil)
  key = [:mcall, recv, mid, a_args, subclasses, suppress_errors, unresolved_recv]
  new_boxes[key] ||= MethodCallBox.new(@node, genv, recv, mid, a_args, subclasses, suppress_errors: suppress_errors, unresolved_recv: unresolved_recv)
end

#add_method_decl_box(genv, cpath, singleton, mid, method_types, overloading) ⇒ Object



109
110
111
112
# File 'lib/typeprof/core/graph/change_set.rb', line 109

def add_method_decl_box(genv, cpath, singleton, mid, method_types, overloading)
  key = [:mdecl, cpath, singleton, mid, method_types, overloading]
  new_boxes[key] ||= MethodDeclBox.new(@node, genv, cpath, singleton, mid, method_types, overloading)
end

#add_method_def_box(genv, cpath, singleton, mid, f_args, ret_boxes) ⇒ Object



104
105
106
107
# File 'lib/typeprof/core/graph/change_set.rb', line 104

def add_method_def_box(genv, cpath, singleton, mid, f_args, ret_boxes)
  key = [:mdef, cpath, singleton, mid, f_args, ret_boxes]
  new_boxes[key] ||= MethodDefBox.new(@node, genv, cpath, singleton, mid, f_args, ret_boxes)
end

#add_splat_box(genv, arg, idx = nil, unresolved_recv = nil) ⇒ Object



84
85
86
87
# File 'lib/typeprof/core/graph/change_set.rb', line 84

def add_splat_box(genv, arg, idx = nil, unresolved_recv = nil)
  key = [:splat, arg, idx, unresolved_recv]
  new_boxes[key] ||= SplatBox.new(@node, genv, arg, idx, unresolved_recv)
end

#add_type_read_box(genv, type) ⇒ Object



139
140
141
142
# File 'lib/typeprof/core/graph/change_set.rb', line 139

def add_type_read_box(genv, type)
  key = [:type_read, type]
  new_boxes[key] ||= TypeReadBox.new(@node, genv, type)
end

#boxesObject



25
# File 'lib/typeprof/core/graph/change_set.rb', line 25

def boxes = @boxes ||= {}

#contravariant_typesObject



23
# File 'lib/typeprof/core/graph/change_set.rb', line 23

def contravariant_types = @contravariant_types ||= {}

#copy_from(other) ⇒ Object



37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/typeprof/core/graph/change_set.rb', line 37

def copy_from(other)
  @covariant_types = other.covariant_types.dup
  @contravariant_types = other.contravariant_types.dup
  @edges = other.edges.dup
  @boxes = other.boxes.dup
  @diagnostics = other.diagnostics.dup

  other.covariant_types.clear
  other.contravariant_types.clear
  other.edges.clear
  other.boxes.clear
  other.diagnostics.clear
end

#covariant_typesObject



22
# File 'lib/typeprof/core/graph/change_set.rb', line 22

def covariant_types = @covariant_types ||= {}

#edgesObject



24
# File 'lib/typeprof/core/graph/change_set.rb', line 24

def edges = @edges ||= {}

#new_contravariant_vertex(genv, sig_type_node) ⇒ Object



63
64
65
66
# File 'lib/typeprof/core/graph/change_set.rb', line 63

def new_contravariant_vertex(genv, sig_type_node)
  # This is used to avoid duplicated vertex generation for the same sig node
  contravariant_types[sig_type_node] ||= Vertex.new(sig_type_node)
end

#new_covariant_vertex(genv, sig_type_node) ⇒ Object



58
59
60
61
# File 'lib/typeprof/core/graph/change_set.rb', line 58

def new_covariant_vertex(genv, sig_type_node)
  # This is used to avoid duplicated vertex generation for the same sig node
  covariant_types[sig_type_node] ||= Vertex.new(sig_type_node)
end

#new_vertex(genv, origin, base_vtx) ⇒ Object



51
52
53
54
55
56
# File 'lib/typeprof/core/graph/change_set.rb', line 51

def new_vertex(genv, origin, base_vtx)
  @new_vertexes ||= {}
  new_vtx = @new_vertexes[base_vtx] ||= Vertex.new(origin)
  add_edge(genv, base_vtx, new_vtx)
  new_vtx
end

#reinstall(genv) ⇒ Object



169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
# File 'lib/typeprof/core/graph/change_set.rb', line 169

def reinstall(genv)
  # Edges stored as nested hashes: {src => {dst => true}}
  new_edges.each do |src, new_dsts|
    old_dsts = edges[src]
    new_dsts.each_key do |dst|
      src.add_edge(genv, dst) unless old_dsts&.key?(dst)
    end
  end
  edges.each do |src, old_dsts|
    new_dsts = new_edges[src]
    old_dsts.each_key do |dst|
      src.remove_edge(genv, dst) unless new_dsts&.key?(dst)
    end
  end
  @edges, @new_edges = @new_edges, @edges
  new_edges.each_value(&:clear)
  new_edges.clear

  boxes.each do |key, box|
    box.destroy(genv)
  end
  @boxes, @new_boxes = @new_boxes, @boxes
  new_boxes.clear

  @diagnostics.each do |diag|
    genv.add_diagnostic_path(diag.node.lenv.path)
    diag.node.remove_diagnostic(diag)
  end
  @new_diagnostics.each do |diag|
    genv.add_diagnostic_path(diag.node.lenv.path)
    diag.node.add_diagnostic(diag)
  end
  @diagnostics, @new_diagnostics = @new_diagnostics, @diagnostics
  @new_diagnostics.clear

  return unless @target

  @depended_value_entities.each do |ve|
    ve.read_boxes.delete(@target) || raise
  end
  @new_depended_value_entities.uniq!
  @new_depended_value_entities.each do |ve|
    ve.read_boxes << @target
  end
  @depended_value_entities, @new_depended_value_entities = @new_depended_value_entities, @depended_value_entities
  @new_depended_value_entities.clear

  @depended_method_entities.each do |me|
    me.method_call_boxes.delete(@target) || raise
  end
  @new_depended_method_entities.uniq!
  @new_depended_method_entities.each do |me|
    me.method_call_boxes << @target
  end
  @depended_method_entities, @new_depended_method_entities = @new_depended_method_entities, @depended_method_entities
  @new_depended_method_entities.clear

  @depended_static_reads.each do |static_read|
    static_read.followers.delete(@target)
  end
  @new_depended_static_reads.uniq!
  @new_depended_static_reads.each do |static_read|
    static_read.followers << @target
  end

  @depended_static_reads, @new_depended_static_reads = @new_depended_static_reads, @depended_static_reads
  @new_depended_static_reads.clear

  @depended_superclasses.each do |mod|
    mod.subclass_checks.delete(@target)
  end
  @new_depended_superclasses.uniq!
  @new_depended_superclasses.each do |mod|
    mod.subclass_checks << @target
  end

  @depended_superclasses, @new_depended_superclasses = @new_depended_superclasses, @depended_superclasses
  @new_depended_superclasses.clear
end

#reuse(new_node) ⇒ Object



30
31
32
33
34
35
# File 'lib/typeprof/core/graph/change_set.rb', line 30

def reuse(new_node)
  @node = new_node
  boxes.each_value do |box|
    box.reuse(new_node)
  end
end