module T::Private::Methods::CallValidation

def self.wrap_method_if_needed(mod, method_sig, original_method)

Returns:
  • (UnboundMethod) - the new wrapper method (or the original one if we didn't wrap it)

Parameters:
  • method_sig (T::Private::Methods::Signature) --
def self.wrap_method_if_needed(mod, method_sig, original_method)
  original_visibility = visibility_method_name(mod, method_sig.method_name)
  if method_sig.mode == T::Private::Methods::Modes.abstract
    T::Private::ClassUtils.replace_method(mod, method_sig.method_name) do |*args, &blk|
      # TODO: write a cop to ensure that abstract methods have an empty body
      #
      # We allow abstract methods to be implemented by things further down the ancestor chain.
      # So, if a super method exists, call it.
      if defined?(super)
        super(*args, &blk)
      else
        raise NotImplementedError.new(
          "The method `#{method_sig.method_name}` on #{mod} is declared as `abstract`. It does not have an implementation."
        )
      end
    end
  # Note, this logic is duplicated (intentionally, for micro-perf) at `Methods._on_method_added`,
  # make sure to keep changes in sync.
  # This is a trapdoor point for each method:
  # if a given method is wrapped, it stays wrapped; and if not, it's never wrapped.
  # (Therefore, we need the `@wrapped_tests_with_validation` check in `T::RuntimeLevels`.)
  elsif method_sig.check_level == :always || (method_sig.check_level == :tests && T::Private::RuntimeLevels.check_tests?)
    create_validator_method(mod, original_method, method_sig, original_visibility)
  else
    T::Configuration.without_ruby_warnings do
      # get all the shims out of the way and put back the original method
      T::Private::DeclState.current.without_on_method_added do
        mod.send(:define_method, method_sig.method_name, original_method)
      end
      mod.send(original_visibility, method_sig.method_name)
    end
  end
  # Return the newly created method (or the original one if we didn't replace it)
  mod.instance_method(method_sig.method_name)
end