typeprof 0.21.11 → 0.30.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/README.md +15 -31
 - data/bin/typeprof +5 -0
 - data/doc/doc.ja.md +134 -0
 - data/doc/doc.md +136 -0
 - data/lib/typeprof/cli/cli.rb +180 -0
 - data/lib/typeprof/cli.rb +2 -133
 - data/lib/typeprof/code_range.rb +112 -0
 - data/lib/typeprof/core/ast/base.rb +263 -0
 - data/lib/typeprof/core/ast/call.rb +251 -0
 - data/lib/typeprof/core/ast/const.rb +126 -0
 - data/lib/typeprof/core/ast/control.rb +432 -0
 - data/lib/typeprof/core/ast/meta.rb +150 -0
 - data/lib/typeprof/core/ast/method.rb +335 -0
 - data/lib/typeprof/core/ast/misc.rb +263 -0
 - data/lib/typeprof/core/ast/module.rb +123 -0
 - data/lib/typeprof/core/ast/pattern.rb +140 -0
 - data/lib/typeprof/core/ast/sig_decl.rb +471 -0
 - data/lib/typeprof/core/ast/sig_type.rb +663 -0
 - data/lib/typeprof/core/ast/value.rb +319 -0
 - data/lib/typeprof/core/ast/variable.rb +315 -0
 - data/lib/typeprof/core/ast.rb +472 -0
 - data/lib/typeprof/core/builtin.rb +146 -0
 - data/lib/typeprof/core/env/method.rb +137 -0
 - data/lib/typeprof/core/env/method_entity.rb +55 -0
 - data/lib/typeprof/core/env/module_entity.rb +408 -0
 - data/lib/typeprof/core/env/static_read.rb +155 -0
 - data/lib/typeprof/core/env/type_alias_entity.rb +27 -0
 - data/lib/typeprof/core/env/value_entity.rb +32 -0
 - data/lib/typeprof/core/env.rb +360 -0
 - data/lib/typeprof/core/graph/box.rb +991 -0
 - data/lib/typeprof/core/graph/change_set.rb +224 -0
 - data/lib/typeprof/core/graph/filter.rb +155 -0
 - data/lib/typeprof/core/graph/vertex.rb +222 -0
 - data/lib/typeprof/core/graph.rb +3 -0
 - data/lib/typeprof/core/service.rb +522 -0
 - data/lib/typeprof/core/type.rb +348 -0
 - data/lib/typeprof/core/util.rb +81 -0
 - data/lib/typeprof/core.rb +32 -0
 - data/lib/typeprof/diagnostic.rb +35 -0
 - data/lib/typeprof/lsp/messages.rb +430 -0
 - data/lib/typeprof/lsp/server.rb +177 -0
 - data/lib/typeprof/lsp/text.rb +69 -0
 - data/lib/typeprof/lsp/util.rb +61 -0
 - data/lib/typeprof/lsp.rb +4 -907
 - data/lib/typeprof/version.rb +1 -1
 - data/lib/typeprof.rb +4 -18
 - data/typeprof.gemspec +5 -7
 - metadata +48 -35
 - data/.github/dependabot.yml +0 -6
 - data/.github/workflows/main.yml +0 -39
 - data/.gitignore +0 -9
 - data/Gemfile +0 -17
 - data/Gemfile.lock +0 -41
 - data/Rakefile +0 -10
 - data/exe/typeprof +0 -10
 - data/lib/typeprof/analyzer.rb +0 -2598
 - data/lib/typeprof/arguments.rb +0 -414
 - data/lib/typeprof/block.rb +0 -176
 - data/lib/typeprof/builtin.rb +0 -893
 - data/lib/typeprof/code-range.rb +0 -177
 - data/lib/typeprof/config.rb +0 -158
 - data/lib/typeprof/container-type.rb +0 -912
 - data/lib/typeprof/export.rb +0 -589
 - data/lib/typeprof/import.rb +0 -852
 - data/lib/typeprof/insns-def.rb +0 -65
 - data/lib/typeprof/iseq.rb +0 -864
 - data/lib/typeprof/method.rb +0 -355
 - data/lib/typeprof/type.rb +0 -1140
 - data/lib/typeprof/utils.rb +0 -212
 - data/tools/coverage.rb +0 -14
 - data/tools/setup-insns-def.rb +0 -30
 - data/typeprof-lsp +0 -3
 
| 
         @@ -0,0 +1,126 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module TypeProf::Core
         
     | 
| 
      
 2 
     | 
    
         
            +
              class AST
         
     | 
| 
      
 3 
     | 
    
         
            +
                class ConstantReadNode < Node
         
     | 
| 
      
 4 
     | 
    
         
            +
                  def initialize(raw_node, lenv)
         
     | 
| 
      
 5 
     | 
    
         
            +
                    super(raw_node, lenv)
         
     | 
| 
      
 6 
     | 
    
         
            +
                    case raw_node.type
         
     | 
| 
      
 7 
     | 
    
         
            +
                    when :constant_read_node, :constant_operator_write_node, :constant_or_write_node, :constant_and_write_node
         
     | 
| 
      
 8 
     | 
    
         
            +
                      @cbase = nil
         
     | 
| 
      
 9 
     | 
    
         
            +
                      @toplevel = false
         
     | 
| 
      
 10 
     | 
    
         
            +
                      @cname = raw_node.name
         
     | 
| 
      
 11 
     | 
    
         
            +
                      @cname_code_range = TypeProf::CodeRange.from_node(raw_node.location)
         
     | 
| 
      
 12 
     | 
    
         
            +
                    when :constant_path_node, :constant_path_target_node
         
     | 
| 
      
 13 
     | 
    
         
            +
                      if raw_node.parent
         
     | 
| 
      
 14 
     | 
    
         
            +
                        @cbase = AST.create_node(raw_node.parent, lenv)
         
     | 
| 
      
 15 
     | 
    
         
            +
                        @toplevel = false
         
     | 
| 
      
 16 
     | 
    
         
            +
                      else
         
     | 
| 
      
 17 
     | 
    
         
            +
                        @cbase = nil
         
     | 
| 
      
 18 
     | 
    
         
            +
                        @toplevel = true
         
     | 
| 
      
 19 
     | 
    
         
            +
                      end
         
     | 
| 
      
 20 
     | 
    
         
            +
                      # temporarily support old Prism https://bugs.ruby-lang.org/issues/20467
         
     | 
| 
      
 21 
     | 
    
         
            +
                      if raw_node.respond_to?(:name)
         
     | 
| 
      
 22 
     | 
    
         
            +
                        @cname = raw_node.name
         
     | 
| 
      
 23 
     | 
    
         
            +
                        @cname_code_range = TypeProf::CodeRange.from_node(raw_node.name_loc)
         
     | 
| 
      
 24 
     | 
    
         
            +
                      else
         
     | 
| 
      
 25 
     | 
    
         
            +
                        @cname = raw_node.child.name
         
     | 
| 
      
 26 
     | 
    
         
            +
                        @cname_code_range = TypeProf::CodeRange.from_node(raw_node.child.location)
         
     | 
| 
      
 27 
     | 
    
         
            +
                      end
         
     | 
| 
      
 28 
     | 
    
         
            +
                    else
         
     | 
| 
      
 29 
     | 
    
         
            +
                      raise raw_node.type.to_s
         
     | 
| 
      
 30 
     | 
    
         
            +
                    end
         
     | 
| 
      
 31 
     | 
    
         
            +
                  end
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                  attr_reader :cname, :cbase, :toplevel, :cname_code_range
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                  def attrs = { cname:, toplevel: }
         
     | 
| 
      
 36 
     | 
    
         
            +
                  def subnodes = { cbase: }
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                  def define0(genv)
         
     | 
| 
      
 39 
     | 
    
         
            +
                    if @cbase
         
     | 
| 
      
 40 
     | 
    
         
            +
                      ScopedConstRead.new(@cname, @cbase.define(genv))
         
     | 
| 
      
 41 
     | 
    
         
            +
                    else
         
     | 
| 
      
 42 
     | 
    
         
            +
                      BaseConstRead.new(genv, @cname, @toplevel ? CRef::Toplevel : @lenv.cref)
         
     | 
| 
      
 43 
     | 
    
         
            +
                    end
         
     | 
| 
      
 44 
     | 
    
         
            +
                  end
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
                  def undefine0(genv)
         
     | 
| 
      
 47 
     | 
    
         
            +
                    @static_ret.destroy(genv)
         
     | 
| 
      
 48 
     | 
    
         
            +
                  end
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
                  def install0(genv)
         
     | 
| 
      
 51 
     | 
    
         
            +
                    @cbase.install(genv) if @cbase
         
     | 
| 
      
 52 
     | 
    
         
            +
                    box = @changes.add_const_read_box(genv, @static_ret)
         
     | 
| 
      
 53 
     | 
    
         
            +
                    box.ret
         
     | 
| 
      
 54 
     | 
    
         
            +
                  end
         
     | 
