Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
Josh Bodah committed Sep 21, 2018
1 parent bcf265a commit ce76ae2
Showing 1 changed file with 59 additions and 5 deletions.
64 changes: 59 additions & 5 deletions lib/spy/util.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,49 @@

module Spy
module Util
# TODO: @jbodah 2018-09-21: superclass merge
class YARDFormatter
def format(info)
acc = []
info[:args].each do |arg_values|
names = types_to_names(arg_values)
type_names = condense_names(names)
acc << "# @param [#{type_names.join(", ")}]"
end
names = types_to_names(info[:return_value])
type_names = condense_names(names)
acc << "# @return [#{type_names.join(", ")}]"
acc.join("\n")
end

def types_to_names(types)
types.map do |arg_value|
if arg_value.is_a?(Array)
head = arg_value[0]
tail = types_to_names(arg_value[1])
"#{head.name}<#{tail.join(", ")}>"
else
arg_value.name
end
end
end

def condense_names(names)
if names.include?("TrueClass") && names.include?("FalseClass")
names.delete("TrueClass")
names.delete("FalseClass")
names << "Boolean"
end
# todo also prune depth
%w(Set Array Hash).each do |container|
if names.include?(container) && names.any? { |n| /#{container}</ =~ n }
names.delete(container)
end
end
names
end
end

class TypeAnalysis
attr_reader :type_info

Expand All @@ -16,12 +59,16 @@ def decorate
self
end

def respond_to_missing?(sym, incl_private = false)
@spy.respond_to_missing?(sym, incl_private)
def respond_to?(sym, incl_private = false)
@spy.respond_to?(sym, incl_private)
end

def method_missing(sym, *args, &block)
@spy.send(sym, *args, &block)
if @spy.respond_to?(sym)
@spy.send(sym, *args, &block)
else
super
end
end

private
Expand Down Expand Up @@ -53,9 +100,16 @@ def record_rv(method_call)
@type_info[method_call.name][:return_value] << type_of(method_call.result)
end

def type_of(obj)
def type_of(obj, depth: 0)
# NOTE: @jbodah 2018-09-21: disabling depth for now
return obj.class if depth > 0

if obj.is_a?(Array) && obj.size > 0
[Array, obj[0].class]
[Array, [type_of(obj.first, depth: 1)]]
elsif obj.is_a?(Hash) && obj.size > 0
[Hash, [type_of(obj.first[0]), type_of(obj.first[1])]]
elsif defined?(Set) && obj.is_a?(Set) && obj.size > 0
[Set, [type_of(obj.first)]]
else
obj.class
end
Expand Down

0 comments on commit ce76ae2

Please sign in to comment.