class Bringhurst::TypeObserver

Attributes

method_calls[R]

Public Class Methods

new() click to toggle source
# File lib/bringhurst/type_observer.rb, line 11
def initialize
  @method_calls = []
end

Public Instance Methods

observe_class(klass) click to toggle source
# File lib/bringhurst/type_observer.rb, line 15
def observe_class(klass)
  wrap_instance_methods_of(klass)
  wrap_class_methods_of(klass)
end
register_call(signature) click to toggle source
# File lib/bringhurst/type_observer.rb, line 20
def register_call(signature)
  @method_calls << signature
end

Private Instance Methods

aliased_method_name_for(method_name) click to toggle source
# File lib/bringhurst/type_observer.rb, line 98
def aliased_method_name_for(method_name)
  "#{ method_name }_#{ SecureRandom.uuid }"
end
class_methods_of(klass) click to toggle source
# File lib/bringhurst/type_observer.rb, line 94
def class_methods_of(klass)
  klass.methods(false)
end
instance_methods_of(klass) click to toggle source
# File lib/bringhurst/type_observer.rb, line 90
def instance_methods_of(klass)
  klass.instance_methods(false)
end
wrap_class_method(klass, method_name) click to toggle source
# File lib/bringhurst/type_observer.rb, line 62
def wrap_class_method(klass, method_name)
  aliased_method_name = aliased_method_name_for(method_name)

  klass.class_eval do
    singleton_class.send(
      :alias_method,
      aliased_method_name,
      method_name,
    )

    define_singleton_method(method_name) do |*args, &block|
      result = public_send(aliased_method_name, *args, &block)

      Bringhurst::TypeObserver.instance.register_call(
        Bringhurst::TypeSignature.new(
          klass: klass,
          method: method_name,
          method_kind: :class,
          arguments: args.map(&:class),
          result: result.class,
        ),
      )

      result
    end
  end
end
wrap_class_methods_of(klass) click to toggle source
# File lib/bringhurst/type_observer.rb, line 32
def wrap_class_methods_of(klass)
  class_methods_of(klass).each do |method_name|
    wrap_class_method(klass, method_name)
  end
end
wrap_instance_method(klass, method_name) click to toggle source
# File lib/bringhurst/type_observer.rb, line 38
def wrap_instance_method(klass, method_name)
  aliased_method_name = aliased_method_name_for(method_name)

  klass.class_eval do
    alias_method(aliased_method_name, method_name)

    define_method(method_name) do |*args, &block|
      result = public_send(aliased_method_name, *args, &block)

      Bringhurst::TypeObserver.instance.register_call(
        Bringhurst::TypeSignature.new(
          klass: klass,
          method: method_name,
          method_kind: :instance,
          arguments: args.map(&:class),
          result: result.class,
        ),
      )

      result
    end
  end
end
wrap_instance_methods_of(klass) click to toggle source
# File lib/bringhurst/type_observer.rb, line 26
def wrap_instance_methods_of(klass)
  instance_methods_of(klass).each do |method_name|
    wrap_instance_method(klass, method_name)
  end
end