lib/finitio/support/proxy_resolver.rb
module Finitio
# Part of the compilation schema, this proxy resolver replaces
# proxies by their real Type instance.
#
# Given that Finitio can support recursive types, we do this in
# two passes:
# 1. Replace proxy types by rewrite (see Type#resolve_proxies)
# in a depth first search.
# 2. If a loop is found, recreate a late ProxyType, that is then
# bound later by mutation.
#
# So ProxyType may still be present in the type chain, but will
# only correspond to recursive types.
class ProxyResolver
def resolve!(system)
@system = system
@built = {}
@building = {}
@late_proxies = []
system.types.each_key do |name|
fetch(name)
end
@late_proxies.each do |proxy|
proxy.bind!(self)
end
system.dup(@built)
end
def fetch(name, &bl)
@built[name] || build_it(name) || import_it(name, &bl)
end
def build_it(name)
if under_build = @building[name]
proxy = ProxyType.new(name)
@late_proxies << proxy
proxy
else
return nil unless type = @system.fetch(name, false){ nil }
@building[name] = type
@built[name] = type.resolve_proxies(self)
@building[name] = nil
@built[name]
end
end
def import_it(name, &bl)
@system.fetch_on_imports(name, &bl)
end
end # class ProxyResolver
end # module Finitio