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