123456789_123456789_123456789_123456789_123456789_

Class: TypeProf::MethodSignature

Relationships & Source Files
Super Chains via Extension / Inclusion / Inheritance
Class Chain:
self, Signature
Instance Chain:
Inherits: TypeProf::Signature
Defined in: lib/typeprof/type.rb

Class Method Summary

Instance Attribute Summary

Instance Method Summary

Constructor Details

.new(lead_tys, opt_tys, rest_ty, post_tys, kw_tys, kw_rest_ty, blk_ty) ⇒ MethodSignature

[ GitHub ]

  
# File 'lib/typeprof/type.rb', line 937

def initialize(lead_tys, opt_tys, rest_ty, post_tys, kw_tys, kw_rest_ty, blk_ty)
  @lead_tys = lead_tys
  @opt_tys = opt_tys
  raise unless opt_tys.is_a?(Array)
  @rest_ty = rest_ty
  @post_tys = post_tys
  raise unless post_tys
  @kw_tys = kw_tys
  kw_tys.each {|a| raise if a.size != 3 } if kw_tys
  @kw_rest_ty = kw_rest_ty
  kw_rest_ty&.each_child_global do |ty|
    raise ty.inspect if ty != Type.any && !ty.is_a?(Type::Hash)
  end
  @blk_ty = blk_ty
end

Instance Attribute Details

#blk_ty (readonly)

[ GitHub ]

  
# File 'lib/typeprof/type.rb', line 964

attr_reader :lead_tys, :opt_tys, :rest_ty, :post_tys, :kw_tys, :kw_rest_ty, :blk_ty

#kw_rest_ty (readonly)

[ GitHub ]

  
# File 'lib/typeprof/type.rb', line 964

attr_reader :lead_tys, :opt_tys, :rest_ty, :post_tys, :kw_tys, :kw_rest_ty, :blk_ty

#kw_tys (readonly)

[ GitHub ]

  
# File 'lib/typeprof/type.rb', line 964

attr_reader :lead_tys, :opt_tys, :rest_ty, :post_tys, :kw_tys, :kw_rest_ty, :blk_ty

#lead_tys (readonly)

[ GitHub ]

  
# File 'lib/typeprof/type.rb', line 964

attr_reader :lead_tys, :opt_tys, :rest_ty, :post_tys, :kw_tys, :kw_rest_ty, :blk_ty

#opt_tys (readonly)

[ GitHub ]

  
# File 'lib/typeprof/type.rb', line 964

attr_reader :lead_tys, :opt_tys, :rest_ty, :post_tys, :kw_tys, :kw_rest_ty, :blk_ty

#post_tys (readonly)

[ GitHub ]

  
# File 'lib/typeprof/type.rb', line 964

attr_reader :lead_tys, :opt_tys, :rest_ty, :post_tys, :kw_tys, :kw_rest_ty, :blk_ty

#rest_ty (readonly)

[ GitHub ]

  
# File 'lib/typeprof/type.rb', line 964

attr_reader :lead_tys, :opt_tys, :rest_ty, :post_tys, :kw_tys, :kw_rest_ty, :blk_ty

Instance Method Details

#include_untyped?(scratch) ⇒ Boolean

[ GitHub ]

  
# File 'lib/typeprof/type.rb', line 953

def include_untyped?(scratch)
  return true if @lead_tys.any? {|ty| ty.include_untyped?(scratch) }
  return true if @opt_tys.any? {|ty| ty.include_untyped?(scratch) }
  return true if @rest_ty&.include_untyped?(scratch)
  return true if @post_tys.any? {|ty| ty.include_untyped?(scratch) }
  return true if @kw_tys&.any? {|_, _, ty| ty.include_untyped?(scratch) }
  return true if @kw_rest_ty&.include_untyped?(scratch)
  return true if @blk_ty&.include_untyped?(scratch)
  false
end

#merge(other)

[ GitHub ]

  
# File 'lib/typeprof/type.rb', line 1015

