class Opal::Autoloader

Constants

VERSION

Public Class Methods

add_load_path(path) click to toggle source
# File lib/opal/autoloader.rb, line 11
def add_load_path(path)
  @load_paths << path
end
const_missing(const_name, mod) click to toggle source
# File lib/opal/autoloader.rb, line 22
def const_missing(const_name, mod)
  # name.nil? is testing for anonymous
  from_mod = mod.name.nil? ? guess_for_anonymous(const_name) : mod
  load_missing_constant(from_mod, const_name)
end
guess_for_anonymous(const_name) click to toggle source
# File lib/opal/autoloader.rb, line 28
def guess_for_anonymous(const_name)
  if Object.const_defined?(const_name)
    raise NameError.new "#{const_name} cannot be autoloaded from an anonymous class or module", const_name
  else
    Object
  end
end
history() click to toggle source

All modules ever loaded.

# File lib/opal/autoloader.rb, line 7
def history
  @history
end
init() click to toggle source
# File lib/opal/autoloader.rb, line 15
def init
  @history = []
  @load_paths = Set.new
  @loaded = Set.new
  @loading = []
end
load_missing_constant(from_mod, const_name) click to toggle source
# File lib/opal/autoloader.rb, line 36
def load_missing_constant(from_mod, const_name)
  # see active_support/dependencies.rb in case of reloading on how to handle
  qualified_name = qualified_name_for(from_mod, const_name)
  qualified_path = qualified_name.underscore

  module_path = search_for_module(qualified_path)
  if module_path
    if @loading.include?(module_path)
      raise "Circular dependency detected while autoloading constant #{qualified_name}"
    else
      require_or_load(from_mod, module_path)
      raise LoadError, "Unable to autoload constant #{qualified_name}, expected #{module_path} to define it" unless from_mod.const_defined?(const_name, false)
      return from_mod.const_get(const_name)
    end
  elsif (parent = from_mod.parent) && parent != from_mod &&
        ! from_mod.parents.any? { |p| p.const_defined?(const_name, false) }
    begin
      return parent.const_missing(const_name)
    rescue NameError => e
      raise unless missing_name?(e, qualified_name_for(parent, const_name))
    end
  end
end
missing_name?(e, name) click to toggle source
# File lib/opal/autoloader.rb, line 60
def missing_name?(e, name)
  mn = if /undefined/ !~ e.message
         $1 if /((::)?([A-Z]\w*)(::[A-Z]\w*)*)$/ =~ e.message
       end
  mn == name
end
qualified_name_for(mod, name) click to toggle source

Returns the constant path for the provided parent and constant name.

# File lib/opal/autoloader.rb, line 68
def qualified_name_for(mod, name)
  mod_name = to_constant_name(mod)
  mod_name == 'Object' ? name.to_s : "#{mod_name}::#{name}"
end
require_or_load(from_mod, module_path) click to toggle source
# File lib/opal/autoloader.rb, line 73
def require_or_load(from_mod, module_path)
  return if @loaded.include?(module_path)
  @loaded << module_path
  @loading << module_path

  begin
    result = require module_path
  rescue Exception
    @loaded.delete module_path
    raise LoadError, "Unable to autoload: require_or_load #{module_path} failed"
  ensure
    @loading.pop
  end

  # Record history *after* loading so first load gets warnings.
  @history << module_path
  result
  # end
end
search_for_module(path) click to toggle source
# File lib/opal/autoloader.rb, line 93
def search_for_module(path)
  # oh my! imagine Bart Simpson, writing on the board:
  # "javascript is not ruby, javascript is not ruby, javascript is not ruby, ..."
  # then running home, starting irb, on the fly developing a chat client and opening a session with Homer at his workplace: "Hi Dad ..."
  @load_paths.each do |load_path|
    mod_path = load_path + '/' + path
    return mod_path if `Opal.modules.hasOwnProperty(#{mod_path})`
  end
  return path if `Opal.modules.hasOwnProperty(#{path})`
  nil # Gee, I sure wish we had first_match ;-)
end