class TypeProf::Core::EscapeBox::HashSplatBox::MethodCallBox
Attributes
Public Class Methods
Source
# File bundled-src/typeprof-0.31.1/lib/typeprof/core/graph/box.rb, line 705 def initialize(node, genv, recv, mid, a_args, subclasses) raise mid.to_s unless mid super(node) @recv = recv.new_vertex(genv, node) @recv.add_edge(genv, self) @mid = mid @a_args = a_args.new_vertexes(genv, node) @a_args.keywords.add_edge(genv, self) if @a_args.keywords @a_args.block.add_edge(genv, self) if @a_args.block @ret = Vertex.new(node) @subclasses = subclasses @generics = {} end
Calls superclass method
TypeProf::Core::Box::new
Public Instance Methods
Source
# File bundled-src/typeprof-0.31.1/lib/typeprof/core/graph/box.rb, line 781 def resolve(genv, changes, &blk) @recv.each_type do |orig_ty| next if orig_ty == Type::Bot.new(genv) if @mid == :"*super" mid = @node.lenv.cref.mid skip = true else mid = @mid skip = false end ty = orig_ty.base_type(genv) base_ty_env = Type.default_param_map(genv, ty) alias_limit = 0 while ty unless skip # First check prepended modules if !ty.is_a?(Type::Singleton) if resolve_prepended_modules(genv, changes, base_ty_env, ty, mid) do |me, ty, mid| yield me, ty, mid, orig_ty end break end end # Then check the class/module itself me = ty.mod.get_method(ty.is_a?(Type::Singleton), mid) changes.add_depended_method_entity(me) if changes if !me.aliases.empty? mid = me.aliases.values.first alias_limit += 1 redo if alias_limit < 5 end if me.exist? yield me, ty, mid, orig_ty break end end skip = false if ty.is_a?(Type::Singleton) # TODO: extended modules else # Finally check included modules break if resolve_included_modules(genv, changes, base_ty_env, ty, mid) do |me, ty, mid| yield me, ty, mid, orig_ty end end ty = genv.get_superclass_type(ty, changes, base_ty_env) end yield nil, nil, mid, orig_ty unless ty end end
Source
# File bundled-src/typeprof-0.31.1/lib/typeprof/core/graph/box.rb, line 872 def resolve_included_modules(genv, changes, base_ty_env, ty, mid, &blk) found = false alias_limit = 0 ty.mod.self_types.each do |(mdecl, idx), self_ty_mod| raise unless mdecl.is_a?(AST::SigModuleNode) if self_ty_mod.type_params self_ty = genv.get_instance_type(self_ty_mod, mdecl.self_type_args[idx], changes, base_ty_env, ty) else self_ty = Type::Instance.new(genv, self_ty_mod, []) end me = self_ty.mod.get_method(false, mid) changes.add_depended_method_entity(me) if changes if !me.aliases.empty? mid = me.aliases.values.first alias_limit += 1 redo if alias_limit < 5 end if me.exist? found = true yield me, self_ty, mid else found ||= resolve_included_modules(genv, changes, base_ty_env, self_ty, mid, &blk) end end alias_limit = 0 ty.mod.included_modules.each do |inc_decl, inc_mod| if inc_decl.is_a?(AST::SigIncludeNode) && inc_mod.type_params inc_ty = genv.get_instance_type(inc_mod, inc_decl.args, changes, base_ty_env, ty) else type_params = inc_mod.type_params.map {|ty_param| Source.new() } # TODO: better support inc_ty = Type::Instance.new(genv, inc_mod, type_params) end me = inc_ty.mod.get_method(false, mid) changes.add_depended_method_entity(me) if changes if !me.aliases.empty? mid = me.aliases.values.first alias_limit += 1 redo if alias_limit < 5 end if me.exist? found = true yield me, inc_ty, mid else found ||= resolve_included_modules(genv, changes, base_ty_env, inc_ty, mid, &blk) end end found end
Source
# File bundled-src/typeprof-0.31.1/lib/typeprof/core/graph/box.rb, line 840 def resolve_prepended_modules(genv, changes, base_ty_env, ty, mid, &blk) found = false alias_limit = 0 # Process prepended modules in reverse order (last prepended = first in ancestor chain) ty.mod.prepended_modules.reverse_each do |prep_decl, prep_mod| if prep_decl.is_a?(AST::SigPrependNode) && prep_mod.type_params prep_ty = genv.get_instance_type(prep_mod, prep_decl.args, changes, base_ty_env, ty) else type_params = prep_mod.type_params.map {|ty_param| Source.new() } # TODO: better support prep_ty = Type::Instance.new(genv, prep_mod, type_params) end me = prep_ty.mod.get_method(false, mid) changes.add_depended_method_entity(me) if changes if !me.aliases.empty? mid = me.aliases.values.first alias_limit += 1 redo if alias_limit < 5 end if me.exist? found = true yield me, prep_ty, mid else found = resolve_prepended_modules(genv, changes, base_ty_env, prep_ty, mid, &blk) end break if found end found end
Source
# File bundled-src/typeprof-0.31.1/lib/typeprof/core/graph/box.rb, line 925 def resolve_subclasses(genv, changes) # TODO: This does not follow new subclasses @recv.each_type do |ty| next if ty == Type::Bot.new(genv) base_ty = ty.base_type(genv) singleton = base_ty.is_a?(Type::Singleton) mod = base_ty.mod mod.each_descendant do |desc_mod| next if mod == desc_mod me = desc_mod.get_method(singleton, @mid) changes.add_depended_method_entity(me) if me && me.exist? yield ty, me end end end end
Source
# File bundled-src/typeprof-0.31.1/lib/typeprof/core/graph/box.rb, line 721 def run0(genv, changes) edges = Set[] called_mdefs = Set[] error_count = 0 resolve(genv, changes) do |me, ty, mid, orig_ty| if !me # TODO: undefined method error if error_count < 3 meth = @node.mid_code_range ? :mid_code_range : :code_range changes.add_diagnostic(meth, "undefined method: #{ orig_ty.show }##{ mid }") end error_count += 1 elsif me.builtin && me.builtin[changes, @node, orig_ty, @a_args, @ret] # do nothing elsif !me.decls.empty? # TODO: support "| ..." me.decls.each do |mdecl| # TODO: union type is ok? # TODO: add_depended_method_entity for types used to resolve overloads ty_env = Type.default_param_map(genv, orig_ty) if ty.is_a?(Type::Instance) ty.mod.type_params.zip(ty.args) do |param, arg| ty_env[param] = arg end end mdecl.resolve_overloads(changes, genv, @node, ty_env, @a_args, @ret) do |method_type| @generics[method_type] ||= method_type.type_params.map {|var| Vertex.new(@node) } end end elsif !me.defs.empty? me.defs.each do |mdef| next if called_mdefs.include?(mdef) called_mdefs << mdef mdef.call(changes, genv, @a_args, @ret) end else pp me raise end end if @subclasses resolve_subclasses(genv, changes) do |recv_ty, me| if !me.defs.empty? me.defs.each do |mdef| next if called_mdefs.include?(mdef) called_mdefs << mdef mdef.call(changes, genv, @a_args, @ret) end end end end edges.each do |src, dst| changes.add_edge(genv, src, dst) end if error_count > 3 meth = @node.mid_code_range ? :mid_code_range : :code_range changes.add_diagnostic(meth, "... and other #{ error_count - 3 } errors") end end