diff --git a/lib/typeprof/core/ast/misc.rb b/lib/typeprof/core/ast/misc.rb index cf69b92b7..9c94bc5ed 100644 --- a/lib/typeprof/core/ast/misc.rb +++ b/lib/typeprof/core/ast/misc.rb @@ -265,19 +265,39 @@ def install0(genv) class ForNode < Node def initialize(raw_node, lenv) super(raw_node, lenv) - # XXX: tentative implementation - # raw_node.index + @index = AST.create_target_node(raw_node.index, lenv) @expr = AST.create_node(raw_node.collection, lenv) @body = raw_node.statements ? AST.create_node(raw_node.statements, lenv) : DummyNilNode.new(TypeProf::CodeRange.new(code_range.last, code_range.last), lenv) end - attr_reader :expr, :body + attr_reader :index, :expr, :body - def subnodes = { expr:, body: } + def subnodes = { index:, expr:, body: } def install0(genv) @expr.install(genv) + + vars = [] + @index.modified_vars(@lenv.locals.keys, vars) + @body.modified_vars(@lenv.locals.keys, vars) + vars.uniq! + + old_vtxs = {} + vars.each do |var| + vtx = @lenv.get_var(var) + nvtx = vtx.new_vertex(genv, self) + old_vtxs[var] = nvtx + @lenv.set_var(var, nvtx) + end + + @index.install(genv) @body.install(genv) + + vars.each do |var| + @changes.add_edge(genv, @lenv.get_var(var), old_vtxs[var]) + @lenv.set_var(var, old_vtxs[var]) + end + Source.new(genv.nil_type) end end diff --git a/lib/typeprof/core/env.rb b/lib/typeprof/core/env.rb index 6da8d0b2d..911174687 100644 --- a/lib/typeprof/core/env.rb +++ b/lib/typeprof/core/env.rb @@ -333,8 +333,6 @@ def initialize(file_context, cref, locals, return_boxes) attr_reader :file_context, :cref, :locals, :return_boxes, :break_vtx, :next_boxes, :strict_const_scope def path = @file_context&.path - def code_units_cache = @file_context&.code_units_cache - def code_range_from_node(node) TypeProf::CodeRange.from_node(node, @file_context&.code_units_cache) end diff --git a/scenario/misc/for-variable-leak.rb b/scenario/misc/for-variable-leak.rb new file mode 100644 index 000000000..2a04d1f72 --- /dev/null +++ b/scenario/misc/for-variable-leak.rb @@ -0,0 +1,13 @@ +## update +def foo + x = "hello" + for i in [1, 2, 3] + x = 42 + end + x +end + +## assert +class Object + def foo: -> (Integer | String) +end diff --git a/scenario/misc/for.rb b/scenario/misc/for.rb index e4fc8e011..718dd2dfc 100644 --- a/scenario/misc/for.rb +++ b/scenario/misc/for.rb @@ -1,7 +1,6 @@ ## update def foo for i in 1..100 - # currently, TypeProf does not initialize i return 1 end end