module T::AbstractUtils

def self.abstract_method?(method)

def self.abstract_method?(method)
  signature = Methods.signature_for_method(method)
  signature&.mode == Methods::Modes.abstract
end

def self.abstract_methods_for(mod)

that have not been implemented.
Given a module, returns the set of methods declared as abstract (in itself or ancestors)
def self.abstract_methods_for(mod)
  declared_methods = declared_abstract_methods_for(mod)
  declared_methods.select do |declared_method|
    actual_method = mod.instance_method(declared_method.name)
    # Note that in the case where an abstract method is overridden by another abstract method,
    # this method will return them both. This is intentional to ensure we validate the final
    # implementation against all declarations of an abstract method (they might not all have the
    # same signature).
    abstract_method?(actual_method)
  end
end

def self.abstract_module?(mod)

ones, will still have `Abstract::Hooks` as an ancestor.
a class extends `Abstract::Hooks`, all of its subclasses, including the eventual concrete
Note that checking `mod.is_a?(Abstract::Hooks)` is not a safe substitute for this method; when

(because we validate that and raise an error otherwise).
this is equivalent to whether it has any abstract methods that haven't been implemented
Returns whether a module is declared as abstract. After the module is finished being declared,
def self.abstract_module?(mod)
  !T::Private::Abstract::Data.get(mod, :abstract_type).nil?
end

def self.declared_abstract_methods_for(mod)

regardless of whether they have been implemented.
Given a module, returns the set of methods declared as abstract (in itself or ancestors)
def self.declared_abstract_methods_for(mod)
  methods = []
  mod.ancestors.each do |ancestor|
    ancestor_methods = ancestor.private_instance_methods(false) + ancestor.instance_methods(false)
    ancestor_methods.each do |method_name|
      method = ancestor.instance_method(method_name)
      methods << method if abstract_method?(method)
    end
  end
  methods
end