def show
Fiber[:show_rec] ||= Set[]
if Fiber[:show_rec].include?(self)
"untyped"
else
begin
Fiber[:show_rec] << self
types = []
bot = @types.keys.any? {|ty| ty.is_a?(Type::Bot) }
optional = true_exist = false_exist = false
each_type do |ty|
if ty.is_a?(Type::Instance)
case ty.mod.cpath
when [:NilClass] then optional = true
when [:TrueClass] then true_exist = true
when [:FalseClass] then false_exist = true
end
end
end
bool = true_exist && false_exist
types << "bool" if bool
each_type do |ty, _source|
if ty.is_a?(Type::Instance)
next if ty.mod.cpath == [:NilClass]
next if bool && (ty.mod.cpath == [:TrueClass] || ty.mod.cpath == [:FalseClass])
end
next if ty.is_a?(Type::Bot)
types << ty.show
end
types = types.uniq.sort
case types.size
when 0
optional ? "nil" : bot ? "bot" : "untyped"
when 1
types.first + (optional ? "?" : "")
else
"(#{ types.join(" | ") })" + (optional ? "?" : "")
end
ensure
Fiber[:show_rec].delete(self) || raise
end
end
end