Class: TypeProf::Import
Relationships & Source Files | |
Inherits: | Object |
Defined in: | lib/typeprof/import.rb |
Class Method Summary
Instance Method Summary
Constructor Details
.new(scratch, json) ⇒ Import
# File 'lib/typeprof/import.rb', line 515
def initialize(scratch, json) @scratch = scratch @json = json end
Class Method Details
.import_builtin(scratch)
[ GitHub ].import_library(scratch, feature)
[ GitHub ]# File 'lib/typeprof/import.rb', line 494
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
.import_rbs_code(scratch, rbs_name, rbs_code)
[ GitHub ].import_rbs_files(scratch, rbs_paths)
[ GitHub ]Instance Method Details
#conv_block(blk)
[ GitHub ]# File 'lib/typeprof/import.rb', line 655
def conv_block(blk) return [Type.nil] unless blk required_block = blk[:required_block] lead_tys = blk[:lead_tys] opt_tys = blk[:opt_tys] rest_ty = blk[:rest_ty] req_kw_tys = blk[:req_kw_tys] opt_kw_tys = blk[:opt_kw_tys] rest_kw_ty = blk[:rest_kw_ty] ret_ty = blk[: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)] } if rest_kw_ty ty = conv_type(rest_kw_ty) kw_rest_ty = Type.gen_hash do |h| k_ty = Type::Instance.new(Type::Builtin[:sym]) h[k_ty] = ty end end msig = MethodSignature.new(lead_tys, opt_tys, rest_ty, [], kw_tys, kw_rest_ty, Type.nil) ret_ty = conv_type(ret_ty) ret = [Type::Proc.new(TypedBlock.new(msig, ret_ty), Type::Builtin[:proc])] ret << Type.nil unless required_block ret end
#conv_func(sig_ret)
[ GitHub ]# File 'lib/typeprof/import.rb', line 621
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)] } if rest_kw_ty ty = conv_type(rest_kw_ty) kw_rest_ty = Type.gen_hash do |h| k_ty = Type::Instance.new(Type::Builtin[:sym]) h[k_ty] = ty end end 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
#conv_method_def(method_name, mdef, rbs_source)
[ GitHub ]# File 'lib/typeprof/import.rb', line 613
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
#conv_type(ty)
[ GitHub ]# File 'lib/typeprof/import.rb', line 690
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.create(Utils::Set[*tys.map {|ty2| conv_type(ty2) }], nil) # 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
#import(explicit = false)
[ GitHub ]# File 'lib/typeprof/import.rb', line 520
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