module T::AbstractUtils

typed: true

Constants

Methods

Private Class Methods

abstract_method?(method) click to toggle source
# File lib/types/abstract_utils.rb, line 18
def self.abstract_method?(method)
  signature = Methods.signature_for_method(method)
  signature&.mode == Methods::Modes.abstract
end
abstract_methods_for(mod) click to toggle source

Given a module, returns the set of methods declared as abstract (in itself or ancestors) that have not been implemented.

# File lib/types/abstract_utils.rb, line 25
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
abstract_module?(mod) click to toggle source

Returns whether a module is declared as abstract. After the module is finished being declared, this is equivalent to whether it has any abstract methods that haven't been implemented (because we validate that and raise an error otherwise).

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

# File lib/types/abstract_utils.rb, line 14
def self.abstract_module?(mod)
  !T::Private::Abstract::Data.get(mod, :abstract_type).nil?
end
declared_abstract_methods_for(mod) click to toggle source

Given a module, returns the set of methods declared as abstract (in itself or ancestors) regardless of whether they have been implemented.

# File lib/types/abstract_utils.rb, line 39
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