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