class Argtrace::OutputModule
helper to convert TypeLib
into RBS. OutputMoudle acts like Module tree node.
Attributes
actual_module[RW]
children[RW]
name[RW]
signatures[RW]
Public Class Methods
new()
click to toggle source
# File lib/argtrace/typelib.rb, line 157 def initialize @children = {} @signatures = [] end
Public Instance Methods
add_signature(signature)
click to toggle source
# File lib/argtrace/typelib.rb, line 162 def add_signature(signature) # this is root node, so use Kernel as const resolve source. @actual_module = Kernel constname = class_const_name(signature.defined_class) add_signature_inner(constname, signature) end
add_signature_inner(name_consts, signature)
click to toggle source
# File lib/argtrace/typelib.rb, line 176 def add_signature_inner(name_consts, signature) if name_consts.empty? @signatures << signature else unless @children.key?(name_consts.first) mod = OutputModule.new mod.name = name_consts.first mod.actual_module = @actual_module.const_get(name_consts.first) @children[name_consts.first] = mod end current_resolving_name = name_consts.shift @children[current_resolving_name].add_signature_inner(name_consts, signature) end end
blocktype_to_rbs(blockparam)
click to toggle source
# File lib/argtrace/typelib.rb, line 231 def blocktype_to_rbs(blockparam) unless blockparam return "" end params = blockparam.type.params .map{|p| type_union_to_rbs(p.type)} .join(", ") return " { (#{params}) -> untyped }" end
class_const_name(klass)
click to toggle source
split class name into consts (e.g. Argtrace::TypeLib
to [“Argtrace”, “TypeLib”]) bad name class is already sanitized, just split.
# File lib/argtrace/typelib.rb, line 172 def class_const_name(klass) klass.to_s.split("::") end
param_to_rbs(param)
click to toggle source
# File lib/argtrace/typelib.rb, line 241 def param_to_rbs(param) case param.mode when :req return "#{type_union_to_rbs(param.type)} #{param.name}" when :opt return "?#{type_union_to_rbs(param.type)} #{param.name}" when :keyreq return "#{param.name}: #{type_union_to_rbs(param.type)}" when :key return "?#{param.name}: #{type_union_to_rbs(param.type)}" when :block return nil end end
sig_to_rbs(indent_level, signature)
click to toggle source
# File lib/argtrace/typelib.rb, line 218 def sig_to_rbs(indent_level, signature) indent = " " * indent_level sig_name = signature.is_singleton_method ? "self.#{signature.method_id}" : signature.method_id params = signature.params .filter{|p| p.mode != :block} .map{|p| param_to_rbs(p)} .compact .join(", ") rettype = type_union_to_rbs(signature.return_type) blocktype = blocktype_to_rbs(signature.params.find{|p| p.mode == :block}) return "#{indent}def #{sig_name} : (#{params})#{blocktype} -> #{rettype}" end
to_rbs()
click to toggle source
# File lib/argtrace/typelib.rb, line 191 def to_rbs # this is root node lines = [] @children.keys.sort.each do |child_name| lines << @children[child_name].to_rbs_inner(0) lines << "" end return lines.join("\n") end
to_rbs_inner(indent_level)
click to toggle source
# File lib/argtrace/typelib.rb, line 201 def to_rbs_inner(indent_level) indent = " " * indent_level classmod_def = @actual_module.class == Class ? "class" : "module" lines = [] lines << "#{indent}#{classmod_def} #{name}" @children.keys.sort.each do |child_name| lines << @children[child_name].to_rbs_inner(indent_level + 1) lines << "" end @signatures.each do |sig| lines << sig_to_rbs(indent_level + 1, sig) end lines << "#{indent}end" return lines.join("\n") end
type_to_rbs(type)
click to toggle source
# File lib/argtrace/typelib.rb, line 280 def type_to_rbs(type) if type.data.is_a?(Symbol) return type.data.inspect elsif true == type.data || false == type.data || BooleanClass == type.data return "bool" elsif nil == type.data || NilClass == type.data return "nil" elsif Array == type.data if type.subdata case type.subdata when true, false, BooleanClass elementtype = "bool" else elementtype = type.subdata.to_s end return "Array[#{elementtype}]" else return "Array" end else return type.data.to_s end end
type_union_to_rbs(typeunion)
click to toggle source
# File lib/argtrace/typelib.rb, line 256 def type_union_to_rbs(typeunion) if typeunion.union.size == 0 return "untyped" end # TODO: ugly if typeunion.union.size == 1 and NilClass == typeunion.union.first.data # TODO: I can't distinguish nil and untyped. return "untyped" end if typeunion.union.count{|x| x.data.is_a?(Symbol)} >= 16 # too much symbols, this should not be enum. typeunion.union.delete_if{|x| x.data.is_a?(Symbol)} typeunion.add(Type.new_with_type(Symbol)) end if typeunion.union.size == 2 and typeunion.union.any?{|x| NilClass == x.data} # type is nil and sometype, so represent it as "sometype?" sometype = typeunion.union.find{|x| NilClass != x.data} return "#{type_to_rbs(sometype)}?" end ret = typeunion.union.map{|type| type_to_rbs(type)}.join("|") return ret end