Module: RailsDevelopmentBoost::DependenciesPatch

Defined in:
lib/rails_development_boost/dependencies_patch.rb,
lib/rails_development_boost/dependencies_patch/instrumentation_patch.rb

Defined Under Namespace

Modules: InstrumentationPatch, LoadablePatch, Util Classes: ModuleCache

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.applied?Boolean

Returns:

  • (Boolean)


56
57
58
# File 'lib/rails_development_boost/dependencies_patch.rb', line 56

def self.applied?
  ActiveSupport::Dependencies < self
end

.apply!Object



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/rails_development_boost/dependencies_patch.rb', line 13

def self.apply!
  return if applied?
  
  # retain the original method in case the application overwrites it on its modules/klasses
  Module.send :alias_method, :_mod_name, :name
  
  patch = self
  ActiveSupport::Dependencies.module_eval do
    alias_method :local_const_defined?, :uninherited_const_defined? unless method_defined?(:local_const_defined?) # pre 4da45060 compatibility
    remove_possible_method :remove_unloadable_constants!
    remove_possible_method :clear
    include patch
    alias_method_chain :load_file, 'constant_tracking'
    alias_method_chain :remove_constant, 'handling_of_connections'
    extend patch
  end
  
  ActiveSupport::Dependencies::Loadable.module_eval do
    include LoadablePatch
    alias_method_chain :require_dependency, 'constant_tracking'
  end

  InstrumentationPatch.apply! if @do_instrument
  
  ActiveSupport::Dependencies.handle_already_autoloaded_constants!
end

.async!Object



48
49
50
# File 'lib/rails_development_boost/dependencies_patch.rb', line 48

def self.async!
  @async = true
end

.async?Boolean

Returns:

  • (Boolean)


52
53
54
# File 'lib/rails_development_boost/dependencies_patch.rb', line 52

def self.async?
  @async
end

.debug!Object



40
41
42
43
44
45
46
# File 'lib/rails_development_boost/dependencies_patch.rb', line 40

def self.debug!
  if applied?
    InstrumentationPatch.apply!
  else
    @do_instrument = true
  end
end

Instance Method Details

#add_explicit_dependency(parent, child) ⇒ Object



219
220
221
222
223
# File 'lib/rails_development_boost/dependencies_patch.rb', line 219

def add_explicit_dependency(parent, child)
  if !Util.anonymous_const_name?(child_mod_name = child._mod_name) && !Util.anonymous_const_name?(parent_mod_name = parent._mod_name)
    ((explicit_dependencies[parent_mod_name] ||= []) << child_mod_name).uniq!
  end
end

#associate_constants_to_file(constants, file_path) ⇒ Object



190
191
192
193
194
195
196
# File 'lib/rails_development_boost/dependencies_patch.rb', line 190

def associate_constants_to_file(constants, file_path)
  # freezing strings before using them as Hash keys is slightly more memory efficient
  constants.map!(&:freeze)
  file_path.freeze
  
  LoadedFile.for(file_path).add_constants(constants)
end

#clearObject

Overridden.



170
171
# File 'lib/rails_development_boost/dependencies_patch.rb', line 170

def clear
end

#handle_already_autoloaded_constants!Object

we might be late to the party and other gems/plugins might have already triggered autoloading of some constants



225
226
227
228
229
230
231
# File 'lib/rails_development_boost/dependencies_patch.rb', line 225

def handle_already_autoloaded_constants! # we might be late to the party and other gems/plugins might have already triggered autoloading of some constants
  loaded.each do |require_path|
    unless load_once_path?(require_path)
      associate_constants_to_file(autoloaded_constants, "#{require_path}.rb") # slightly heavy-handed..
    end
  end
end

#in_autoload_path?(expanded_file_path) ⇒ Boolean

Returns:

  • (Boolean)


233
234
235
236
237
238
# File 'lib/rails_development_boost/dependencies_patch.rb', line 233

def in_autoload_path?(expanded_file_path)
  autoload_paths.any? do |autoload_path|
    autoload_path = autoload_path.to_s # handle Pathnames
    expanded_file_path.starts_with?(autoload_path.ends_with?('/') ? autoload_path : "#{autoload_path}/")
  end
end

#load_file_from_explicit_load(expanded_path) ⇒ Object



240
241
242
243
244
245
246
247
# File 'lib/rails_development_boost/dependencies_patch.rb', line 240

def load_file_from_explicit_load(expanded_path)
  unless LoadedFile.loaded?(expanded_path)
    load_file(expanded_path)
    if LoadedFile.loaded?(expanded_path) && (file = LoadedFile.for(expanded_path)).decorator_like?
      file.associate_to_greppable_constants
    end
  end
end

#load_file_with_constant_tracking(path, *args) ⇒ Object

Augmented ‘load_file’.



174
175
176
177
178
179
# File 'lib/rails_development_boost/dependencies_patch.rb', line 174

def load_file_with_constant_tracking(path, *args)
  async_synchronize do
    @module_cache = nil # nuking the module_cache helps to avoid any stale-class issues when the async mode is used in a console session
    load_file_with_constant_tracking_internal(path, args)
  end
end

#now_loading(path) ⇒ Object



181
182
183
184
185
186
187
188
# File 'lib/rails_development_boost/dependencies_patch.rb', line 181

def now_loading(path)
  currently_loading << path
  yield
rescue Exception => e
  error_loading_file(currently_loading.last, e)
ensure
  currently_loading.pop
end

#remove_constant_with_handling_of_connections(const_name) ⇒ Object

Augmented ‘remove_constant’.



199
200
201
202
203
204
205
206
# File 'lib/rails_development_boost/dependencies_patch.rb', line 199

def remove_constant_with_handling_of_connections(const_name)
  async_synchronize do
    module_cache # make sure module_cache has been created
    prevent_further_removal_of(const_name) do
      unprotected_remove_constant(const_name)
    end
  end
end

#remove_explicitely_unloadable_constants!Object



165
166
167
# File 'lib/rails_development_boost/dependencies_patch.rb', line 165

def remove_explicitely_unloadable_constants!
  explicitly_unloadable_constants.each { |const| remove_constant(const) }
end

#required_dependency(file_name) ⇒ Object



208
209
210
211
212
213
214
215
216
217
# File 'lib/rails_development_boost/dependencies_patch.rb', line 208

def required_dependency(file_name)
  # Rails uses require_dependency for loading helpers, we are however dealing with the helper problem elsewhere, so we can skip them
  return if (curr_loading = currently_loading.last) && curr_loading =~ /_controller(?:\.rb)?\Z/ && file_name =~ /_helper(?:\.rb)?\Z/
  
  if full_path = ActiveSupport::Dependencies.search_for_file(file_name)
    RequiredDependency.new(curr_loading).related_files.each do |related_file|
      LoadedFile.relate_files(related_file, full_path)
    end
  end
end

#unload_modified_files!Object



157
158
159
160
161
162
163
# File 'lib/rails_development_boost/dependencies_patch.rb', line 157

def unload_modified_files!
  unloaded_something = unload_modified_files_internal!
  load_failure       = clear_load_failure
  unloaded_something || load_failure
ensure
  async_synchronize { @module_cache = nil }
end