# frozen_string_literal: true# typed: truemoduleT::Utils# Used to convert from a type specification to a `T::Types::Base`.defself.coerce(val)ifval.is_a?(T::Private::Types::TypeAlias)val.aliased_typeelsifval.is_a?(T::Types::Base)valelsifval.is_a?(Module)T::Types::Simple::Private::Pool.type_for_module(val)elsifval.is_a?(::Array)T::Types::FixedArray.new(val)elsifval.is_a?(::Hash)T::Types::FixedHash.new(val)elsifval.is_a?(T::Private::Methods::DeclBuilder)T::Private::Methods.finalize_proc(val.decl)elsifval.is_a?(::T::Enum)T::Types::TEnum.new(val)elsifval.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}`."elseraise"Invalid value for type constraint. Must be an #{T::Types::Base}, a "\"class/module, or an array. Got a `#{val.class}`."endend# Dynamically confirm that `value` is recursively a valid value of# type `type`, including recursively through collections. Note that# in some cases this runtime check can be very expensive, especially# with large collections of objects.defself.check_type_recursive!(value,type)T::Private::Casts.cast_recursive(value,type,cast_method: "T.check_type_recursive!")end# Returns the set of all methods (public, protected, private) defined on a module or its# ancestors, excluding Object and its ancestors. Overrides of methods from Object (and its# ancestors) are included.defself.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_mapdo|ancestor|# equivalent to checking Object.ancestors.include?(ancestor)next[]ifObject<=ancestorancestor.instance_methods(false)+ancestor.private_instance_methods(false)end.uniqend# Returns the signature for the `UnboundMethod`, or nil if it's not sig'd## @example T::Utils.signature_for_method(x.method(:foo))defself.signature_for_method(method)T::Private::Methods.signature_for_method(method)end# Returns the signature for the instance method on the supplied module, or nil if it's not found or not typed.## @example T::Utils.signature_for_instance_method(MyClass, :my_method)defself.signature_for_instance_method(mod,method_name)T::Private::Methods.signature_for_method(mod.instance_method(method_name))enddefself.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# Unwraps all the sigs.defself.run_all_sig_blocksT::Private::Methods.run_all_sig_blocksend# Return the underlying type for a type alias. Otherwise returns type.defself.resolve_alias(type)casetypewhenT::Private::Types::TypeAliastype.aliased_typeelsetypeendend# 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).# If so, returns the T::Types::Base of the something else. Otherwise, returns nil.defself.unwrap_nilable(type)casetypewhenT::Types::Unionnon_nil_types=type.types.reject{|t|t==Nilable::NIL_TYPE}returnniliftype.types.length==non_nil_types.lengthcasenon_nil_types.lengthwhen0thennilwhen1thennon_nil_types.firstelseT::Types::Union::Private::Pool.union_of_types(non_nil_types[0],non_nil_types[1],non_nil_types[2..-1])endelsenilendend# Returns the arity of a method, unwrapping the sig if neededdefself.arity(method)arity=method.arityreturnarityifarity!=-1||method.is_a?(Proc)sig=T::Private::Methods.signature_for_method(method)sig?sig.method.arity:arityend# Elide the middle of a string as needed and replace it with an ellipsis.# Keep the given number of characters at the start and end of the string.## This method operates on string length, not byte length.## If the string is shorter than the requested truncation length, return it# without adding an ellipsis. This method may return a longer string than# the original if the characters removed are shorter than the ellipsis.## @param [String] str## @param [Fixnum] start_len The length of string before the ellipsis# @param [Fixnum] end_len The length of string after the ellipsis## @param [String] ellipsis The string to add in place of the elided text## @return [String]#defself.string_truncate_middle(str,start_len,end_len,ellipsis='...')returnunlessstrraiseArgumentError.new('must provide start_len')unlessstart_lenraiseArgumentError.new('must provide end_len')unlessend_lenraiseArgumentError.new('start_len must be >= 0')ifstart_len<0raiseArgumentError.new('end_len must be >= 0')ifend_len<0str=str.to_sreturnstrifstr.length<=start_len+end_lenstart_part=str[0...start_len-ellipsis.length]end_part=end_len==0?'':str[-end_len..-1]"#{start_part}#{ellipsis}#{end_part}"enddefself.lift_enum(enum)unlessenum.is_a?(T::Types::Enum)raiseArgumentError.new("#{enum.inspect} is not a T.deprecated_enum")endclasses=enum.values.map(&:class).uniqifclasses.empty?T.untypedelsifclasses.length>1T::Types::Union.new(classes)elseT::Types::Simple::Private::Pool.type_for_module(classes.first)endendmoduleNilable# :is_union_type, T::Boolean: whether the type is an T::Types::Union type# :non_nilable_type, Class: if it is an T.nilable type, the corresponding underlying type; otherwise, nil.TypeInfo=Struct.new(:is_union_type,:non_nilable_type)NIL_TYPE=T::Utils.coerce(NilClass)defself.get_type_info(prop_type)ifprop_type.is_a?(T::Types::Union)non_nilable_type=T::Utils.unwrap_nilable(prop_type)ifnon_nilable_type&.is_a?(T::Types::Simple)non_nilable_type=non_nilable_type.raw_typeendTypeInfo.new(true,non_nilable_type)elseTypeInfo.new(false,nil)endend# Get the underlying type inside prop_type:# - if the type is A, the function returns A# - if the type is T.nilable(A), the function returns Adefself.get_underlying_type(prop_type)type_info=get_type_info(prop_type)iftype_info.is_union_typetype_info.non_nilable_type||prop_typeelsifprop_type.is_a?(T::Types::Simple)prop_type.raw_typeelseprop_typeendend# The difference between this function and the above function is that the Sorbet type, like T::Types::Simple# is preserved.defself.get_underlying_type_object(prop_type)T::Utils.unwrap_nilable(prop_type)||prop_typeenddefself.is_union_with_nilclass(prop_type)caseprop_typewhenT::Types::Unionprop_type.types.include?(NIL_TYPE)elsefalseendendendend