86 lines
2.4 KiB
Ruby
86 lines
2.4 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module Zeitwerk
|
|
module Registry # :nodoc: all
|
|
require_relative "registry/explicit_namespaces"
|
|
require_relative "registry/inceptions"
|
|
|
|
class << self
|
|
# Keeps track of all loaders. Useful to broadcast messages and to prevent
|
|
# them from being garbage collected.
|
|
#
|
|
# @private
|
|
# @sig Array[Zeitwerk::Loader]
|
|
attr_reader :loaders
|
|
|
|
# Registers gem loaders to let `for_gem` be idempotent in case of reload.
|
|
#
|
|
# @private
|
|
# @sig Hash[String, Zeitwerk::Loader]
|
|
attr_reader :gem_loaders_by_root_file
|
|
|
|
# Maps absolute paths to the loaders responsible for them.
|
|
#
|
|
# This information is used by our decorated `Kernel#require` to be able to
|
|
# invoke callbacks and autovivify modules.
|
|
#
|
|
# @private
|
|
# @sig Hash[String, Zeitwerk::Loader]
|
|
attr_reader :autoloads
|
|
|
|
# Registers a loader.
|
|
#
|
|
# @private
|
|
# @sig (Zeitwerk::Loader) -> void
|
|
def register_loader(loader)
|
|
loaders << loader
|
|
end
|
|
|
|
# @private
|
|
# @sig (Zeitwerk::Loader) -> void
|
|
def unregister_loader(loader)
|
|
loaders.delete(loader)
|
|
gem_loaders_by_root_file.delete_if { |_, l| l == loader }
|
|
autoloads.delete_if { |_, l| l == loader }
|
|
end
|
|
|
|
# This method returns always a loader, the same instance for the same root
|
|
# file. That is how Zeitwerk::Loader.for_gem is idempotent.
|
|
#
|
|
# @private
|
|
# @sig (String) -> Zeitwerk::Loader
|
|
def loader_for_gem(root_file, namespace:, warn_on_extra_files:)
|
|
gem_loaders_by_root_file[root_file] ||= GemLoader.__new(root_file, namespace: namespace, warn_on_extra_files: warn_on_extra_files)
|
|
end
|
|
|
|
# @private
|
|
# @sig (Zeitwerk::Loader, String) -> String
|
|
def register_autoload(loader, abspath)
|
|
autoloads[abspath] = loader
|
|
end
|
|
|
|
# @private
|
|
# @sig (String) -> void
|
|
def unregister_autoload(abspath)
|
|
autoloads.delete(abspath)
|
|
end
|
|
|
|
# @private
|
|
# @sig (String) -> Zeitwerk::Loader?
|
|
def loader_for(path)
|
|
autoloads[path]
|
|
end
|
|
|
|
# @private
|
|
# @sig (Zeitwerk::Loader) -> void
|
|
def on_unload(loader)
|
|
autoloads.delete_if { |_path, object| object == loader }
|
|
end
|
|
end
|
|
|
|
@loaders = []
|
|
@gem_loaders_by_root_file = {}
|
|
@autoloads = {}
|
|
end
|
|
end
|