| 
      
 55 
     | 
    
         
            +
                end
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
                class ConstantWriteNode < Node
         
     | 
| 
      
 58 
     | 
    
         
            +
                  def initialize(raw_node, rhs, lenv)
         
     | 
| 
      
 59 
     | 
    
         
            +
                    super(raw_node, lenv)
         
     | 
| 
      
 60 
     | 
    
         
            +
                    case raw_node.type
         
     | 
| 
      
 61 
     | 
    
         
            +
                    when :constant_write_node, :constant_target_node, :constant_operator_write_node, :constant_or_write_node, :constant_and_write_node
         
     | 
| 
      
 62 
     | 
    
         
            +
                      # C = expr
         
     | 
| 
      
 63 
     | 
    
         
            +
                      @cpath = nil
         
     | 
| 
      
 64 
     | 
    
         
            +
                      @static_cpath = lenv.cref.cpath + [raw_node.name]
         
     | 
| 
      
 65 
     | 
    
         
            +
                      @cname_code_range = TypeProf::CodeRange.from_node(raw_node.respond_to?(:name_loc) ? raw_node.name_loc : raw_node)
         
     | 
| 
      
 66 
     | 
    
         
            +
                    when :constant_path_write_node, :constant_path_operator_write_node, :constant_path_or_write_node, :constant_path_and_write_node
         
     | 
| 
      
 67 
     | 
    
         
            +
                      # expr::C = expr
         
     | 
| 
      
 68 
     | 
    
         
            +
                      @cpath = AST.create_node(raw_node.target, lenv)
         
     | 
| 
      
 69 
     | 
    
         
            +
                      @static_cpath = AST.parse_cpath(raw_node.target, lenv.cref)
         
     | 
| 
      
 70 
     | 
    
         
            +
                      @cname_code_range = TypeProf::CodeRange.from_node(raw_node.target)
         
     | 
| 
      
 71 
     | 
    
         
            +
                    when :constant_path_target_node
         
     | 
| 
      
 72 
     | 
    
         
            +
                      # expr::C, * = ary
         
     | 
| 
      
 73 
     | 
    
         
            +
                      @cpath = ConstantReadNode.new(raw_node, lenv)
         
     | 
| 
      
 74 
     | 
    
         
            +
                      @static_cpath = AST.parse_cpath(raw_node, lenv.cref)
         
     | 
| 
      
 75 
     | 
    
         
            +
                      @cname_code_range = TypeProf::CodeRange.from_node(raw_node)
         
     | 
| 
      
 76 
     | 
    
         
            +
                    else
         
     | 
| 
      
 77 
     | 
    
         
            +
                      raise
         
     | 
| 
      
 78 
     | 
    
         
            +
                    end
         
     | 
| 
      
 79 
     | 
    
         
            +
                    @rhs = rhs
         
     | 
| 
      
 80 
     | 
    
         
            +
                  end
         
     | 
| 
      
 81 
     | 
    
         
            +
             
     | 
| 
      
 82 
     | 
    
         
            +
                  attr_reader :cpath, :rhs, :static_cpath, :cname_code_range
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
                  def subnodes = { cpath:, rhs: }
         
     | 
| 
      
 85 
     | 
    
         
            +
                  def attrs = { static_cpath: }
         
     | 
| 
      
 86 
     | 
    
         
            +
             
     | 
| 
      
 87 
     | 
    
         
            +
                  def define0(genv)
         
     | 
| 
      
 88 
     | 
    
         
            +
                    @cpath.define(genv) if @cpath
         
     | 
| 
      
 89 
     | 
    
         
            +
                    @rhs.define(genv) if @rhs
         
     | 
| 
      
 90 
     | 
    
         
            +
                    if @static_cpath
         
     | 
| 
      
 91 
     | 
    
         
            +
                      mod = genv.resolve_const(@static_cpath)
         
     | 
| 
      
 92 
     | 
    
         
            +
                      mod.add_def(self)
         
     | 
| 
      
 93 
     | 
    
         
            +
                      mod
         
     | 
| 
      
 94 
     | 
    
         
            +
                    else
         
     | 
| 
      
 95 
     | 
    
         
            +
                      nil
         
     | 
| 
      
 96 
     | 
    
         
            +
                    end
         
     | 
| 
      
 97 
     | 
    
         
            +
                  end
         
     | 
| 
      
 98 
     | 
    
         
            +
             
     | 
| 
      
 99 
     | 
    
         
            +
                  def define_copy(genv)
         
     | 
| 
      
 100 
     | 
    
         
            +
                    if @static_cpath
         
     | 
| 
      
 101 
     | 
    
         
            +
                      mod = genv.resolve_const(@static_cpath)
         
     | 
| 
      
 102 
     | 
    
         
            +
                      mod.add_def(self)
         
     | 
| 
      
 103 
     | 
    
         
            +
                      mod.remove_def(@prev_node)
         
     | 
| 
      
 104 
     | 
    
         
            +
                    end
         
     | 
| 
      
 105 
     | 
    
         
            +
                    super(genv)
         
     | 
| 
      
 106 
     | 
    
         
            +
                  end
         
     | 
| 
      
 107 
     | 
    
         
            +
             
     | 
| 
      
 108 
     | 
    
         
            +
                  def undefine0(genv)
         
     | 
| 
      
 109 
     | 
    
         
            +
                    if @static_cpath
         
     | 
| 
      
 110 
     | 
    
         
            +
                      genv.resolve_const(@static_cpath).remove_def(self)
         
     | 
| 
      
 111 
     | 
    
         
            +
                    end
         
     | 
| 
      
 112 
     | 
    
         
            +
                    @rhs.undefine(genv) if @rhs
         
     | 
| 
      
 113 
     | 
    
         
            +
                    @cpath.undefine(genv) if @cpath
         
     | 
| 
      
 114 
     | 
    
         
            +
                  end
         
     | 
| 
      
 115 
     | 
    
         
            +
             
     | 
| 
      
 116 
     | 
    
         
            +
                  def install0(genv)
         
     | 
| 
      
 117 
     | 
    
         
            +
                    @cpath.install(genv) if @cpath
         
     | 
| 
      
 118 
     | 
    
         
            +
                    val = @rhs.install(genv)
         
     | 
| 
      
 119 
     | 
    
         
            +
                    if @static_cpath
         
     | 
| 
      
 120 
     | 
    
         
            +
                      @changes.add_edge(genv, val, @static_ret.vtx)
         
     | 
| 
      
 121 
     | 
    
         
            +
                    end
         
     | 
| 
      
 122 
     | 
    
         
            +
                    val
         
     | 
| 
      
 123 
     | 
    
         
            +
                  end
         
     | 
| 
      
 124 
     | 
    
         
            +
                end
         
     | 
| 
      
 125 
     | 
    
         
            +
              end
         
     | 
| 
      
 126 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,432 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module TypeProf::Core
         
     | 
| 
      
 2 
     | 
    
         
            +
              class AST
         
     | 
| 
      
 3 
     | 
    
         
            +
                def self.is_a_class(node)
         
     | 
| 
      
 4 
     | 
    
         
            +
                  if node.is_a?(CallNode)
         
     | 
| 
      
 5 
     | 
    
         
            +
                    recv = node.recv
         
     | 
| 
      
 6 
     | 
    
         
            +
                    if recv.is_a?(LocalVariableReadNode)
         
     | 
| 
      
 7 
     | 
    
         
            +
                      if node.positional_args && node.positional_args.size == 1 && node.positional_args[0].static_ret
         
     | 
| 
      
 8 
     | 
    
         
            +
                        # TODO: need static resolusion of a constant
         
     | 
| 
      
 9 
     | 
    
         
            +
                        return [recv.var, node.positional_args[0].static_ret]
         
     | 
| 
      
 10 
     | 
    
         
            +
                      end
         
     | 
| 
      
 11 
     | 
    
         
            +
                    end
         
     | 
| 
      
 12 
     | 
    
         
            +
                  end
         
     | 
| 
      
 13 
     | 
    
         
            +
                  return nil
         
     | 
| 
      
 14 
     | 
    
         
            +
                end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                class BranchNode < Node
         
     | 
| 
      
 17 
     | 
    
         
            +
                  def initialize(raw_node, lenv)
         
     | 
| 
      
 18 
     | 
    
         
            +
                    super(raw_node, lenv)
         
     | 
| 
      
 19 
     | 
    
         
            +
                    @cond = AST.create_node(raw_node.predicate, lenv)
         
     | 
| 
      
 20 
     | 
    
         
            +
                    @then = raw_node.statements ? AST.create_node(raw_node.statements, lenv) : nil
         
     | 
| 
      
 21 
     | 
    
         
            +
                    else_clause = raw_node.is_a?(Prism::IfNode) ? raw_node.subsequent : raw_node.else_clause
         
     | 
| 
      
 22 
     | 
    
         
            +
                    if else_clause
         
     | 
