Class: DeepCover::AutoloadTracker
- Inherits:
-
Object
- Object
- DeepCover::AutoloadTracker
- Defined in:
- lib/deep_cover/autoload_tracker.rb
Defined Under Namespace
Classes: AutoloadEntry
Class Attribute Summary collapse
-
.warned_for_frozen_module ⇒ Object
Returns the value of attribute warned_for_frozen_module.
Instance Attribute Summary collapse
-
#autoloads_by_basename ⇒ Object
readonly
Returns the value of attribute autoloads_by_basename.
-
#interceptor_files_by_path ⇒ Object
readonly
Returns the value of attribute interceptor_files_by_path.
Class Method Summary collapse
-
.warn_frozen_module(mod) ⇒ Object
Using frozen modules/classes is almost unheard of, but a warning makes things easier if someone does it.
Instance Method Summary collapse
- #autoload_path_for(mod, name, path) ⇒ Object
-
#initialize ⇒ AutoloadTracker
constructor
A new instance of AutoloadTracker.
-
#initialize_autoloaded_paths(mods = ObjectSpace.each_object(Module)) ⇒ Object
In JRuby, ObjectSpace.each_object is allowed for Module and Class, so we are good.
- #possible_autoload_target?(requested_path) ⇒ Boolean
-
#remove_interceptors ⇒ Object
We need to remove the interceptor hooks, otherwise, the problem if manually requiring something that is autoloaded will cause issues.
-
#wrap_require(requested_path, absolute_path_found) ⇒ Object
&block.
Constructor Details
#initialize ⇒ AutoloadTracker
Returns a new instance of AutoloadTracker.
27 28 29 30 |
# File 'lib/deep_cover/autoload_tracker.rb', line 27 def initialize @autoloads_by_basename = {} @interceptor_files_by_path = {} end |
Class Attribute Details
.warned_for_frozen_module ⇒ Object
Returns the value of attribute warned_for_frozen_module.
125 126 127 |
# File 'lib/deep_cover/autoload_tracker.rb', line 125 def warned_for_frozen_module @warned_for_frozen_module end |
Instance Attribute Details
#autoloads_by_basename ⇒ Object (readonly)
Returns the value of attribute autoloads_by_basename.
26 27 28 |
# File 'lib/deep_cover/autoload_tracker.rb', line 26 def autoloads_by_basename @autoloads_by_basename end |
#interceptor_files_by_path ⇒ Object (readonly)
Returns the value of attribute interceptor_files_by_path.
26 27 28 |
# File 'lib/deep_cover/autoload_tracker.rb', line 26 def interceptor_files_by_path @interceptor_files_by_path end |
Class Method Details
.warn_frozen_module(mod) ⇒ Object
Using frozen modules/classes is almost unheard of, but a warning makes things easier if someone does it
130 131 132 133 134 135 |
# File 'lib/deep_cover/autoload_tracker.rb', line 130 def self.warn_frozen_module(mod) return if warned_for_frozen_module self.warned_for_frozen_module ||= true warn "There is an autoload on a frozen module/class: #{mod}, DeepCover cannot handle those, failure is probable. " \ "This warning won't be displayed again (even for different module/class)" end |
Instance Method Details
#autoload_path_for(mod, name, path) ⇒ Object
32 33 34 35 36 37 38 39 40 |
# File 'lib/deep_cover/autoload_tracker.rb', line 32 def autoload_path_for(mod, name, path) interceptor_path = setup_interceptor_for(mod, name, path) if DeepCover.custom_requirer.is_being_required?(path) already_loaded_feature else interceptor_path end end |
#initialize_autoloaded_paths(mods = ObjectSpace.each_object(Module)) ⇒ Object
In JRuby, ObjectSpace.each_object is allowed for Module and Class, so we are good.
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/deep_cover/autoload_tracker.rb', line 79 def initialize_autoloaded_paths(mods = ObjectSpace.each_object(Module)) # &do_autoload_block mods.each do |mod| # Module's constants are shared with Object. But if you set autoloads directly on Module, they # appear on multiple classes. So just skip, Object will take care of those. next if mod == Module # This happens with JRuby next unless mod.respond_to?(:constants) if mod.frozen? if mod.constants.any? { |name| mod.autoload?(name) } self.class.warn_frozen_module(mod) end next end mod.constants.each do |name| # JRuby can talk about deprecated constants here path = Tools.silence_warnings do mod.autoload?(name) end next unless path interceptor_path = setup_interceptor_for(mod, name, path) yield mod, name, interceptor_path end end end |
#possible_autoload_target?(requested_path) ⇒ Boolean
42 43 44 45 46 |
# File 'lib/deep_cover/autoload_tracker.rb', line 42 def possible_autoload_target?(requested_path) basename = basename_without_extension(requested_path) autoloads = @autoloads_by_basename[basename] autoloads && !autoloads.empty? end |
#remove_interceptors ⇒ Object
We need to remove the interceptor hooks, otherwise, the problem if manually requiring something that is autoloaded will cause issues.
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 |
# File 'lib/deep_cover/autoload_tracker.rb', line 108 def remove_interceptors # &do_autoload_block @autoloads_by_basename.each do |basename, entries| entries.each do |entry| mod = entry.mod_if_available next unless mod # Module's constants are shared with Object. But if you set autoloads directly on Module, they # appear on multiple classes. So just skip, Object will take care of those. next if mod == Module yield mod, entry.name, entry.target_path end end @autoloaded_paths = {} @interceptor_files_by_path = {} end |
#wrap_require(requested_path, absolute_path_found) ⇒ Object
&block
51 52 53 |
# File 'lib/deep_cover/autoload_tracker.rb', line 51 def wrap_require(requested_path, absolute_path_found) # &block yield end |