class TypeProf::Core::AST::BranchNode - typeprof: Ruby Standard Library Documentation

# class TypeProf::Core::AST::BranchNode

### Attributes

cond[R]
else[R]
then[R]

### Public Class Methods

new(raw_node, lenv) click to toggle source
Calls superclass method `TypeProf::Core::AST::Node::new`

    # File typeprof-0.30.1/lib/typeprof/core/ast/control.rb, line 17
    def initialize(raw_node, lenv)
      super(raw_node, lenv)
      @cond = AST.create_node(raw_node.predicate, lenv)
      @then = raw_node.statements ? AST.create_node(raw_node.statements, lenv) : nil
      else_clause = raw_node.is_a?(Prism::IfNode) ? raw_node.subsequent : raw_node.else_clause
      if else_clause
        else_clause = else_clause.statements if else_clause.type == :else_node
        @else = else_clause ? AST.create_node(else_clause, lenv) : nil
      else
        @else = nil
      end
    end

### Public Instance Methods

install0(genv) click to toggle source

    # File typeprof-0.30.1/lib/typeprof/core/ast/control.rb, line 34
    def install0(genv)
      ret = Vertex.new(self)

      @cond.install(genv)

      vars = []
      vars << @cond.var if @cond.is_a?(LocalVariableReadNode)
      var, filter_class = AST.is_a_class(@cond)
      vars << var if var
      @then.modified_vars(@lenv.locals.keys, vars) if @then
      @else.modified_vars(@lenv.locals.keys, vars) if @else
      modified_vtxs = {}
      vars.uniq.each do |var|
        vtx = @lenv.get_var(var)
        nvtx_then = vtx.new_vertex(genv, self)
        nvtx_else = vtx.new_vertex(genv, self)
        modified_vtxs[var] = [nvtx_then, nvtx_else]
      end
      if @cond.is_a?(LocalVariableReadNode)
        nvtx_then, nvtx_else = modified_vtxs[@cond.var]
        nvtx_then = NilFilter.new(genv, self, nvtx_then, !self.is_a?(IfNode)).next_vtx
        nvtx_else = NilFilter.new(genv, self, nvtx_else, self.is_a?(IfNode)).next_vtx
        modified_vtxs[@cond.var] = [nvtx_then, nvtx_else]
      end
      if filter_class
        nvtx_then, nvtx_else = modified_vtxs[var]
        nvtx_then = IsAFilter.new(genv, self, nvtx_then, !self.is_a?(IfNode), filter_class).next_vtx
        nvtx_else = IsAFilter.new(genv, self, nvtx_else, self.is_a?(IfNode), filter_class).next_vtx
        modified_vtxs[var] = [nvtx_then, nvtx_else]
      end

      if @then
        modified_vtxs.each do |var, (nvtx_then, _)|
          @lenv.set_var(var, nvtx_then)
        end
        if @cond.is_a?(InstanceVariableReadNode)
          @lenv.push_read_filter(@cond.var, :non_nil)
        end
        then_val = @then.install(genv)
        if @cond.is_a?(InstanceVariableReadNode)
          @lenv.pop_read_filter(@cond.var)
        end
        modified_vtxs.each do |var, ary|
          ary[0] = @lenv.get_var(var)
        end
      else
        then_val = Source.new(genv.nil_type)
      end
      @changes.add_edge(genv, then_val, ret)

      if @else
        modified_vtxs.each do |var, (_, nvtx_else)|
          @lenv.set_var(var, nvtx_else)
        end
        else_val = @else.install(genv)
        modified_vtxs.each do |var, ary|
          ary[1] = @lenv.get_var(var)
        end
      else
        else_val = Source.new(genv.nil_type)
      end
      @changes.add_edge(genv, else_val, ret)

      modified_vtxs.each do |var, (nvtx_then, nvtx_else)|
        nvtx_then = BotFilter.new(genv, self, nvtx_then, then_val).next_vtx
        nvtx_else = BotFilter.new(genv, self, nvtx_else, else_val).next_vtx
        nvtx_join = nvtx_then.new_vertex(genv, self)
        @changes.add_edge(genv, nvtx_else, nvtx_join)
        @lenv.set_var(var, nvtx_join)
      end

      ret
    end

subnodes(= { cond:, then:, else: }) click to toggle source

    # File typeprof-0.30.1/lib/typeprof/core/ast/control.rb, line 32
      def subnodes = { cond:, then:, else: }

      def install0(genv)
        ret = Vertex.new(self)

        @cond.install(genv)

        vars = []
        vars << @cond.var if @cond.is_a?(LocalVariableReadNode)
        var, filter_class = AST.is_a_class(@cond)
        vars << var if var
        @then.modified_vars(@lenv.locals.keys, vars) if @then
        @else.modified_vars(@lenv.locals.keys, vars) if @else
        modified_vtxs = {}
        vars.uniq.each do |var|
          vtx = @lenv.get_var(var)
          nvtx_then = vtx.new_vertex(genv, self)
          nvtx_else = vtx.new_vertex(genv, self)
          modified_vtxs[var] = [nvtx_then, nvtx_else]
        end
        if @cond.is_a?(LocalVariableReadNode)
          nvtx_then, nvtx_else = modified_vtxs[@cond.var]
          nvtx_then = NilFilter.new(genv, self, nvtx_then, !self.is_a?(IfNode)).next_vtx
          nvtx_else = NilFilter.new(genv, self, nvtx_else, self.is_a?(IfNode)).next_vtx
          modified_vtxs[@cond.var] = [nvtx_then, nvtx_else]
        end
        if filter_class
          nvtx_then, nvtx_else = modified_vtxs[var]
          nvtx_then = IsAFilter.new(genv, self, nvtx_then, !self.is_a?(IfNode), filter_class).next_vtx
          nvtx_else = IsAFilter.new(genv, self, nvtx_else, self.is_a?(IfNode), filter_class).next_vtx
          modified_vtxs[var] = [nvtx_then, nvtx_else]
        end

        if @then
          modified_vtxs.each do |var, (nvtx_then, _)|
            @lenv.set_var(var, nvtx_then)
          end
          if @cond.is_a?(InstanceVariableReadNode)
            @lenv.push_read_filter(@cond.var, :non_nil)
          end
          then_val = @then.install(genv)
          if @cond.is_a?(InstanceVariableReadNode)
            @lenv.pop_read_filter(@cond.var)
          end
          modified_vtxs.each do |var, ary|
            ary[0] = @lenv.get_var(var)
          end
        else
          then_val = Source.new(genv.nil_type)
        end
        @changes.add_edge(genv, then_val, ret)

        if @else
          modified_vtxs.each do |var, (_, nvtx_else)|
            @lenv.set_var(var, nvtx_else)
          end
          else_val = @else.install(genv)
          modified_vtxs.each do |var, ary|
            ary[1] = @lenv.get_var(var)
          end
        else
          else_val = Source.new(genv.nil_type)
        end
        @changes.add_edge(genv, else_val, ret)

        modified_vtxs.each do |var, (nvtx_then, nvtx_else)|
          nvtx_then = BotFilter.new(genv, self, nvtx_then, then_val).next_vtx
          nvtx_else = BotFilter.new(genv, self, nvtx_else, else_val).next_vtx
          nvtx_join = nvtx_then.new_vertex(genv, self)
          @changes.add_edge(genv, nvtx_else, nvtx_join)
          @lenv.set_var(var, nvtx_join)
        end

        ret
      end
    end