| 
      
 23 
     | 
    
         
            +
                      else_clause = else_clause.statements if else_clause.type == :else_node
         
     | 
| 
      
 24 
     | 
    
         
            +
                      @else = else_clause ? AST.create_node(else_clause, lenv) : nil
         
     | 
| 
      
 25 
     | 
    
         
            +
                    else
         
     | 
| 
      
 26 
     | 
    
         
            +
                      @else = nil
         
     | 
| 
      
 27 
     | 
    
         
            +
                    end
         
     | 
| 
      
 28 
     | 
    
         
            +
                  end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                  attr_reader :cond, :then, :else
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                  def subnodes = { cond:, then:, else: }
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                  def install0(genv)
         
     | 
| 
      
 35 
     | 
    
         
            +
                    ret = Vertex.new(self)
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                    @cond.install(genv)
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
                    vars = []
         
     | 
| 
      
 40 
     | 
    
         
            +
                    vars << @cond.var if @cond.is_a?(LocalVariableReadNode)
         
     | 
| 
      
 41 
     | 
    
         
            +
                    var, filter_class = AST.is_a_class(@cond)
         
     | 
| 
      
 42 
     | 
    
         
            +
                    vars << var if var
         
     | 
| 
      
 43 
     | 
    
         
            +
                    @then.modified_vars(@lenv.locals.keys, vars) if @then
         
     | 
| 
      
 44 
     | 
    
         
            +
                    @else.modified_vars(@lenv.locals.keys, vars) if @else
         
     | 
| 
      
 45 
     | 
    
         
            +
                    modified_vtxs = {}
         
     | 
| 
      
 46 
     | 
    
         
            +
                    vars.uniq.each do |var|
         
     | 
| 
      
 47 
     | 
    
         
            +
                      vtx = @lenv.get_var(var)
         
     | 
| 
      
 48 
     | 
    
         
            +
                      nvtx_then = vtx.new_vertex(genv, self)
         
     | 
| 
      
 49 
     | 
    
         
            +
                      nvtx_else = vtx.new_vertex(genv, self)
         
     | 
| 
      
 50 
     | 
    
         
            +
                      modified_vtxs[var] = [nvtx_then, nvtx_else]
         
     | 
| 
      
 51 
     | 
    
         
            +
                    end
         
     | 
| 
      
 52 
     | 
    
         
            +
                    if @cond.is_a?(LocalVariableReadNode)
         
     | 
| 
      
 53 
     | 
    
         
            +
                      nvtx_then, nvtx_else = modified_vtxs[@cond.var]
         
     | 
| 
      
 54 
     | 
    
         
            +
                      nvtx_then = NilFilter.new(genv, self, nvtx_then, !self.is_a?(IfNode)).next_vtx
         
     | 
| 
      
 55 
     | 
    
         
            +
                      nvtx_else = NilFilter.new(genv, self, nvtx_else, self.is_a?(IfNode)).next_vtx
         
     | 
| 
      
 56 
     | 
    
         
            +
                      modified_vtxs[@cond.var] = [nvtx_then, nvtx_else]
         
     | 
| 
      
 57 
     | 
    
         
            +
                    end
         
     | 
| 
      
 58 
     | 
    
         
            +
                    if filter_class
         
     | 
| 
      
 59 
     | 
    
         
            +
                      nvtx_then, nvtx_else = modified_vtxs[var]
         
     | 
| 
      
 60 
     | 
    
         
            +
                      nvtx_then = IsAFilter.new(genv, self, nvtx_then, !self.is_a?(IfNode), filter_class).next_vtx
         
     | 
| 
      
 61 
     | 
    
         
            +
                      nvtx_else = IsAFilter.new(genv, self, nvtx_else, self.is_a?(IfNode), filter_class).next_vtx
         
     | 
| 
      
 62 
     | 
    
         
            +
                      modified_vtxs[var] = [nvtx_then, nvtx_else]
         
     | 
| 
      
 63 
     | 
    
         
            +
                    end
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
                    if @then
         
     | 
| 
      
 66 
     | 
    
         
            +
                      modified_vtxs.each do |var, (nvtx_then, _)|
         
     | 
| 
      
 67 
     | 
    
         
            +
                        @lenv.set_var(var, nvtx_then)
         
     | 
| 
      
 68 
     | 
    
         
            +
                      end
         
     | 
| 
      
 69 
     | 
    
         
            +
                      if @cond.is_a?(InstanceVariableReadNode)
         
     | 
| 
      
 70 
     | 
    
         
            +
                        @lenv.push_read_filter(@cond.var, :non_nil)
         
     | 
| 
      
 71 
     | 
    
         
            +
                      end
         
     | 
| 
      
 72 
     | 
    
         
            +
                      then_val = @then.install(genv)
         
     | 
| 
      
 73 
     | 
    
         
            +
                      if @cond.is_a?(InstanceVariableReadNode)
         
     | 
| 
      
 74 
     | 
    
         
            +
                        @lenv.pop_read_filter(@cond.var)
         
     | 
| 
      
 75 
     | 
    
         
            +
                      end
         
     | 
| 
      
 76 
     | 
    
         
            +
                      modified_vtxs.each do |var, ary|
         
     | 
| 
      
 77 
     | 
    
         
            +
                        ary[0] = @lenv.get_var(var)
         
     | 
| 
      
 78 
     | 
    
         
            +
                      end
         
     | 
| 
      
 79 
     | 
    
         
            +
                    else
         
     | 
| 
      
 80 
     | 
    
         
            +
                      then_val = Source.new(genv.nil_type)
         
     | 
| 
      
 81 
     | 
    
         
            +
                    end
         
     | 
| 
      
 82 
     | 
    
         
            +
                    @changes.add_edge(genv, then_val, ret)
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
                    if @else
         
     | 
| 
      
 85 
     | 
    
         
            +
                      modified_vtxs.each do |var, (_, nvtx_else)|
         
     | 
| 
      
 86 
     | 
    
         
            +
                        @lenv.set_var(var, nvtx_else)
         
     | 
| 
      
 87 
     | 
    
         
            +
                      end
         
     | 
| 
      
 88 
     | 
    
         
            +
                      else_val = @else.install(genv)
         
     | 
| 
      
 89 
     | 
    
         
            +
                      modified_vtxs.each do |var, ary|
         
     | 
| 
      
 90 
     | 
    
         
            +
                        ary[1] = @lenv.get_var(var)
         
     | 
| 
      
 91 
     | 
    
         
            +
                      end
         
     | 
| 
      
 92 
     | 
    
         
            +
                    else
         
     | 
| 
      
 93 
     | 
    
         
            +
                      else_val = Source.new(genv.nil_type)
         
     | 
| 
      
 94 
     | 
    
         
            +
                    end
         
     | 
| 
      
 95 
     | 
    
         
            +
                    @changes.add_edge(genv, else_val, ret)
         
     | 
| 
      
 96 
     | 
    
         
            +
             
     | 
| 
      
 97 
     | 
    
         
            +
                    modified_vtxs.each do |var, (nvtx_then, nvtx_else)|
         
     | 
| 
      
 98 
     | 
    
         
            +
                      nvtx_then = BotFilter.new(genv, self, nvtx_then, then_val).next_vtx
         
     | 
| 
      
 99 
     | 
    
         
            +
                      nvtx_else = BotFilter.new(genv, self, nvtx_else, else_val).next_vtx
         
     | 
| 
      
 100 
     | 
    
         
            +
                      nvtx_join = nvtx_then.new_vertex(genv, self)
         
     | 
| 
      
 101 
     | 
    
         
            +
                      @changes.add_edge(genv, nvtx_else, nvtx_join)
         
     | 
| 
      
 102 
     | 
    
         
            +
                      @lenv.set_var(var, nvtx_join)
         
     | 
| 
      
 103 
     | 
    
         
            +
                    end
         
     | 
| 
      
 104 
     | 
    
         
            +
             
     | 
| 
      
 105 
     | 
    
         
            +
                    ret
         
     | 
| 
      
 106 
     | 
    
         
            +
                  end
         
     | 
| 
      
 107 
     | 
    
         
            +
                end
         
     | 
| 
      
 108 
     | 
    
         
            +
             
     | 
| 
      
 109 
     | 
    
         
            +
                class IfNode < BranchNode
         
     | 
| 
      
 110 
     | 
    
         
            +
                end
         
     | 
| 
      
 111 
     | 
    
         
            +
             
     | 
| 
      
 112 
     | 
    
         
            +
                class UnlessNode < BranchNode
         
     | 
| 
      
 113 
     | 
    
         
            +
                end
         
     | 
| 
      
 114 
     | 
    
         
            +
             
     | 
| 
      
 115 
     | 
    
         
            +
                class LoopNode < Node
         
     | 
| 
      
 116 
     | 
    
         
            +
                  def initialize(raw_node, lenv)
         
     | 
| 
      
 117 
     | 
    
         
            +
                    super(raw_node, lenv)
         
     | 
