Module: T::AbstractUtils

Defined in:
lib/types/abstract_utils.rb

Overview

typed: true

Constant Summary collapse

Methods =
T::Private::Methods

Class Method Summary collapse

Class Method Details

.abstract_method?(method) ⇒ Boolean

Returns:



18
19
20
21
# 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) ⇒ Object

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



25
26
27
28
29
30
31
32
33
34
35
# 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) ⇒ Boolean

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.

Returns:



14
15
16
# 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) ⇒ Object

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



39
40
41
42
43
44
45
46
47
48
49
# 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