class T::Private::Methods::Signature
def initialize(method:, method_name:, raw_arg_types:, raw_return_type:, bind:, mode:, check_level:, parameters: method.parameters, soft_notify:, generated: false, override_allow_incompatible: false)
def initialize(method:, method_name:, raw_arg_types:, raw_return_type:, bind:, mode:, check_level:, parameters: method.parameters, soft_notify:, generated: false, override_allow_incompatible: false) @method = method @method_name = method_name @arg_types = [] @kwarg_types = {} @block_type = nil @block_name = nil @rest_type = nil @rest_name = nil @keyrest_type = nil @keyrest_name = nil @return_type = T::Utils.coerce(raw_return_type) @bind = bind ? T::Utils.coerce(bind) : bind @mode = mode @check_level = check_level @req_arg_count = 0 @req_kwarg_names = [] @has_rest = false @has_keyrest = false @parameters = parameters @soft_notify = soft_notify @override_allow_incompatible = override_allow_incompatible @generated = generated @ever_failed = false param_names = parameters.map {|_, name| name} declared_param_names = raw_arg_types.keys missing_names = param_names - declared_param_names extra_names = declared_param_names - param_names if !missing_names.empty? raise "The declaration for `#{method.name}` is missing parameter(s): #{missing_names.join(', ')}" end if !extra_names.empty? raise "The declaration for `#{method.name}` has extra parameter(s): #{extra_names.join(', ')}" end parameters.zip(raw_arg_types) do |(param_kind, param_name), (type_name, raw_type)| if type_name != param_name hint = "" # Ruby reorders params so that required keyword arguments # always precede optional keyword arguments. We can't tell # whether the culprit is the Ruby reordering or user error, so # we error but include a note if param_kind == :keyreq && parameters.any? {|k, _| k == :key} hint = "\n\nNote: Any required keyword arguments must precede any optional keyword " \ "arguments. If your method declaration matches your `def`, try reordering any " \ "optional keyword parameters to the end of the method list." end raise "Parameter `#{type_name}` is declared out of order (declared as arg number " \ "#{declared_param_names.index(type_name) + 1}, defined in the method as arg number " \ "#{param_names.index(type_name) + 1}).#{hint}\nMethod: #{method_desc}" end type = T::Utils.coerce(raw_type) case param_kind when :req if @arg_types.length > @req_arg_count # Note that this is actually is supported by Ruby, but it would add complexity to # support it here, and I'm happy to discourage its use anyway. raise "Required params after optional params are not supported in method declarations. Method: #{method_desc}" end @arg_types << [param_name, type] @req_arg_count += 1 when :opt @arg_types << [param_name, type] when :key, :keyreq @kwarg_types[param_name] = type if param_kind == :keyreq @req_kwarg_names << param_name end when :block @block_name = param_name @block_type = type when :rest @has_rest = true @rest_name = param_name @rest_type = type when :keyrest @has_keyrest = true @keyrest_name = param_name @keyrest_type = type else raise "Unexpected param_kind: `#{param_kind}`. Method: #{method_desc}" end end end