| 
      
 118 
     | 
    
         
            +
                    @cond = AST.create_node(raw_node.predicate, lenv)
         
     | 
| 
      
 119 
     | 
    
         
            +
                    @body = raw_node.statements ? AST.create_node(raw_node.statements, lenv) : DummyNilNode.new(code_range, lenv)
         
     | 
| 
      
 120 
     | 
    
         
            +
                  end
         
     | 
| 
      
 121 
     | 
    
         
            +
             
     | 
| 
      
 122 
     | 
    
         
            +
                  attr_reader :cond, :body
         
     | 
| 
      
 123 
     | 
    
         
            +
             
     | 
| 
      
 124 
     | 
    
         
            +
                  def subnodes = { cond:, body: }
         
     | 
| 
      
 125 
     | 
    
         
            +
             
     | 
| 
      
 126 
     | 
    
         
            +
                  def install0(genv)
         
     | 
| 
      
 127 
     | 
    
         
            +
                    vars = []
         
     | 
| 
      
 128 
     | 
    
         
            +
                    vars << @cond.var if @cond.is_a?(LocalVariableReadNode)
         
     | 
| 
      
 129 
     | 
    
         
            +
                    @cond.modified_vars(@lenv.locals.keys, vars)
         
     | 
| 
      
 130 
     | 
    
         
            +
                    @body.modified_vars(@lenv.locals.keys, vars)
         
     | 
| 
      
 131 
     | 
    
         
            +
                    vars.uniq!
         
     | 
| 
      
 132 
     | 
    
         
            +
                    old_vtxs = {}
         
     | 
| 
      
 133 
     | 
    
         
            +
                    vars.each do |var|
         
     | 
| 
      
 134 
     | 
    
         
            +
                      vtx = @lenv.get_var(var)
         
     | 
| 
      
 135 
     | 
    
         
            +
                      nvtx = vtx.new_vertex(genv, self)
         
     | 
| 
      
 136 
     | 
    
         
            +
                      old_vtxs[var] = nvtx
         
     | 
| 
      
 137 
     | 
    
         
            +
                      @lenv.set_var(var, nvtx)
         
     | 
| 
      
 138 
     | 
    
         
            +
                    end
         
     | 
| 
      
 139 
     | 
    
         
            +
             
     | 
| 
      
 140 
     | 
    
         
            +
                    @cond.install(genv)
         
     | 
| 
      
 141 
     | 
    
         
            +
                    if @cond.is_a?(LocalVariableReadNode)
         
     | 
| 
      
 142 
     | 
    
         
            +
                      nvtx_then = NilFilter.new(genv, self, old_vtxs[@cond.var], self.is_a?(UntilNode)).next_vtx
         
     | 
| 
      
 143 
     | 
    
         
            +
                      @lenv.set_var(@cond.var, nvtx_then)
         
     | 
| 
      
 144 
     | 
    
         
            +
                    end
         
     | 
| 
      
 145 
     | 
    
         
            +
             
     | 
| 
      
 146 
     | 
    
         
            +
                    if @lenv.exist_var?(:"*expected_block_ret")
         
     | 
| 
      
 147 
     | 
    
         
            +
                      expected_block_ret = @lenv.locals[:"*expected_block_ret"]
         
     | 
| 
      
 148 
     | 
    
         
            +
                      @lenv.set_var(:"*expected_block_ret", nil)
         
     | 
| 
      
 149 
     | 
    
         
            +
                    end
         
     | 
| 
      
 150 
     | 
    
         
            +
             
     | 
| 
      
 151 
     | 
    
         
            +
                    @body.install(genv)
         
     | 
| 
      
 152 
     | 
    
         
            +
             
     | 
| 
      
 153 
     | 
    
         
            +
                    if expected_block_ret
         
     | 
| 
      
 154 
     | 
    
         
            +
                      @lenv.set_var(:"*expected_block_ret", expected_block_ret)
         
     | 
| 
      
 155 
     | 
    
         
            +
                    end
         
     | 
| 
      
 156 
     | 
    
         
            +
             
     | 
| 
      
 157 
     | 
    
         
            +
                    vars.each do |var|
         
     | 
| 
      
 158 
     | 
    
         
            +
                      @changes.add_edge(genv, @lenv.get_var(var), old_vtxs[var])
         
     | 
| 
      
 159 
     | 
    
         
            +
                      @lenv.set_var(var, old_vtxs[var])
         
     | 
| 
      
 160 
     | 
    
         
            +
                    end
         
     | 
| 
      
 161 
     | 
    
         
            +
                    if @cond.is_a?(LocalVariableReadNode)
         
     | 
| 
      
 162 
     | 
    
         
            +
                      nvtx_then = NilFilter.new(genv, self, old_vtxs[@cond.var], !self.is_a?(UntilNode)).next_vtx
         
     | 
| 
      
 163 
     | 
    
         
            +
                      @lenv.set_var(@cond.var, nvtx_then)
         
     | 
| 
      
 164 
     | 
    
         
            +
                    end
         
     | 
| 
      
 165 
     | 
    
         
            +
             
     | 
| 
      
 166 
     | 
    
         
            +
                    Source.new(genv.nil_type)
         
     | 
| 
      
 167 
     | 
    
         
            +
                  end
         
     | 
| 
      
 168 
     | 
    
         
            +
                end
         
     | 
| 
      
 169 
     | 
    
         
            +
             
     | 
| 
      
 170 
     | 
    
         
            +
                class WhileNode < LoopNode
         
     | 
| 
      
 171 
     | 
    
         
            +
                end
         
     | 
| 
      
 172 
     | 
    
         
            +
             
     | 
| 
      
 173 
     | 
    
         
            +
                class UntilNode < LoopNode
         
     | 
| 
      
 174 
     | 
    
         
            +
                end
         
     | 
| 
      
 175 
     | 
    
         
            +
             
     | 
| 
      
 176 
     | 
    
         
            +
                class BreakNode < Node
         
     | 
| 
      
 177 
     | 
    
         
            +
                  def initialize(raw_node, lenv)
         
     | 
| 
      
 178 
     | 
    
         
            +
                    super(raw_node, lenv)
         
     | 
| 
      
 179 
     | 
    
         
            +
                    @arg = raw_node.arguments ? AST.create_node(raw_node.arguments.arguments.first, lenv) : nil
         
     | 
| 
      
 180 
     | 
    
         
            +
                  end
         
     | 
| 
      
 181 
     | 
    
         
            +
             
     | 
| 
      
 182 
     | 
    
         
            +
                  attr_reader :arg
         
     | 
| 
      
 183 
     | 
    
         
            +
             
     | 
| 
      
 184 
     | 
    
         
            +
                  def subnodes = { arg: }
         
     | 
| 
      
 185 
     | 
    
         
            +
             
     | 
| 
      
 186 
     | 
    
         
            +
                  def install0(genv)
         
     | 
| 
      
 187 
     | 
    
         
            +
                    _arg = @arg ? @arg.install(genv) : Source.new(genv.nil_type)
         
     | 
| 
      
 188 
     | 
    
         
            +
                    # TODO: implement!
         
     | 
| 
      
 189 
     | 
    
         
            +
                  end
         
     | 
| 
      
 190 
     | 
    
         
            +
                end
         
     | 
| 
      
 191 
     | 
    
         
            +
             
     | 
| 
      
 192 
     | 
    
         
            +
                def self.parse_return_arguments(raw_node, lenv, code_range)
         
     | 
| 
      
 193 
     | 
    
         
            +
                  if raw_node.arguments
         
     | 
| 
      
 194 
     | 
    
         
            +
                    elems = raw_node.arguments.arguments
         
     | 
| 
      
 195 
     | 
    
         
            +
                    if elems.one?
         
     | 
| 
      
 196 
     | 
    
         
            +
                      AST.create_node(elems.first, lenv)
         
     | 
| 
      
 197 
     | 
    
         
            +
                    else
         
     | 
| 
      
 198 
     | 
    
         
            +
                      ArrayNode.new(raw_node.arguments, lenv, elems)
         
     | 
| 
      
 199 
     | 
    
         
            +
                    end
         
     | 
| 
      
 200 
     | 
    
         
            +
                  else
         
     | 
| 
      
 201 
     | 
    
         
            +
                    DummyNilNode.new(code_range, lenv)
         
     | 
| 
      
 202 
     | 
    
         
            +
                  end
         
     | 
| 
      
 203 
     | 
    
         
            +
                end
         
     | 
| 
      
 204 
     | 
    
         
            +
             
     | 
| 
      
 205 
     | 
    
         
            +
                class NextNode < Node
         
     | 
| 
      
 206 
     | 
    
         
            +
                  def initialize(raw_node, lenv)
         
     | 
| 
      
 207 
     | 
    
         
            +
                    super(raw_node, lenv)
         
     | 
| 
      
 208 
     | 
    
         
            +
                    @arg = AST.parse_return_arguments(raw_node, lenv, code_range)
         
     | 
