diff --git a/lib/typeprof/core/graph/change_set.rb b/lib/typeprof/core/graph/change_set.rb index 8e7d6008..bb48dfeb 100644 --- a/lib/typeprof/core/graph/change_set.rb +++ b/lib/typeprof/core/graph/change_set.rb @@ -6,8 +6,8 @@ def initialize(node, target) @new_vertexes = {} @covariant_types = {} @contravariant_types = {} - @edges = [] - @new_edges = [] + @edges = {} + @new_edges = {} @boxes = {} @new_boxes = {} @diagnostics = [] @@ -62,7 +62,14 @@ def new_contravariant_vertex(genv, sig_type_node) end def add_edge(genv, src, dst) - @new_edges << [src, dst] + key = [src, dst] + return if @new_edges[key] + @new_edges[key] = @edges[key] || begin + bridge = Vertex.new(@node) + src.add_edge(genv, bridge) + bridge.add_edge(genv, dst) + bridge + end end # TODO: if an edge is removed during one analysis, we may need to remove sub-boxes? @@ -158,12 +165,12 @@ def add_depended_superclass(mod) end def reinstall(genv) - @new_edges.uniq! - @new_edges.each do |src, dst| - src.add_edge(genv, dst) unless @edges.include?([src, dst]) - end - @edges.each do |src, dst| - src.remove_edge(genv, dst) unless @new_edges.include?([src, dst]) + @edges.each do |key, bridge| + unless @new_edges.key?(key) + src, dst = key + src.remove_edge(genv, bridge) + bridge.remove_edge(genv, dst) + end end @edges, @new_edges = @new_edges, @edges @new_edges.clear diff --git a/scenario/control/break2.rb b/scenario/control/break2.rb new file mode 100644 index 00000000..6daa4592 --- /dev/null +++ b/scenario/control/break2.rb @@ -0,0 +1,67 @@ +## update +def foo + count = 0 + loop do + count += 1 + break count if count == 3 + end +end + +## assert +class Object + def foo: -> Integer +end + +## update +def foo + count = 0 + loop do + count += 1 + begin + break count if count == 3 + rescue + break count + end + end +end + +## assert +class Object + def foo: -> Integer +end + +## update +def foo + count = 0 + loop do + count += 1 + begin + break count if count == 3 + rescue + break 'str' + end + end +end + +## assert +class Object + def foo: -> (Integer | String) +end + +## update +def foo + count = 0 + loop do + count += 1 + begin + # break count if count == 3 + rescue + break 'str' + end + end +end + +## assert +class Object + def foo: -> String +end