def merge(other)
  raise if @lead_tys.size != other.lead_tys.size
  raise if @post_tys.size != other.post_tys.size
  if @kw_tys && other.kw_tys
    kws1 = {}
    @kw_tys.each {|req, kw, _| kws1[kw] = req }
    kws2 = {}
    other.kw_tys.each {|req, kw, _| kws2[kw] = req }
    (kws1.keys & kws2.keys).each do |kw|
      raise if !!kws1[kw] != !!kws2[kw]
    end
  elsif @kw_tys || other.kw_tys
    (@kw_tys || other.kw_tys).each do |req,|
      raise if req
    end
  end
  lead_tys = @lead_tys.zip(other.lead_tys).map {|ty1, ty2| ty1.union(ty2) }
  if @opt_tys || other.opt_tys
    opt_tys = []
    [@opt_tys.size, other.opt_tys.size].max.times do |i|
      ty1 = @opt_tys[i]
      ty2 = other.opt_tys[i]
      ty = ty1 ? ty2 ? ty1.union(ty2) : ty1 : ty2
      opt_tys << ty
    end
  end
  if @rest_ty || other.rest_ty
    if @rest_ty && other.rest_ty
      rest_ty = @rest_ty.union(other.rest_ty)
    else
      rest_ty = @rest_ty || other.rest_ty
    end
  end
  post_tys = @post_tys.zip(other.post_tys).map {|ty1, ty2| ty1.union(ty2) }
  if @kw_tys && other.kw_tys
    kws1 = {}
    @kw_tys.each {|req, kw, ty| kws1[kw] = [req, ty] }
    kws2 = {}
    other.kw_tys.each {|req, kw, ty| kws2[kw] = [req, ty] }
    kw_tys = (kws1.keys | kws2.keys).map do |kw|
      req1, ty1 = kws1[kw]
      _req2, ty2 = kws2[kw]
      ty1 ||= Type.bot
      ty2 ||= Type.bot
      [!!req1, kw, ty1.union(ty2)]
    end
  elsif @kw_tys || other.kw_tys
    kw_tys = @kw_tys || other.kw_tys
  else
    kw_tys = nil
  end
  if @kw_rest_ty || other.kw_rest_ty
    if @kw_rest_ty && other.kw_rest_ty
      kw_rest_ty = @kw_rest_ty.union(other.kw_rest_ty)
    else
      kw_rest_ty = @kw_rest_ty || other.kw_rest_ty
    end
  end
  blk_ty = @blk_ty.union(other.blk_ty) if @blk_ty
  MethodSignature.new(lead_tys, opt_tys, rest_ty, post_tys, kw_tys, kw_rest_ty, blk_ty)
end

#merge_as_block_arguments(other)

[ GitHub ]

  
# File 'lib/typeprof/type.rb', line 977

def merge_as_block_arguments(other)
  lead_tys1, opt_tys1, rest_ty1, post_tys1 = @lead_tys, @opt_tys, @rest_ty, @post_tys
  lead_tys2, opt_tys2, rest_ty2, post_tys2 = other.lead_tys, other.opt_tys, other.rest_ty, other.post_tys

  case
  when lead_tys1.size > lead_tys2.size
    n = lead_tys2.size
    lead_tys1, opt_tys1 = lead_tys1[0, n], lead_tys1[n..] + opt_tys1
  when lead_tys1.size < lead_tys2.size
    n = lead_tys1.size
    lead_tys2, opt_tys2 = lead_tys2[0, n], lead_tys2[n..] + opt_tys2
  end
  case
  when post_tys1.size > post_tys2.size
    i = post_tys1.size - post_tys2.size
    if rest_ty1
      rest_ty1 = post_tys[0, i].inject(rest_ty1) {|ty1, ty2| ty1.union(ty2) }
      post_tys1 = post_tys1[i..]
    else
      opt_tys1, post_tys1 = opt_tys1 + post_tys1[0, i], post_tys1[i..]
    end
  when post_tys1.size < post_tys2.size
    i = post_tys2.size - post_tys1.size
    if rest_ty2
      rest_ty2 = post_tys[0, i].inject(rest_ty2) {|ty1, ty2| ty1.union(ty2) }
      post_tys2 = post_tys2[i..]
    else
      opt_tys2, post_tys2 = opt_tys2 + post_tys2[0, i], post_tys2[i..]
    end
  end

  # XXX: tweak keywords too

  msig1 = MethodSignature.new(lead_tys1, opt_tys1, rest_ty1, post_tys1, @kw_tys, @kw_rest_ty, @blk_ty)
  msig2 = MethodSignature.new(lead_tys2, opt_tys2, rest_ty2, post_tys2, other.kw_tys, other.kw_rest_ty, other.blk_ty)
  msig1.merge(msig2)
end

#substitute(subst, depth)

[ GitHub ]

  
# File 'lib/typeprof/type.rb', line 966

def substitute(subst, depth)
  lead_tys = @lead_tys.map {|ty| ty.substitute(subst, depth - 1) }
  opt_tys = @opt_tys.map {|ty| ty.substitute(subst, depth - 1) }
  rest_ty = @rest_ty&.substitute(subst, depth - 1)
  post_tys = @post_tys.map {|ty| ty.substitute(subst, depth - 1) }
  kw_tys = @kw_tys.map {|req, key, ty| [req, key, ty.substitute(subst, depth - 1)] }
  kw_rest_ty = @kw_rest_ty&.substitute(subst, depth - 1)
  blk_ty = @blk_ty.substitute(subst, depth - 1)
  MethodSignature.new(lead_tys, opt_tys, rest_ty, post_tys, kw_tys, kw_rest_ty, blk_ty)
end