| 
      
 209 
     | 
    
         
            +
                  end
         
     | 
| 
      
 210 
     | 
    
         
            +
             
     | 
| 
      
 211 
     | 
    
         
            +
                  attr_reader :arg
         
     | 
| 
      
 212 
     | 
    
         
            +
             
     | 
| 
      
 213 
     | 
    
         
            +
                  def subnodes = { arg: }
         
     | 
| 
      
 214 
     | 
    
         
            +
             
     | 
| 
      
 215 
     | 
    
         
            +
                  def install0(genv)
         
     | 
| 
      
 216 
     | 
    
         
            +
                    @arg.install(genv)
         
     | 
| 
      
 217 
     | 
    
         
            +
                    if @lenv.exist_var?(:"*expected_block_ret")
         
     | 
| 
      
 218 
     | 
    
         
            +
                      @lenv.add_next_box(@changes.add_escape_box(genv, @arg.ret, @lenv.get_var(:"*expected_block_ret")))
         
     | 
| 
      
 219 
     | 
    
         
            +
                    end
         
     | 
| 
      
 220 
     | 
    
         
            +
                    Source.new(Type::Bot.new(genv))
         
     | 
| 
      
 221 
     | 
    
         
            +
                  end
         
     | 
| 
      
 222 
     | 
    
         
            +
                end
         
     | 
| 
      
 223 
     | 
    
         
            +
             
     | 
| 
      
 224 
     | 
    
         
            +
                class RedoNode < Node
         
     | 
| 
      
 225 
     | 
    
         
            +
                  def initialize(raw_node, lenv)
         
     | 
| 
      
 226 
     | 
    
         
            +
                    super(raw_node, lenv)
         
     | 
| 
      
 227 
     | 
    
         
            +
                  end
         
     | 
| 
      
 228 
     | 
    
         
            +
             
     | 
| 
      
 229 
     | 
    
         
            +
                  def install0(genv)
         
     | 
| 
      
 230 
     | 
    
         
            +
                    # TODO: This should return a bot type
         
     | 
| 
      
 231 
     | 
    
         
            +
                    Source.new()
         
     | 
| 
      
 232 
     | 
    
         
            +
                  end
         
     | 
| 
      
 233 
     | 
    
         
            +
                end
         
     | 
| 
      
 234 
     | 
    
         
            +
             
     | 
| 
      
 235 
     | 
    
         
            +
                class CaseNode < Node
         
     | 
| 
      
 236 
     | 
    
         
            +
                  def initialize(raw_node, lenv)
         
     | 
| 
      
 237 
     | 
    
         
            +
                    super(raw_node, lenv)
         
     | 
| 
      
 238 
     | 
    
         
            +
                    @pivot = raw_node.predicate ? AST.create_node(raw_node.predicate, lenv) : nil
         
     | 
| 
      
 239 
     | 
    
         
            +
                    @whens = []
         
     | 
| 
      
 240 
     | 
    
         
            +
                    @clauses = []
         
     | 
| 
      
 241 
     | 
    
         
            +
                    raw_node.conditions.each do |raw_cond|
         
     | 
| 
      
 242 
     | 
    
         
            +
                      @whens << AST.create_node(raw_cond.conditions.first, lenv) # XXX: multiple conditions
         
     | 
| 
      
 243 
     | 
    
         
            +
                      @clauses << (raw_cond.statements ? AST.create_node(raw_cond.statements, lenv) : DummyNilNode.new(code_range, lenv)) # TODO: code_range for NilNode
         
     | 
| 
      
 244 
     | 
    
         
            +
                    end
         
     | 
| 
      
 245 
     | 
    
         
            +
                    @else_clause = raw_node.else_clause && raw_node.else_clause.statements ? AST.create_node(raw_node.else_clause.statements, lenv) : DummyNilNode.new(code_range, lenv) # TODO: code_range for NilNode
         
     | 
| 
      
 246 
     | 
    
         
            +
                  end
         
     | 
| 
      
 247 
     | 
    
         
            +
             
     | 
| 
      
 248 
     | 
    
         
            +
                  attr_reader :pivot, :whens, :clauses, :else_clause
         
     | 
| 
      
 249 
     | 
    
         
            +
             
     | 
| 
      
 250 
     | 
    
         
            +
                  def subnodes = { pivot:, whens:, clauses:, else_clause: }
         
     | 
| 
      
 251 
     | 
    
         
            +
             
     | 
| 
      
 252 
     | 
    
         
            +
                  def install0(genv)
         
     | 
| 
      
 253 
     | 
    
         
            +
                    ret = Vertex.new(self)
         
     | 
| 
      
 254 
     | 
    
         
            +
                    @pivot&.install(genv)
         
     | 
| 
      
 255 
     | 
    
         
            +
                    @whens.zip(@clauses) do |vals, clause|
         
     | 
| 
      
 256 
     | 
    
         
            +
                      vals.install(genv)
         
     | 
| 
      
 257 
     | 
    
         
            +
                      @changes.add_edge(genv, clause.install(genv), ret)
         
     | 
| 
      
 258 
     | 
    
         
            +
                    end
         
     | 
| 
      
 259 
     | 
    
         
            +
                    @changes.add_edge(genv, @else_clause.install(genv), ret)
         
     | 
| 
      
 260 
     | 
    
         
            +
                    ret
         
     | 
| 
      
 261 
     | 
    
         
            +
                  end
         
     | 
| 
      
 262 
     | 
    
         
            +
                end
         
     | 
| 
      
 263 
     | 
    
         
            +
             
     | 
| 
      
 264 
     | 
    
         
            +
                class CaseMatchNode < Node
         
     | 
| 
      
 265 
     | 
    
         
            +
                  def initialize(raw_node, lenv)
         
     | 
| 
      
 266 
     | 
    
         
            +
                    super(raw_node, lenv)
         
     | 
| 
      
 267 
     | 
    
         
            +
                    @pivot = AST.create_node(raw_node.predicate, lenv)
         
     | 
| 
      
 268 
     | 
    
         
            +
                    @patterns = []
         
     | 
| 
      
 269 
     | 
    
         
            +
                    @clauses = []
         
     | 
| 
      
 270 
     | 
    
         
            +
                    raw_node.conditions.each do |raw_cond|
         
     | 
| 
      
 271 
     | 
    
         
            +
                      raise if raw_cond.type != :in_node
         
     | 
| 
      
 272 
     | 
    
         
            +
                      @patterns << AST.create_pattern_node(raw_cond.pattern, lenv)
         
     | 
| 
      
 273 
     | 
    
         
            +
                      @clauses << (raw_cond.statements ? AST.create_node(raw_cond.statements, lenv) : DummyNilNode.new(code_range, lenv)) # TODO: code_range for NilNode
         
     | 
| 
      
 274 
     | 
    
         
            +
                    end
         
     | 
| 
      
 275 
     | 
    
         
            +
                    @else_clause = raw_node.else_clause && raw_node.else_clause.statements ? AST.create_node(raw_node.else_clause.statements, lenv) : nil
         
     | 
| 
      
 276 
     | 
    
         
            +
                  end
         
     | 
| 
      
 277 
     | 
    
         
            +
             
     | 
| 
      
 278 
     | 
    
         
            +
                  attr_reader :pivot, :patterns, :clauses, :else_clause
         
     | 
| 
      
 279 
     | 
    
         
            +
             
     | 
| 
      
 280 
     | 
    
         
            +
                  def subnodes = { pivot:, patterns:, clauses:, else_clause: }
         
     | 
| 
      
 281 
     | 
    
         
            +
             
     | 
| 
      
 282 
     | 
    
         
            +
                  def install0(genv)
         
     | 
| 
      
 283 
     | 
    
         
            +
                    ret = Vertex.new(self)
         
     | 
| 
      
 284 
     | 
    
         
            +
                    @pivot&.install(genv)
         
     | 
| 
      
 285 
     | 
    
         
            +
                    @patterns.zip(@clauses) do |pattern, clause|
         
     | 
| 
      
 286 
     | 
    
         
            +
                      pattern.install(genv)
         
     | 
| 
      
 287 
     | 
    
         
            +
                      @changes.add_edge(genv, clause.install(genv), ret)
         
     | 
| 
      
 288 
     | 
    
         
            +
                    end
         
     | 
| 
      
 289 
     | 
    
         
            +
                    @changes.add_edge(genv, @else_clause.install(genv), ret) if @else_clause
         
     | 
| 
      
 290 
     | 
    
         
            +
                    ret
         
     | 
| 
      
 291 
     | 
    
         
            +
                  end
         
     | 
| 
      
 292 
     | 
    
         
            +
                end
         
     | 
| 
      
 293 
     | 
    
         
            +
             
     | 
| 
      
 294 
     | 
    
         
            +
                class AndNode < Node
         
     | 
| 
      
 295 
     | 
    
         
            +
                  def initialize(raw_node, e1 = nil, raw_e2 = nil, lenv)
         
     | 
