# File typeprof-0.12.0/lib/typeprof/import.rb, line 481
def self.import_builtin(scratch)
Import.new(scratch, scratch.rbs_reader.load_builtin).import
end
# File typeprof-0.12.0/lib/typeprof/import.rb, line 485
def self.import_library(scratch, feature)
begin
json = scratch.rbs_reader.load_library(feature)
rescue RBS::EnvironmentLoader::UnknownLibraryError
return nil
rescue RBS::DuplicatedDeclarationError
return true
end
# need cache?
Import.new(scratch, json).import
end
# File typeprof-0.12.0/lib/typeprof/import.rb, line 502
def self.import_rbs_code(scratch, rbs_name, rbs_code)
Import.new(scratch, scratch.rbs_reader.load_rbs_string(rbs_name, rbs_code)).import(true)
end
# File typeprof-0.12.0/lib/typeprof/import.rb, line 640
def conv_block(blk)
return [Type.nil] unless blk
req, lead_tys, opt_tys, ret_ty = blk
lead_tys = lead_tys.map {|ty| conv_type(ty) }
opt_tys = opt_tys.map {|ty| conv_type(ty) }
msig = MethodSignature.new(lead_tys, opt_tys, nil, [], {}, nil, Type.nil)
ret_ty = conv_type(ret_ty)
ret = [Type::Proc.new(TypedBlock.new(msig, ret_ty), Type::Builtin[:proc])]
ret << Type.nil unless req
ret
end
# File typeprof-0.12.0/lib/typeprof/import.rb, line 612
def conv_func(sig_ret)
#type_params = sig_ret[:type_params] # XXX
lead_tys = sig_ret[:lead_tys]
opt_tys = sig_ret[:opt_tys]
rest_ty = sig_ret[:rest_ty]
req_kw_tys = sig_ret[:req_kw_tys]
opt_kw_tys = sig_ret[:opt_kw_tys]
rest_kw_ty = sig_ret[:rest_kw_ty]
blk = sig_ret[:blk]
ret_ty = sig_ret[:ret_ty]
lead_tys = lead_tys.map {|ty| conv_type(ty) }
opt_tys = opt_tys.map {|ty| conv_type(ty) }
rest_ty = conv_type(rest_ty) if rest_ty
kw_tys = []
req_kw_tys.each {|key, ty| kw_tys << [true, key, conv_type(ty)] }
opt_kw_tys.each {|key, ty| kw_tys << [false, key, conv_type(ty)] }
kw_rest_ty = conv_type(rest_kw_ty) if rest_kw_ty
blks = conv_block(blk)
ret_ty = conv_type(ret_ty)
blks.map do |blk|
[MethodSignature.new(lead_tys, opt_tys, rest_ty, [], kw_tys, kw_rest_ty, blk), ret_ty]
end
end
# File typeprof-0.12.0/lib/typeprof/import.rb, line 604
def conv_method_def(method_name, mdef, rbs_source)
sig_rets = mdef[:sig_rets].flat_map do |sig_ret|
conv_func(sig_ret)
end
TypedMethodDef.new(sig_rets, rbs_source, mdef[:visibility])
end
# File typeprof-0.12.0/lib/typeprof/import.rb, line 652
def conv_type(ty)
case ty.first
when :class then path_to_klass(ty[1])
when :instance then Type::Instance.new(path_to_klass(ty[1]))
when :cell
Type::Cell.new(Type::Cell::Elements.new(ty[2].map {|ty| conv_type(ty) }), conv_type(ty[1]))
when :any then Type.any
when :void then Type::Void.new
when :nil then Type.nil
when :optional then Type.optional(conv_type(ty[1]))
when :bool then Type.bool
when :self then Type::Var.new(:self)
when :int then Type::Instance.new(Type::Builtin[:int])
when :str then Type::Instance.new(Type::Builtin[:str])
when :sym then Type::Symbol.new(ty.last, Type::Instance.new(Type::Builtin[:sym]))
when :true then Type::Instance.new(Type::Builtin[:true])
when :false then Type::Instance.new(Type::Builtin[:false])
when :array
_, path, lead_tys, rest_ty = ty
lead_tys = lead_tys.map {|ty| conv_type(ty) }
rest_ty = conv_type(rest_ty)
base_type = Type::Instance.new(path_to_klass(path))
Type::Array.new(Type::Array::Elements.new(lead_tys, rest_ty), base_type)
when :hash
_, path, (k, v) = ty
Type.gen_hash(Type::Instance.new(path_to_klass(path))) do |h|
k_ty = conv_type(k)
v_ty = conv_type(v)
h[k_ty] = v_ty
end
when :hash_record
_, path, key_tys = ty
Type.gen_hash(Type::Instance.new(path_to_klass(path))) do |h|
key_tys.each do |key, ty|
k_ty = Type::Symbol.new(key, Type::Instance.new(Type::Builtin[:sym]))
v_ty = conv_type(ty)
h[k_ty] = v_ty
end
end
when :union
tys = ty[1]
Type::Union.new(Utils::Set[*tys.map {|ty2| conv_type(ty2) }], nil).normalize # XXX: Array and Hash support
when :var
Type::Var.new(ty[1])
when :proc
msig, ret_ty = conv_func(ty[1]).first # Currently, RBS Proc does not accept a block, so the size should be always one
Type::Proc.new(TypedBlock.new(msig, ret_ty), Type::Instance.new(Type::Builtin[:proc]))
else
pp ty
raise NotImplementedError
end
end
# File typeprof-0.12.0/lib/typeprof/import.rb, line 511
def import(explicit = false)
classes = @json[:classes].map do |classpath, cdef|
type_params = cdef[:type_params]
superclass, superclass_type_args = cdef[:superclass]
members = cdef[:members]
name = classpath.last
superclass = path_to_klass(superclass) if superclass
base_klass = path_to_klass(classpath[0..-2])
klass = @scratch.get_constant(base_klass, name)
if klass.is_a?(Type::Any)
klass = @scratch.new_class(base_klass, name, type_params, superclass, nil)
# There builtin classes are needed to interpret RBS declarations
case classpath
when [:NilClass] then Type::Builtin[:nil] = klass
when [:TrueClass] then Type::Builtin[:true] = klass
when [:FalseClass] then Type::Builtin[:false] = klass
when [:Integer] then Type::Builtin[:int] = klass
when [:String] then Type::Builtin[:str] = klass
when [:Symbol] then Type::Builtin[:sym] = klass
when [:Array] then Type::Builtin[:ary] = klass
when [:Hash] then Type::Builtin[:hash] = klass
when [:Proc] then Type::Builtin[:proc] = klass
end
end
[klass, superclass_type_args, members]
end
classes.each do |klass, superclass_type_args, members|
@scratch.add_superclass_type_args!(klass, superclass_type_args&.map {|ty| conv_type(ty) })
modules = members[:modules]
methods = members[:methods]
attr_methods = members[:attr_methods]
ivars = members[:ivars]
cvars = members[:cvars]
rbs_sources = members[:rbs_sources]
modules.each do |kind, mods|
mods.each do |mod, type_args|
type_args = type_args&.map {|ty| conv_type(ty) }
case kind
when :include
@scratch.mix_module(:after, klass, path_to_klass(mod), type_args, false, nil)
when :extend
@scratch.mix_module(:after, klass, path_to_klass(mod), type_args, true, nil)
when :prepend
@scratch.mix_module(:before, klass, path_to_klass(mod), type_args, false, nil)
end
end
end
methods.each do |(singleton, method_name), mdef|
rbs_source = explicit ? rbs_sources[[singleton, method_name]] : nil
mdef = conv_method_def(method_name, mdef, rbs_source)
@scratch.add_method(klass, method_name, singleton, mdef)
end
attr_methods.each do |(singleton, method_name), mdef|
kind = mdef[:kind]
ivar = mdef[:ivar]
ty = conv_type(mdef[:ty]).remove_type_vars
@scratch.add_attr_method(klass, ivar, :"@#{ ivar }", kind, mdef[:visibility], nil)
@scratch.add_ivar_write!(Type::Instance.new(klass), :"@#{ ivar }", ty, nil)
end
ivars.each do |ivar_name, ty|
ty = conv_type(ty).remove_type_vars
@scratch.add_ivar_write!(Type::Instance.new(klass), ivar_name, ty, nil)
end
cvars.each do |ivar_name, ty|
ty = conv_type(ty).remove_type_vars
@scratch.add_cvar_write!(klass, ivar_name, ty, nil)
end
end
@json[:constants].each do |classpath, value|
base_klass = path_to_klass(classpath[0..-2])
value = conv_type(value).remove_type_vars
@scratch.add_constant(base_klass, classpath[-1], value, nil)
end
@json[:globals].each do |name, ty|
ty = conv_type(ty).remove_type_vars
@scratch.add_gvar_write!(name, ty, nil)
end
true
end
# File typeprof-0.12.0/lib/typeprof/import.rb, line 705
def path_to_klass(path)
klass = Type::Builtin[:obj]
path.each do |name|
klass = @scratch.get_constant(klass, name)
if klass == Type.any
raise TypeProfError.new("A constant `#{ path.join("::") }' is used but not defined in RBS")
end
end
klass
end