class TypeProf::Core::MethodDeclBox - typeprof: Ruby Standard Library Documentation

# class TypeProf::Core::MethodDeclBox

### Attributes

cpath[R]
method_types[R]
mid[R]
node[RW]
overloading[R]
ret[R]
singleton[R]

### Public Class Methods

new(node, genv, cpath, singleton, mid, method_types, overloading) click to toggle source
Calls superclass method `TypeProf::Core::Box::new`

    # File typeprof-0.30.1/lib/typeprof/core/graph/box.rb, line 96
    def initialize(node, genv, cpath, singleton, mid, method_types, overloading)
      super(node)
      @cpath = cpath
      @singleton = singleton
      @mid = mid
      @method_types = method_types
      @overloading = overloading
      @ret = Source.new

      me = genv.resolve_method(@cpath, @singleton, @mid)
      me.add_decl(self)
      me.add_run_all_method_call_boxes(genv)
      me.add_run_all_mdefs(genv)
    end

### Public Instance Methods

destroy(genv) click to toggle source

    # File typeprof-0.30.1/lib/typeprof/core/graph/box.rb, line 115
    def destroy(genv)
      me = genv.resolve_method(@cpath, @singleton, @mid)
      me.remove_decl(self)
      me.add_run_all_method_call_boxes(genv)
    end

match_arguments?(genv, changes, param_map, a_args, method_type) click to toggle source

    # File typeprof-0.30.1/lib/typeprof/core/graph/box.rb, line 121
    def match_arguments?(genv, changes, param_map, a_args, method_type)
      # TODO: handle a tuple as a splat argument?
      if a_args.splat_flags.any?
        return false unless method_type.rest_positionals
        method_type.req_positionals.size.times do |i|
          return false if a_args.splat_flags[i]
        end
        method_type.post_positionals.size.times do |i|
          return false if a_args.splat_flags[-i - 1]
        end
      else
        actual = a_args.positionals.size
        required_formal = method_type.req_positionals.size + method_type.post_positionals.size
        if actual < required_formal
          # too few actual arguments
          return false
        end
        if !method_type.rest_positionals && actual > required_formal + method_type.opt_positionals.size
          # too many actual arguments
          return false
        end
      end

      method_type.req_positionals.each_with_index do |ty, i|
        f_arg = ty.contravariant_vertex(genv, changes, param_map)
        return false unless a_args.positionals[i].check_match(genv, changes, f_arg)
      end
      method_type.post_positionals.each_with_index do |ty, i|
        f_arg = ty.contravariant_vertex(genv, changes, param_map)
        i -= method_type.post_positionals.size
        return false unless a_args.positionals[i].check_match(genv, changes, f_arg)
      end

      start_rest = method_type.req_positionals.size
      end_rest = a_args.positionals.size - method_type.post_positionals.size

      i = 0
      while i < method_type.opt_positionals.size && start_rest < end_rest
        break if a_args.splat_flags[start_rest]
        f_arg = method_type.opt_positionals[i].contravariant_vertex(genv, changes, param_map)
        return false unless a_args.positionals[start_rest].check_match(genv, changes, f_arg)
        i += 1
        start_rest += 1
      end

      if start_rest < end_rest
        vtxs = a_args.get_rest_args(genv, start_rest, end_rest)
        while i < method_type.opt_positionals.size
          f_arg = method_type.opt_positionals[i].contravariant_vertex(genv, changes, param_map)
          return false if vtxs.any? {|vtx| !vtx.check_match(genv, changes, f_arg) }
          i += 1
        end
        if method_type.rest_positionals
          f_arg = method_type.rest_positionals.contravariant_vertex(genv, changes, param_map)
          return false if vtxs.any? {|vtx| !vtx.check_match(genv, changes, f_arg) }
        end
      end

      return true
    end

resolve_overloads(changes, genv, node, param_map, a_args, ret) { |method_type| ... } click to toggle source

    # File typeprof-0.30.1/lib/typeprof/core/graph/box.rb, line 182
    def resolve_overloads(changes, genv, node, param_map, a_args, ret)
      match_any_overload = false
      @method_types.each do |method_type|
        param_map0 = param_map.dup
        if method_type.type_params
          method_type.type_params.zip(yield(method_type)) do |var, vtx|
            param_map0[var] = vtx
          end
        end

        next unless match_arguments?(genv, changes, param_map0, a_args, method_type)

        rbs_blk = method_type.block
        next if method_type.block_required && !a_args.block
        next if !rbs_blk && a_args.block
        if rbs_blk && a_args.block
          # rbs_blk_func.optional_keywords, ...
          a_args.block.each_type do |ty|
            case ty
            when Type::Proc
              blk_f_ret = rbs_blk.return_type.contravariant_vertex(genv, changes, param_map0)
              blk_a_args = rbs_blk.req_positionals.map do |blk_a_arg|
                blk_a_arg.covariant_vertex(genv, changes, param_map0)
              end

              ty.block.accept_args(genv, changes, blk_a_args, blk_f_ret, true)
            end
          end
        end
        ret_vtx = method_type.return_type.covariant_vertex(genv, changes, param_map0)

        changes.add_edge(genv, ret_vtx, ret)
        match_any_overload = true
      end
      unless match_any_overload
        meth = node.mid_code_range ? :mid_code_range : :code_range
        changes.add_diagnostic(meth, "failed to resolve overloads")
      end
    end

show() click to toggle source

    # File typeprof-0.30.1/lib/typeprof/core/graph/box.rb, line 222
    def show
      @method_types.map do |method_type|
        args = []
        method_type.req_positionals.each do |arg|
          args << arg.show
        end
        method_type.opt_positionals.each do |arg|
          args << "?#{arg.show}"
        end
        if method_type.rest_positionals
          args << "*#{method_type.rest_positionals.show}"
        end
        method_type.post_positionals.each do |arg|
          args << arg.show
        end

        method_type.req_keywords.each do |key, arg|
          args << "#{ key }: #{arg.show}"
        end
        method_type.opt_keywords.each do |key, arg|
          args << "?#{ key }: #{arg.show}"
        end
        if method_type.rest_keywords
          args << "**#{method_type.rest_keywords.show}"
        end

        s = args.empty? ? "-> " : "(#{ args.join(", ") }) -> "
        s += method_type.return_type.show
      end.join(" | ")
    end