| 
      
 296 
     | 
    
         
            +
                    super(raw_node, lenv)
         
     | 
| 
      
 297 
     | 
    
         
            +
                    @e1 = e1 || AST.create_node(raw_node.left, lenv)
         
     | 
| 
      
 298 
     | 
    
         
            +
                    @e2 = AST.create_node(raw_e2 || raw_node.right, lenv)
         
     | 
| 
      
 299 
     | 
    
         
            +
                  end
         
     | 
| 
      
 300 
     | 
    
         
            +
             
     | 
| 
      
 301 
     | 
    
         
            +
                  attr_reader :e1, :e2
         
     | 
| 
      
 302 
     | 
    
         
            +
             
     | 
| 
      
 303 
     | 
    
         
            +
                  def subnodes = { e1:, e2: }
         
     | 
| 
      
 304 
     | 
    
         
            +
             
     | 
| 
      
 305 
     | 
    
         
            +
                  def install0(genv)
         
     | 
| 
      
 306 
     | 
    
         
            +
                    ret = Vertex.new(self)
         
     | 
| 
      
 307 
     | 
    
         
            +
                    @changes.add_edge(genv, @e1.install(genv), ret)
         
     | 
| 
      
 308 
     | 
    
         
            +
                    @changes.add_edge(genv, @e2.install(genv), ret)
         
     | 
| 
      
 309 
     | 
    
         
            +
                    ret
         
     | 
| 
      
 310 
     | 
    
         
            +
                  end
         
     | 
| 
      
 311 
     | 
    
         
            +
                end
         
     | 
| 
      
 312 
     | 
    
         
            +
             
     | 
| 
      
 313 
     | 
    
         
            +
                class OrNode < Node
         
     | 
| 
      
 314 
     | 
    
         
            +
                  def initialize(raw_node, e1 = nil, raw_e2 = nil, lenv)
         
     | 
| 
      
 315 
     | 
    
         
            +
                    super(raw_node, lenv)
         
     | 
| 
      
 316 
     | 
    
         
            +
                    @e1 = e1 || AST.create_node(raw_node.left, lenv)
         
     | 
| 
      
 317 
     | 
    
         
            +
                    @e2 = AST.create_node(raw_e2 || raw_node.right, lenv)
         
     | 
| 
      
 318 
     | 
    
         
            +
                  end
         
     | 
| 
      
 319 
     | 
    
         
            +
             
     | 
| 
      
 320 
     | 
    
         
            +
                  attr_reader :e1, :e2
         
     | 
| 
      
 321 
     | 
    
         
            +
             
     | 
| 
      
 322 
     | 
    
         
            +
                  def subnodes = { e1:, e2: }
         
     | 
| 
      
 323 
     | 
    
         
            +
             
     | 
| 
      
 324 
     | 
    
         
            +
                  def install0(genv)
         
     | 
| 
      
 325 
     | 
    
         
            +
                    ret = Vertex.new(self)
         
     | 
| 
      
 326 
     | 
    
         
            +
                    v1 = @e1.install(genv)
         
     | 
| 
      
 327 
     | 
    
         
            +
                    v1 = NilFilter.new(genv, self, v1, false).next_vtx
         
     | 
| 
      
 328 
     | 
    
         
            +
                    @changes.add_edge(genv, v1, ret)
         
     | 
| 
      
 329 
     | 
    
         
            +
                    @changes.add_edge(genv, @e2.install(genv), ret)
         
     | 
| 
      
 330 
     | 
    
         
            +
                    ret
         
     | 
| 
      
 331 
     | 
    
         
            +
                  end
         
     | 
| 
      
 332 
     | 
    
         
            +
                end
         
     | 
| 
      
 333 
     | 
    
         
            +
             
     | 
| 
      
 334 
     | 
    
         
            +
                class ReturnNode < Node
         
     | 
| 
      
 335 
     | 
    
         
            +
                  def initialize(raw_node, lenv)
         
     | 
| 
      
 336 
     | 
    
         
            +
                    super(raw_node, lenv)
         
     | 
| 
      
 337 
     | 
    
         
            +
                    @arg = AST.parse_return_arguments(raw_node, lenv, code_range)
         
     | 
| 
      
 338 
     | 
    
         
            +
                  end
         
     | 
| 
      
 339 
     | 
    
         
            +
             
     | 
| 
      
 340 
     | 
    
         
            +
                  attr_reader :arg
         
     | 
| 
      
 341 
     | 
    
         
            +
             
     | 
| 
      
 342 
     | 
    
         
            +
                  def subnodes = { arg: }
         
     | 
| 
      
 343 
     | 
    
         
            +
             
     | 
| 
      
 344 
     | 
    
         
            +
                  def install0(genv)
         
     | 
| 
      
 345 
     | 
    
         
            +
                    @arg.install(genv)
         
     | 
| 
      
 346 
     | 
    
         
            +
                    e_ret = @lenv.locals[:"*expected_method_ret"]
         
     | 
| 
      
 347 
     | 
    
         
            +
                    @lenv.add_return_box(@changes.add_escape_box(genv, @arg.ret, e_ret)) if e_ret
         
     | 
| 
      
 348 
     | 
    
         
            +
                    Source.new(Type::Bot.new(genv))
         
     | 
| 
      
 349 
     | 
    
         
            +
                  end
         
     | 
| 
      
 350 
     | 
    
         
            +
                end
         
     | 
| 
      
 351 
     | 
    
         
            +
             
     | 
| 
      
 352 
     | 
    
         
            +
                class BeginNode < Node
         
     | 
| 
      
 353 
     | 
    
         
            +
                  def initialize(raw_node, lenv)
         
     | 
| 
      
 354 
     | 
    
         
            +
                    super(raw_node, lenv)
         
     | 
| 
      
 355 
     | 
    
         
            +
                    @body = raw_node.statements ? AST.create_node(raw_node.statements, lenv) : DummyNilNode.new(code_range, lenv)
         
     | 
| 
      
 356 
     | 
    
         
            +
                    @rescue_conds = []
         
     | 
| 
      
 357 
     | 
    
         
            +
                    @rescue_clauses = []
         
     | 
| 
      
 358 
     | 
    
         
            +
                    raw_res = raw_node.rescue_clause
         
     | 
| 
      
 359 
     | 
    
         
            +
                    while raw_res
         
     | 
| 
      
 360 
     | 
    
         
            +
                      raw_res.exceptions.each do |raw_cond|
         
     | 
| 
      
 361 
     | 
    
         
            +
                        @rescue_conds << AST.create_node(raw_cond, lenv)
         
     | 
| 
      
 362 
     | 
    
         
            +
                      end
         
     | 
| 
      
 363 
     | 
    
         
            +
                      if raw_res.statements
         
     | 
| 
      
 364 
     | 
    
         
            +
                        @rescue_clauses << AST.create_node(raw_res.statements, lenv)
         
     | 
| 
      
 365 
     | 
    
         
            +
                      end
         
     | 
| 
      
 366 
     | 
    
         
            +
                      raw_res = raw_res.subsequent
         
     | 
| 
      
 367 
     | 
    
         
            +
                    end
         
     | 
| 
      
 368 
     | 
    
         
            +
                    @else_clause = raw_node.else_clause ? AST.create_node(raw_node.else_clause.statements, lenv) : DummyNilNode.new(code_range, lenv)
         
     | 
| 
      
 369 
     | 
    
         
            +
                    @ensure_clause = raw_node.ensure_clause ? AST.create_node(raw_node.ensure_clause.statements, lenv) : DummyNilNode.new(code_range, lenv)
         
     | 
| 
      
 370 
     | 
    
         
            +
                  end
         
     | 
| 
      
 371 
     | 
    
         
            +
             
     | 
| 
      
 372 
     | 
    
         
            +
                  attr_reader :body, :rescue_conds, :rescue_clauses, :else_clause, :ensure_clause
         
     | 
| 
      
 373 
     | 
    
         
            +
             
     | 
| 
      
 374 
     | 
    
         
            +
                  def subnodes = { body:, rescue_conds:, rescue_clauses:, else_clause:, ensure_clause: }
         
     | 
| 
      
 375 
     | 
    
         
            +
             
     | 
| 
      
 376 
     | 
    
         
            +
                  def define0(genv)
         
     | 
| 
      
 377 
     | 
    
         
            +
                    @body.define(genv)
         
     | 
| 
      
 378 
     | 
    
         
            +
                    @rescue_conds.each {|cond| cond.define(genv) }
         
     | 
| 
      
 379 
     | 
    
         
            +
                    @rescue_clauses.each {|clause| clause.define(genv) }
         
     | 
| 
      
 380 
     | 
    
         
            +
                    @else_clause.define(genv) if @else_clause
         
     | 
| 
      
 381 
     | 
    
         
            +
                    @ensure_clause.define(genv) if @ensure_clause
         
     | 
| 
      
 382 
     | 
    
         
            +
                  end
         
     | 
