module T::Utils

def self.arity(method)

Returns the arity of a method, unwrapping the sig if needed
def self.arity(method)
  arity = method.arity
  return arity if arity != -1 || method.is_a?(Proc)
  sig = T::Private::Methods.signature_for_method(method)
  sig ? sig.method.arity : arity
end

def self.coerce(val)

Used to convert from a type specification to a `T::Types::Base`.
def self.coerce(val)
  if val.is_a?(T::Private::Types::TypeAlias)
    val.aliased_type
  elsif val.is_a?(T::Types::Base)
    val
  elsif val == ::Array
    T::Array[T.untyped]
  elsif val == ::Set
    T::Set[T.untyped]
  elsif val == ::Hash
    T::Hash[T.untyped, T.untyped]
  elsif val == ::Enumerable
    T::Enumerable[T.untyped]
  elsif val == ::Enumerator
    T::Enumerator[T.untyped]
  elsif val == ::Range
    T::Range[T.untyped]
  elsif val.is_a?(Module)
    T::Types::Simple::Private::Pool.type_for_module(val)
  elsif val.is_a?(::Array)
    T::Types::FixedArray.new(val)
  elsif val.is_a?(::Hash)
    T::Types::FixedHash.new(val)
  elsif val.is_a?(T::Private::Methods::DeclBuilder)
    T::Private::Methods.finalize_proc(val.decl)
  elsif val.is_a?(::T::Enum)
    T::Types::TEnum.new(val)
  elsif val.is_a?(::String)
    raise "Invalid String literal for type constraint. Must be an #{T::Types::Base}, a " \
          "class/module, or an array. Got a String with value `#{val}`."
  else
    raise "Invalid value for type constraint. Must be an #{T::Types::Base}, a " \
          "class/module, or an array. Got a `#{val.class}`."
  end
end

def self.lift_enum(enum)

def self.lift_enum(enum)
  unless enum.is_a?(T::Types::Enum)
    raise ArgumentError.new("#{enum.inspect} is not a T.enum")
  end
  classes = enum.values.map(&:class).uniq
  if classes.empty?
    T.untyped
  elsif classes.length > 1
    T::Types::Union.new(classes)
  else
    T::Types::Simple::Private::Pool.type_for_module(classes.first)
  end
end

def self.methods_excluding_object(mod)

ancestors) are included.
ancestors, excluding Object and its ancestors. Overrides of methods from Object (and its
Returns the set of all methods (public, protected, private) defined on a module or its
def self.methods_excluding_object(mod)
  # We can't just do mod.instance_methods - Object.instance_methods, because that would leave out
  # any methods from Object that are overridden in mod.
  mod.ancestors.flat_map do |ancestor|
    # equivalent to checking Object.ancestors.include?(ancestor)
    next [] if Object <= ancestor
    ancestor.instance_methods(false) + ancestor.private_instance_methods(false)
  end.uniq
end

def self.resolve_alias(type)

Return the underlying type for a type alias. Otherwise returns type.
def self.resolve_alias(type)
  case type
  when T::Private::Types::TypeAlias
    type.aliased_type
  else
    type
  end
end

def self.run_all_sig_blocks

Unwraps all the sigs.
def self.run_all_sig_blocks
  T::Private::Methods.run_all_sig_blocks
end

def self.signature_for_instance_method(mod, method_name)

Other tags:
    Example: T::Utils.signature_for_instance_method(MyClass, :my_method) -
def self.signature_for_instance_method(mod, method_name)
  T::Private::Methods.signature_for_method(mod.instance_method(method_name))
end

def self.signature_for_method(method)

Other tags:
    Example: T::Utils.signature_for_method(x.method(:foo)) -
def self.signature_for_method(method)
  T::Private::Methods.signature_for_method(method)
end

def self.string_truncate_middle(str, start_len, end_len, ellipsis='...')

Returns:
  • (String) -

Parameters:
  • ellipsis (String) -- The string to add in place of the elided text
  • end_len (Fixnum) -- The length of string after the ellipsis
  • start_len (Fixnum) -- The length of string before the ellipsis
  • str (String) --
def self.string_truncate_middle(str, start_len, end_len, ellipsis='...')
  return unless str
  raise ArgumentError.new('must provide start_len') unless start_len
  raise ArgumentError.new('must provide end_len') unless end_len
  raise ArgumentError.new('start_len must be >= 0') if start_len < 0
  raise ArgumentError.new('end_len must be >= 0') if end_len < 0
  str = str.to_s
  return str if str.length <= start_len + end_len
  start_part = str[0...start_len - ellipsis.length]
  end_part = end_len == 0 ? '' : str[-end_len..-1]
  "#{start_part}#{ellipsis}#{end_part}"
end

def self.unwrap_nilable(type)

If so, returns the T::Types::Base of the something else. Otherwise, returns nil.
Give a type which is a subclass of T::Types::Base, determines if the type is a simple nilable type (union of NilClass and something else).
def self.unwrap_nilable(type)
  case type
  when T::Types::Union
    non_nil_types = type.types.reject {|t| t == Nilable::NIL_TYPE}
    if non_nil_types.length == 1
      non_nil_types.first
    else
      nil
    end
  else
    nil
  end
end

def self.wrap_method_with_call_validation_if_needed(mod, method_sig, original_method)

def self.wrap_method_with_call_validation_if_needed(mod, method_sig, original_method)
  T::Private::Methods::CallValidation.wrap_method_if_needed(mod, method_sig, original_method)
end