module Zeitwerk::Loader::EagerLoad

def actual_eager_load_dir(dir, namespace, force: false)

@sig (String, Module, Boolean) -> void

corresponds to `dir`.
The caller is responsible for making sure `namespace` is the namespace that
def actual_eager_load_dir(dir, namespace, force: false)
_exclusions = !force
 if honour_exclusions && excluded_from_eager_load?(dir)
ager load directory #{dir} start") if logger
= [[dir, namespace]]
to_eager_load = queue.shift
 namespace = to_eager_load
ir) do |basename, abspath|
xt if honour_exclusions && eager_load_exclusions.member?(abspath)
 ruby?(abspath)
if (cref = autoloads[abspath])
  cget(*cref)
end
se
if collapse?(abspath)
  queue << [abspath, namespace]
else
  cname = inflector.camelize(basename, abspath).to_sym
  queue << [abspath, cget(namespace, cname)]
end
d
ager load directory #{dir} end") if logger

def eager_load(force: false)

@sig (true | false) -> void

overridden passing `force: true`.
specific files and directories with `do_not_eager_load`, and that can be
shadowed files are not eager loaded. You can opt-out specifically in
need to be in `$LOAD_PATH`, absolute file names are used. Ignored and
Eager loads all files in the root directories, recursively. Files do not
def eager_load(force: false)
  mutex.synchronize do
    break if @eager_loaded
    raise Zeitwerk::SetupRequired unless @setup
    log("eager load start") if logger
    actual_roots.each do |root_dir, root_namespace|
      actual_eager_load_dir(root_dir, root_namespace, force: force)
    end
    autoloaded_dirs.each do |autoloaded_dir|
      Zeitwerk::Registry.unregister_autoload(autoloaded_dir)
    end
    autoloaded_dirs.clear
    @eager_loaded = true
    log("eager load end") if logger
  end
end

def eager_load_child_namespace(child, child_name, root_dir, root_namespace)

@sig (Module, String, Module, Boolean) -> void

strict namespace descendant of `root_namespace`.
In order to invoke this method, the caller has to ensure `child` is a
def eager_load_child_namespace(child, child_name, root_dir, root_namespace)
 = child_name
 root_namespace.equal?(Object)
ix = suffix.delete_prefix(real_mod_name(root_namespace) + "::")
e directories are at the same namespace level, there may be more if
ind collapsed ones. As we scan, we look for matches for the first
ent, and store them in `next_dirs`. If there are any, we look for
next segments in those matches. Repeat.
e exhaust the search locating directories that match all segments,
ust need to eager load those ones.
 [root_dir]
irs = []
.split("::").each do |segment|
e dir = dirs.shift
(dir) do |basename, abspath|
next unless dir?(abspath)
if collapse?(abspath)
  dirs << abspath
elsif segment == inflector.camelize(basename, abspath)
  next_dirs << abspath
end
d
rn if next_dirs.empty?
.replace(next_dirs)
_dirs.clear
ach do |dir|
al_eager_load_dir(dir, child)

def eager_load_dir(path)

@sig (String | Pathname) -> void
def eager_load_dir(path)
  raise Zeitwerk::SetupRequired unless @setup
  abspath = File.expand_path(path)
  raise Zeitwerk::Error.new("#{abspath} is not a directory") unless dir?(abspath)
  cnames = []
  root_namespace = nil
  walk_up(abspath) do |dir|
    return if ignored_path?(dir)
    return if eager_load_exclusions.member?(dir)
    break if root_namespace = roots[dir]
    basename = File.basename(dir)
    return if hidden?(basename)
    unless collapse?(dir)
      cnames << inflector.camelize(basename, dir).to_sym
    end
  end
  raise Zeitwerk::Error.new("I do not manage #{abspath}") unless root_namespace
  return if @eager_loaded
  namespace = root_namespace
  cnames.reverse_each do |cname|
    # Can happen if there are no Ruby files. This is not an error condition,
    # the directory is actually managed. Could have Ruby files later.
    return unless cdef?(namespace, cname)
    namespace = cget(namespace, cname)
  end
  # A shortcircuiting test depends on the invocation of this method. Please
  # keep them in sync if refactored.
  actual_eager_load_dir(abspath, namespace)
end

def eager_load_namespace(mod)

@sig (Module) -> void
def eager_load_namespace(mod)
  raise Zeitwerk::SetupRequired unless @setup
  unless mod.is_a?(Module)
    raise Zeitwerk::Error, "#{mod.inspect} is not a class or module object"
  end
  return if @eager_loaded
  mod_name = real_mod_name(mod)
  return unless mod_name
  actual_roots.each do |root_dir, root_namespace|
    if mod.equal?(Object)
      # A shortcircuiting test depends on the invocation of this method.
      # Please keep them in sync if refactored.
      actual_eager_load_dir(root_dir, root_namespace)
    elsif root_namespace.equal?(Object)
      eager_load_child_namespace(mod, mod_name, root_dir, root_namespace)
    else
      root_namespace_name = real_mod_name(root_namespace)
      if root_namespace_name.start_with?(mod_name + "::")
        actual_eager_load_dir(root_dir, root_namespace)
      elsif mod_name == root_namespace_name
        actual_eager_load_dir(root_dir, root_namespace)
      elsif mod_name.start_with?(root_namespace_name + "::")
        eager_load_child_namespace(mod, mod_name, root_dir, root_namespace)
      else
        # Unrelated constant hierarchies, do nothing.
      end
    end
  end
end

def load_file(path)

@sig (String | Pathname) -> void

to descend orderly and make sure the file is loadable.
The method is implemented as `constantize` for files, in a sense, to be able

Raises if the argument is ignored, shadowed, or not managed by the receiver.

Loads the given Ruby file.
def load_file(path)
  abspath = File.expand_path(path)
  raise Zeitwerk::Error.new("#{abspath} does not exist") unless File.exist?(abspath)
  raise Zeitwerk::Error.new("#{abspath} is not a Ruby file") if dir?(abspath) || !ruby?(abspath)
  raise Zeitwerk::Error.new("#{abspath} is ignored") if ignored_path?(abspath)
  basename = File.basename(abspath, ".rb")
  raise Zeitwerk::Error.new("#{abspath} is ignored") if hidden?(basename)
  base_cname = inflector.camelize(basename, abspath).to_sym
  root_namespace = nil
  cnames = []
  walk_up(File.dirname(abspath)) do |dir|
    raise Zeitwerk::Error.new("#{abspath} is ignored") if ignored_path?(dir)
    break if root_namespace = roots[dir]
    basename = File.basename(dir)
    raise Zeitwerk::Error.new("#{abspath} is ignored") if hidden?(basename)
    unless collapse?(dir)
      cnames << inflector.camelize(basename, dir).to_sym
    end
  end
  raise Zeitwerk::Error.new("I do not manage #{abspath}") unless root_namespace
  namespace = root_namespace
  cnames.reverse_each do |cname|
    namespace = cget(namespace, cname)
  end
  raise Zeitwerk::Error.new("#{abspath} is shadowed") if shadowed_file?(abspath)
  cget(namespace, base_cname)
end