| 
      
 383 
     | 
    
         
            +
             
     | 
| 
      
 384 
     | 
    
         
            +
                  def undefine0(genv)
         
     | 
| 
      
 385 
     | 
    
         
            +
                    @body.undefine(genv)
         
     | 
| 
      
 386 
     | 
    
         
            +
                    @rescue_conds.each {|cond| cond.undefine(genv) }
         
     | 
| 
      
 387 
     | 
    
         
            +
                    @rescue_clauses.each {|clause| clause.undefine(genv) }
         
     | 
| 
      
 388 
     | 
    
         
            +
                    @else_clause.undefine(genv) if @else_clause
         
     | 
| 
      
 389 
     | 
    
         
            +
                    @ensure_clause.undefine(genv) if @ensure_clause
         
     | 
| 
      
 390 
     | 
    
         
            +
                  end
         
     | 
| 
      
 391 
     | 
    
         
            +
             
     | 
| 
      
 392 
     | 
    
         
            +
                  def install0(genv)
         
     | 
| 
      
 393 
     | 
    
         
            +
                    ret = Vertex.new(self)
         
     | 
| 
      
 394 
     | 
    
         
            +
                    @changes.add_edge(genv, @body.install(genv), ret)
         
     | 
| 
      
 395 
     | 
    
         
            +
                    @rescue_conds.each {|cond| cond.install(genv) }
         
     | 
| 
      
 396 
     | 
    
         
            +
                    @rescue_clauses.each {|clause| @changes.add_edge(genv, clause.install(genv), ret) }
         
     | 
| 
      
 397 
     | 
    
         
            +
                    @changes.add_edge(genv, @else_clause.install(genv), ret) if @else_clause
         
     | 
| 
      
 398 
     | 
    
         
            +
                    @ensure_clause.install(genv) if @ensure_clause
         
     | 
| 
      
 399 
     | 
    
         
            +
                    ret
         
     | 
| 
      
 400 
     | 
    
         
            +
                  end
         
     | 
| 
      
 401 
     | 
    
         
            +
                end
         
     | 
| 
      
 402 
     | 
    
         
            +
             
     | 
| 
      
 403 
     | 
    
         
            +
                class RetryNode < Node
         
     | 
| 
      
 404 
     | 
    
         
            +
                  def initialize(raw_node, lenv)
         
     | 
| 
      
 405 
     | 
    
         
            +
                    super(raw_node, lenv)
         
     | 
| 
      
 406 
     | 
    
         
            +
                  end
         
     | 
| 
      
 407 
     | 
    
         
            +
             
     | 
| 
      
 408 
     | 
    
         
            +
                  def install0(genv)
         
     | 
| 
      
 409 
     | 
    
         
            +
                    Source.new(Type::Bot.new(genv))
         
     | 
| 
      
 410 
     | 
    
         
            +
                  end
         
     | 
| 
      
 411 
     | 
    
         
            +
                end
         
     | 
| 
      
 412 
     | 
    
         
            +
             
     | 
| 
      
 413 
     | 
    
         
            +
                class RescueModifierNode < Node
         
     | 
| 
      
 414 
     | 
    
         
            +
                  def initialize(raw_node, lenv)
         
     | 
| 
      
 415 
     | 
    
         
            +
                    super(raw_node, lenv)
         
     | 
| 
      
 416 
     | 
    
         
            +
                    @expression = AST.create_node(raw_node.expression, lenv)
         
     | 
| 
      
 417 
     | 
    
         
            +
                    @rescue_expression = AST.create_node(raw_node.rescue_expression, lenv)
         
     | 
| 
      
 418 
     | 
    
         
            +
                  end
         
     | 
| 
      
 419 
     | 
    
         
            +
             
     | 
| 
      
 420 
     | 
    
         
            +
                  attr_reader :expression, :rescue_expression
         
     | 
| 
      
 421 
     | 
    
         
            +
             
     | 
| 
      
 422 
     | 
    
         
            +
                  def subnodes = { expression:, rescue_expression: }
         
     | 
| 
      
 423 
     | 
    
         
            +
             
     | 
| 
      
 424 
     | 
    
         
            +
                  def install0(genv)
         
     | 
| 
      
 425 
     | 
    
         
            +
                    ret = Vertex.new(self)
         
     | 
| 
      
 426 
     | 
    
         
            +
                    @changes.add_edge(genv, @expression.install(genv), ret)
         
     | 
| 
      
 427 
     | 
    
         
            +
                    @changes.add_edge(genv, @rescue_expression.install(genv), ret)
         
     | 
| 
      
 428 
     | 
    
         
            +
                    ret
         
     | 
| 
      
 429 
     | 
    
         
            +
                  end
         
     | 
| 
      
 430 
     | 
    
         
            +
                end
         
     | 
| 
      
 431 
     | 
    
         
            +
              end
         
     | 
| 
      
 432 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,150 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module TypeProf::Core
         
     | 
| 
      
 2 
     | 
    
         
            +
              class AST
         
     | 
| 
      
 3 
     | 
    
         
            +
                class IncludeMetaNode < Node
         
     | 
| 
      
 4 
     | 
    
         
            +
                  def initialize(raw_node, lenv)
         
     | 
| 
      
 5 
     | 
    
         
            +
                    super(raw_node, lenv)
         
     | 
| 
      
 6 
     | 
    
         
            +
                    # TODO: error for splat
         
     | 
| 
      
 7 
     | 
    
         
            +
                    @args = raw_node.arguments.arguments.map do |raw_arg|
         
     | 
| 
      
 8 
     | 
    
         
            +
                      next if raw_arg.is_a?(Prism::SplatNode)
         
     | 
| 
      
 9 
     | 
    
         
            +
                      AST.create_node(raw_arg, lenv)
         
     | 
| 
      
 10 
     | 
    
         
            +
                    end.compact
         
     | 
| 
      
 11 
     | 
    
         
            +
                    # TODO: error for non-LIT
         
     | 
| 
      
 12 
     | 
    
         
            +
                    # TODO: fine-grained hover
         
     | 
| 
      
 13 
     | 
    
         
            +
                  end
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                  attr_reader :args
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                  def subnodes = { args: }
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                  def define0(genv)
         
     | 
| 
      
 20 
     | 
    
         
            +
                    mod = genv.resolve_cpath(@lenv.cref.cpath)
         
     | 
| 
      
 21 
     | 
    
         
            +
                    @args.each do |arg|
         
     | 
| 
      
 22 
     | 
    
         
            +
                      arg.define(genv)
         
     | 
| 
      
 23 
     | 
    
         
            +
                      if arg.static_ret
         
     | 
| 
      
 24 
     | 
    
         
            +
                        arg.static_ret.followers << mod
         
     | 
| 
      
 25 
     | 
    
         
            +
                        mod.add_include_def(genv, arg)
         
     | 
| 
      
 26 
     | 
    
         
            +
                      end
         
     | 
| 
      
 27 
     | 
    
         
            +
                    end
         
     | 
| 
      
 28 
     | 
    
         
            +
                  end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                  def undefine0(genv)
         
     | 
| 
      
 31 
     | 
    
         
            +
                    mod = genv.resolve_cpath(@lenv.cref.cpath)
         
     | 
| 
      
 32 
     | 
    
         
            +
                    @args.each do |arg|
         
     | 
| 
      
 33 
     | 
    
         
            +
                      if arg.static_ret
         
     | 
| 
      
 34 
     | 
    
         
            +
                        mod.remove_include_def(genv, arg)
         
     | 
| 
      
 35 
     | 
    
         
            +
                      end
         
     | 
| 
      
 36 
     | 
    
         
            +
                      arg.undefine(genv)
         
     | 
| 
      
 37 
     | 
    
         
            +
                    end
         
     | 
| 
      
 38 
     | 
    
         
            +
                    super(genv)
         
     | 
| 
      
 39 
     | 
    
         
            +
                  end
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
                  def install0(genv)
         
     | 
| 
      
 42 
     | 
    
         
            +
                    @args.each {|arg| arg.install(genv) }
         
     | 
| 
      
 43 
     | 
    
         
            +
                    Source.new
         
     | 
| 
      
 44 
     | 
    
         
            +
                  end
         
     | 
| 
      
 45 
     | 
    
         
            +
                end
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
                class AttrReaderMetaNode < Node
         
     | 
| 
      
 48 
     | 
    
         
            +
                  def initialize(raw_node, lenv)
         
     | 
| 
      
 49 
     | 
    
         
            +
                    super(raw_node, lenv)
         
     | 
| 
      
 50 
     | 
    
         
            +
                    @args = []
         
     | 
| 
      
 51 
     | 
    
         
            +
                    raw_node.arguments.arguments.each do |raw_arg|
         
     | 
| 
      
 52 
     | 
    
         
            +
                      @args << raw_arg.value.to_sym if raw_arg.type == :symbol_node
         
     | 
| 
      
 53 
     | 
    
         
            +
                    end
         
     | 
