In Files

  • typeprof-0.12.0/lib/typeprof/type.rb

Class/Module Index [+]

Quicksearch

Union

Attributes

elems[R]
types[R]

Public Class Methods

new(tys, elems) click to toggle source
 
               # File typeprof-0.12.0/lib/typeprof/type.rb, line 210
def initialize(tys, elems)
  raise unless tys.is_a?(Utils::Set)
  @types = tys # Set

  # invariant check
  local = nil
  tys.each do |ty|
    raise ty.inspect unless ty.is_a?(Type)
    local = true if ty.is_a?(Local)
  end
  raise if local && elems

  @elems = elems
  raise elems.inspect if elems && !elems.is_a?(::Hash)
end
            

Public Instance Methods

consistent?(_other) click to toggle source
 
               # File typeprof-0.12.0/lib/typeprof/type.rb, line 364
def consistent?(_other)
  raise "should not be called"
end
            
each_child(&blk) click to toggle source
 
               # File typeprof-0.12.0/lib/typeprof/type.rb, line 262
def each_child(&blk) # local
  @types.each(&blk)
  raise if @elems
end
            
each_child_global(&blk) click to toggle source
 
               # File typeprof-0.12.0/lib/typeprof/type.rb, line 267
def each_child_global(&blk)
  @types.each(&blk)
  @elems&.each do |(container_kind, base_type), elems|
    yield container_kind.new(elems, base_type)
  end
end
            
each_free_type_variable(&blk) click to toggle source
 
               # File typeprof-0.12.0/lib/typeprof/type.rb, line 226
def each_free_type_variable(&blk)
  each_child_global do |ty|
    ty.each_free_type_variable(&blk)
  end
end
            
globalize(env, visited, depth) click to toggle source
 
               # File typeprof-0.12.0/lib/typeprof/type.rb, line 323
def globalize(env, visited, depth)
  return Type.any if depth <= 0
  tys = Utils::Set[]
  if @elems
    # XXX: If @elems is non nil, the Union type should global, so calling globalize against such a type should not occur.
    # However, currently, ActualArguments may contain global types for flag_args_kw_splat case.
    # This should be fixed in future in ActualArguments side. See Scratch#setup_actual_arguments.
    #raise
  end

  elems = @elems ? @elems.dup : {}
  @types.each do |ty|
    ty = ty.globalize(env, visited, depth - 1)
    case ty
    when Type::Array, Type::Hash
      key = [ty.class, ty.base_type]
      elems[key] = union_elems(elems[key], ty.elems)
    else
      tys = tys.add(ty)
    end
  end
  elems = nil if elems.empty?

  Type::Union.new(tys, elems).normalize
end
            
include_untyped?(scratch) click to toggle source
 
               # File typeprof-0.12.0/lib/typeprof/type.rb, line 391
def include_untyped?(scratch)
  @types.each do |ty|
    return true if ty.include_untyped?(scratch)
  end
  @elems&.each do |(container_kind, base_type), elems|
    return true if base_type.include_untyped?(scratch)
    return true if elems.include_untyped?(scratch)
  end
  false
end
            
inspect() click to toggle source
 
               # File typeprof-0.12.0/lib/typeprof/type.rb, line 274
def inspect
  a = []
  a << "Type::Union{#{ @types.to_a.map {|ty| ty.inspect }.join(", ") }"
  @elems&.each do |(container_kind, base_type), elems|
    a << ", #{ container_kind.new(elems, base_type).inspect }"
  end
  a << "}"
  a.join
end
            
limit_size(limit) click to toggle source
 
               # File typeprof-0.12.0/lib/typeprof/type.rb, line 232
def limit_size(limit)
  return Type.any if limit <= 0
  tys = Utils::Set[]
  @types.each do |ty|
    tys = tys.add(ty.limit_size(limit - 1))
  end
  elems = @elems&.to_h do |key, elems|
    [key, elems.limit_size(limit - 1)]
  end
  Union.new(tys, elems)
end
            
localize(env, alloc_site, depth) click to toggle source
 
               # File typeprof-0.12.0/lib/typeprof/type.rb, line 349
def localize(env, alloc_site, depth)
  return env, Type.any if depth <= 0
  tys = @types.map do |ty|
    env, ty2 = ty.localize(env, alloc_site, depth - 1)
    ty2
  end
  @elems&.each do |(container_kind, base_type), elems|
    ty = container_kind.new(elems, base_type)
    env, ty = ty.localize(env, alloc_site, depth - 1)
    tys = tys.add(ty)
  end
  ty = Union.new(tys, nil).normalize
  return env, ty
end
            
normalize() click to toggle source
 
               # File typeprof-0.12.0/lib/typeprof/type.rb, line 246
def normalize
  if @types.size == 1 && !@elems
    @types.each {|ty| return ty }
  elsif @types.size == 0
    if @elems && @elems.size == 1
      (container_kind, base_type), elems = @elems.first
      # container_kind = Type::Array or Type::Hash
      container_kind.new(elems, base_type)
    else
      self
    end
  else
    self
  end
end
            
screen_name(scratch) click to toggle source
 
               # File typeprof-0.12.0/lib/typeprof/type.rb, line 284
def screen_name(scratch)
  types = @types.to_a
  @elems&.each do |(container_kind, base_type), elems|
    types << container_kind.new(elems, base_type)
  end
  if types.size == 0
    "bot"
  else
    types = types.to_a
    optional = !!types.delete(Type::Instance.new(Type::Builtin[:nil]))
    bool = false
    if types.include?(Type::Instance.new(Type::Builtin[:false])) &&
       types.include?(Type::Instance.new(Type::Builtin[:true]))
      types.delete(Type::Instance.new(Type::Builtin[:false]))
      types.delete(Type::Instance.new(Type::Builtin[:true]))
      bool = true
    end
    types.delete(Type.any) unless Config.options[:show_untyped]
    proc_tys, types = types.partition {|ty| ty.is_a?(Proc) }
    types = types.map {|ty| ty.screen_name(scratch) }
    types << scratch.show_proc_signature(proc_tys) unless proc_tys.empty?
    types << "bool" if bool
    types = types.sort
    if optional
      case types.size
      when 0 then "nil"
      when 1 then types.first + "?"
      else
        "(#{ types.join (" | ") })?"
      end
    else
      types.join (" | ")
    end
  end
rescue SystemStackError
  p self
  raise
end
            
substitute(subst, depth) click to toggle source
 
               # File typeprof-0.12.0/lib/typeprof/type.rb, line 368
def substitute(subst, depth)
  return Type.any if depth <= 0
  unions = []
  tys = Utils::Set[]
  @types.each do |ty|
    ty = ty.substitute(subst, depth - 1)
    case ty
    when Union
      unions << ty
    else
      tys = tys.add(ty)
    end
  end
  elems = @elems&.to_h do |(container_kind, base_type), elems|
    [[container_kind, base_type], elems.substitute(subst, depth - 1)]
  end
  ty = Union.new(tys, elems).normalize
  unions.each do |ty0|
    ty = ty.union(ty0)
  end
  ty
end