module T::Private::Methods::SignatureValidation

def self.validate(signature)

def self.validate(signature)
  if signature.method_name == :initialize && signature.method.owner.is_a?(Class)
    # Constructors are special. They look like overrides in terms of a super_method existing,
    # but in practice, you never call them polymorphically. Conceptually, they're standard
    # methods (this is consistent with how they're treated in other languages, e.g. Java)
    if signature.mode != Modes.standard
      raise "`initialize` should not use `.abstract` or `.implementation` or any other inheritance modifiers."
    end
    return
  end
  super_method = signature.method.super_method
  if super_method && super_method.owner != signature.method.owner
    Methods.maybe_run_sig_block_for_method(super_method)
    super_signature = Methods.signature_for_method(super_method)
    # If the super_method has any kwargs we can't build a
    # Signature for it, so we'll just skip validation in that case.
    if !super_signature && !super_method.parameters.select {|kind, _| kind == :rest || kind == :kwrest}.empty?
      nil
    else
      # super_signature can be nil when we're overriding a method (perhaps a builtin) that didn't use
      # one of the method signature helpers. Use an untyped signature so we can still validate
      # everything but types.
      #
      # We treat these signatures as overridable, that way people can use `.override` with
      # overrides of builtins. In the future we could try to distinguish when the method is a
      # builtin and treat non-builtins as non-overridable (so you'd be forced to declare them with
      # `.overridable`).
      #
      super_signature ||= Methods::Signature.new_untyped(method: super_method)
      validate_override_mode(signature, super_signature)
      validate_override_shape(signature, super_signature)
      validate_override_types(signature, super_signature)
    end
  else
    validate_non_override_mode(signature)
  end
end