| 
      
 54 
     | 
    
         
            +
                    # TODO: error for non-LIT
         
     | 
| 
      
 55 
     | 
    
         
            +
                    # TODO: fine-grained hover
         
     | 
| 
      
 56 
     | 
    
         
            +
                  end
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
                  attr_reader :args
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
                  def attrs = { args: }
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
                  def req_positionals = []
         
     | 
| 
      
 63 
     | 
    
         
            +
                  def opt_positionals = []
         
     | 
| 
      
 64 
     | 
    
         
            +
                  def post_positionals = []
         
     | 
| 
      
 65 
     | 
    
         
            +
                  def rest_positionals = nil
         
     | 
| 
      
 66 
     | 
    
         
            +
                  def req_keywords = []
         
     | 
| 
      
 67 
     | 
    
         
            +
                  def opt_keywords = []
         
     | 
| 
      
 68 
     | 
    
         
            +
                  def rest_keywords = nil
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
                  def mname_code_range(name)
         
     | 
| 
      
 71 
     | 
    
         
            +
                    idx = @args.index(name.to_sym) # TODO: support string args
         
     | 
| 
      
 72 
     | 
    
         
            +
                    node = @raw_node.arguments.arguments[idx].location
         
     | 
| 
      
 73 
     | 
    
         
            +
                    TypeProf::CodeRange.from_node(node)
         
     | 
| 
      
 74 
     | 
    
         
            +
                  end
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
                  def install0(genv)
         
     | 
| 
      
 77 
     | 
    
         
            +
                    @args.each do |arg|
         
     | 
| 
      
 78 
     | 
    
         
            +
                      ivar_name = :"@#{ arg }"
         
     | 
| 
      
 79 
     | 
    
         
            +
                      ivar_box = @changes.add_ivar_read_box(genv, @lenv.cref.cpath, false, ivar_name)
         
     | 
| 
      
 80 
     | 
    
         
            +
                      e_ret = Vertex.new(self)
         
     | 
| 
      
 81 
     | 
    
         
            +
                      ret_box = @changes.add_escape_box(genv, ivar_box.ret, e_ret)
         
     | 
| 
      
 82 
     | 
    
         
            +
                      @changes.add_method_def_box(genv, @lenv.cref.cpath, false, arg, FormalArguments::Empty, [ret_box])
         
     | 
| 
      
 83 
     | 
    
         
            +
                    end
         
     | 
| 
      
 84 
     | 
    
         
            +
                    Source.new
         
     | 
| 
      
 85 
     | 
    
         
            +
                  end
         
     | 
| 
      
 86 
     | 
    
         
            +
                end
         
     | 
| 
      
 87 
     | 
    
         
            +
             
     | 
| 
      
 88 
     | 
    
         
            +
                class AttrAccessorMetaNode < Node
         
     | 
| 
      
 89 
     | 
    
         
            +
                  def initialize(raw_node, lenv)
         
     | 
| 
      
 90 
     | 
    
         
            +
                    super(raw_node, lenv)
         
     | 
| 
      
 91 
     | 
    
         
            +
                    @args = []
         
     | 
| 
      
 92 
     | 
    
         
            +
                    raw_node.arguments.arguments.each do |raw_arg|
         
     | 
| 
      
 93 
     | 
    
         
            +
                      @args << raw_arg.value.to_sym if raw_arg.type == :symbol_node
         
     | 
| 
      
 94 
     | 
    
         
            +
                    end
         
     | 
| 
      
 95 
     | 
    
         
            +
                    # TODO: error for non-LIT
         
     | 
| 
      
 96 
     | 
    
         
            +
                    # TODO: fine-grained hover
         
     | 
| 
      
 97 
     | 
    
         
            +
                  end
         
     | 
| 
      
 98 
     | 
    
         
            +
             
     | 
| 
      
 99 
     | 
    
         
            +
                  attr_reader :args
         
     | 
| 
      
 100 
     | 
    
         
            +
             
     | 
| 
      
 101 
     | 
    
         
            +
                  def attrs = { args: }
         
     | 
| 
      
 102 
     | 
    
         
            +
             
     | 
| 
      
 103 
     | 
    
         
            +
                  def mname_code_range(name)
         
     | 
| 
      
 104 
     | 
    
         
            +
                    idx = @args.index(name.to_sym) # TODO: support string args
         
     | 
| 
      
 105 
     | 
    
         
            +
                    node = @raw_node.arguments.arguments[idx].location
         
     | 
| 
      
 106 
     | 
    
         
            +
                    TypeProf::CodeRange.from_node(node)
         
     | 
| 
      
 107 
     | 
    
         
            +
                  end
         
     | 
| 
      
 108 
     | 
    
         
            +
             
     | 
| 
      
 109 
     | 
    
         
            +
                  def define0(genv)
         
     | 
| 
      
 110 
     | 
    
         
            +
                    @args.map do |arg|
         
     | 
| 
      
 111 
     | 
    
         
            +
                      mod = genv.resolve_ivar(lenv.cref.cpath, false, :"@#{ arg }")
         
     | 
| 
      
 112 
     | 
    
         
            +
                      mod.add_def(self)
         
     | 
| 
      
 113 
     | 
    
         
            +
                      mod
         
     | 
| 
      
 114 
     | 
    
         
            +
                    end
         
     | 
| 
      
 115 
     | 
    
         
            +
                  end
         
     | 
| 
      
 116 
     | 
    
         
            +
             
     | 
| 
      
 117 
     | 
    
         
            +
                  def define_copy(genv)
         
     | 
| 
      
 118 
     | 
    
         
            +
                    @args.map do |arg|
         
     | 
| 
      
 119 
     | 
    
         
            +
                      mod = genv.resolve_ivar(lenv.cref.cpath, false, :"@#{ arg }")
         
     | 
| 
      
 120 
     | 
    
         
            +
                      mod.add_def(self)
         
     | 
| 
      
 121 
     | 
    
         
            +
                      mod.remove_def(@prev_node)
         
     | 
| 
      
 122 
     | 
    
         
            +
                      mod
         
     | 
| 
      
 123 
     | 
    
         
            +
                    end
         
     | 
| 
      
 124 
     | 
    
         
            +
                    super(genv)
         
     | 
| 
      
 125 
     | 
    
         
            +
                  end
         
     | 
| 
      
 126 
     | 
    
         
            +
             
     | 
| 
      
 127 
     | 
    
         
            +
                  def undefine0(genv)
         
     | 
| 
      
 128 
     | 
    
         
            +
                    @args.each do |arg|
         
     | 
| 
      
 129 
     | 
    
         
            +
                      mod = genv.resolve_ivar(lenv.cref.cpath, false, :"@#{ arg }")
         
     | 
| 
      
 130 
     | 
    
         
            +
                      mod.remove_def(self)
         
     | 
| 
      
 131 
     | 
    
         
            +
                    end
         
     | 
| 
      
 132 
     | 
    
         
            +
                  end
         
     | 
| 
      
 133 
     | 
    
         
            +
             
     | 
| 
      
 134 
     | 
    
         
            +
                  def install0(genv)
         
     | 
| 
      
 135 
     | 
    
         
            +
                    @args.zip(@static_ret) do |arg, ive|
         
     | 
| 
      
 136 
     | 
    
         
            +
                      ivar_box = @changes.add_ivar_read_box(genv, @lenv.cref.cpath, false, :"@#{ arg }")
         
     | 
| 
      
 137 
     | 
    
         
            +
                      e_ret = Vertex.new(self)
         
     | 
| 
      
 138 
     | 
    
         
            +
                      ret_box = @changes.add_escape_box(genv, ivar_box.ret, e_ret)
         
     | 
| 
      
 139 
     | 
    
         
            +
                      @changes.add_method_def_box(genv, @lenv.cref.cpath, false, arg, FormalArguments::Empty, [ret_box])
         
     | 
| 
      
 140 
     | 
    
         
            +
             
     | 
| 
      
 141 
     | 
    
         
            +
                      vtx = Vertex.new(self)
         
     | 
| 
      
 142 
     | 
    
         
            +
                      @changes.add_edge(genv, vtx, ive.vtx)
         
     | 
| 
      
 143 
     | 
    
         
            +
                      f_args = FormalArguments.new([vtx], [], nil, [], [], [], nil, nil)
         
     | 
| 
      
 144 
     | 
    
         
            +
                      @changes.add_method_def_box(genv, @lenv.cref.cpath, false, :"#{ arg }=", f_args, [ret_box])
         
     | 
| 
      
 145 
     | 
    
         
            +
                    end
         
     | 
| 
      
 146 
     | 
    
         
            +
                    Source.new
         
     | 
| 
      
 147 
     | 
    
         
            +
                  end
         
     | 
| 
      
 148 
     | 
    
         
            +
                end
         
     | 
| 
      
 149 
     | 
    
         
            +
              end
         
     | 
| 
      
 150 
     | 
    
         
            +
            end
         
     |