# 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==::ArrayT::Array[T.untyped]elsifval==::SetT::Set[T.untyped]elsifval==::HashT::Hash[T.untyped,T.untyped]elsifval==::EnumerableT::Enumerable[T.untyped]elsifval==::EnumeratorT::Enumerator[T.untyped]elsifval==::RangeT::Range[T.untyped]elsifval.is_a?(Module)T::Types::Simple.new(val)# rubocop:disable PrisonGuard/UseOpusTypesShortcutelsifval.is_a?(::Array)T::Types::FixedArray.new(val)# rubocop:disable PrisonGuard/UseOpusTypesShortcutelsifval.is_a?(::Hash)T::Types::FixedHash.new(val)# rubocop:disable PrisonGuard/UseOpusTypesShortcutelsifval.is_a?(T::Private::Methods::DeclBuilder)T::Private::Methods.finalize_proc(val.decl)elsifval.is_a?(::T::Enum)T::Types::TEnum.new(val)# rubocop:disable PrisonGuard/UseOpusTypesShortcutelsifval.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# 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# Associates a signature with a forwarder method that matches the signature of the method it# forwards to. This is necessary because forwarder methods are often declared with catch-all# splat parameters, rather than the exact set of parameters ultimately used by the target method,# so they cannot be validated as strictly.## The caller of this method must ensure that the forwarder method properly forwards all parameters# such that the signature is accurate.defself.register_forwarder(from_method,to_method,remove_first_param: false)T::Private::Methods.register_forwarder(from_method,to_method,remove_first_param: remove_first_param)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}ifnon_nil_types.length==1non_nil_types.firstelsenilendelsenilendend# Returns the arity of a method, unwrapping the sig if neededdefself.arity(method)arity=method.arity# rubocop:disable PrisonGuard/NoArityreturnarityifarity!=-1||method.is_a?(Proc)sig=T::Private::Methods.signature_for_method(method)sig?sig.method.arity:arity# rubocop:disable PrisonGuard/NoArityend# 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}"endmoduleNilable# :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&&non_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