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: ConstantsHeap, ModuleCache

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.applied?Boolean

Returns:

  • (Boolean)


69
70
71
# File 'lib/rails_development_boost/dependencies_patch.rb', line 69

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
39
40
41
42
43
44
45
46
47
# 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
    unless method_defined?(:local_const_defined?) # pre 4da45060 compatibility
      if method_defined?(:uninherited_const_defined?)
        alias_method :local_const_defined?, :uninherited_const_defined?
      else # post 4.0 compat
        def local_const_defined?(mod, const_name)
          mod.const_defined?(const_name, false)
        end
      end
    end
    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
    @routes_path_loading = nil
  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=(new_value) ⇒ Object



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

def self.async=(new_value)
  @async = Async.process_new_async_value(new_value)
end

.async?Boolean

Returns:

  • (Boolean)


61
62
63
# File 'lib/rails_development_boost/dependencies_patch.rb', line 61

def self.async?
  @async
end

.debug!Object



49
50
51
52
53
54
55
# File 'lib/rails_development_boost/dependencies_patch.rb', line 49

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

.enable_async_mode_by_default!Object



65
66
67
# File 'lib/rails_development_boost/dependencies_patch.rb', line 65

def self.enable_async_mode_by_default!
  Async.enable_by_default!(defined?(@async))
end

Instance Method Details

#add_explicit_dependency(parent, child) ⇒ Object



303
304
305
306
307
# File 'lib/rails_development_boost/dependencies_patch.rb', line 303

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



255
256
257
258
259
260
261
# File 'lib/rails_development_boost/dependencies_patch.rb', line 255

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.



224
225
# File 'lib/rails_development_boost/dependencies_patch.rb', line 224

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



309
310
311
312
313
314
315
# File 'lib/rails_development_boost/dependencies_patch.rb', line 309

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)


317
318
319
320
321
322
# File 'lib/rails_development_boost/dependencies_patch.rb', line 317

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



324
325
326
327
328
329
330
331
# File 'lib/rails_development_boost/dependencies_patch.rb', line 324

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’.



228
229
230
231
232
233
234
235
236
# File 'lib/rails_development_boost/dependencies_patch.rb', line 228

def load_file_with_constant_tracking(path, *args)
  async_synchronize do
    if @module_cache
      @module_cache = nil
      constants_to_remove.clear_seen
    end
    load_file_with_constant_tracking_internal(path, args)
  end
end

#loading_routes_file(path) ⇒ Object



247
248
249
250
251
252
253
# File 'lib/rails_development_boost/dependencies_patch.rb', line 247

def loading_routes_file(path)
  prev_value = @routes_path_loading
  @routes_path_loading = Util.load_path_to_real_path(path)
  yield
ensure
  @routes_path_loading = prev_value
end

#now_loading(path) ⇒ Object



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

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

#process_consts_scheduled_for_removalObject



273
274
275
276
277
278
279
280
281
282
# File 'lib/rails_development_boost/dependencies_patch.rb', line 273

def process_consts_scheduled_for_removal
  unless @now_removing_const
    @now_removing_const = true
    begin
      process_consts_scheduled_for_removal_internal
    ensure
      @now_removing_const = nil
    end
  end
end

#remove_constant_with_handling_of_connections(const_name) ⇒ Object

Augmented ‘remove_constant’.



285
286
287
288
289
290
# File 'lib/rails_development_boost/dependencies_patch.rb', line 285

def remove_constant_with_handling_of_connections(const_name)
  async_synchronize do
    schedule_const_for_unloading(const_name)
    process_consts_scheduled_for_removal
  end
end

#remove_explicitely_unloadable_constants!Object



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

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

#required_dependency(file_name) ⇒ Object



292
293
294
295
296
297
298
299
300
301
# File 'lib/rails_development_boost/dependencies_patch.rb', line 292

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

#schedule_const_for_unloading(const_name) ⇒ Object



263
264
265
266
267
268
269
270
271
# File 'lib/rails_development_boost/dependencies_patch.rb', line 263

def schedule_const_for_unloading(const_name)
  if constants_to_remove.add_const?(const_name)
    if qualified_const_defined?(const_name) && object = const_name.constantize
      @module_cache ||= ModuleCache.new # make sure module_cache has been created
      schedule_dependent_constants_for_removal(const_name, object)
    end
    true
  end
end

#unload_modified_files!Object



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

def unload_modified_files!
  async_synchronize do
    unloaded_something = unload_modified_files_internal!
    load_failure       = clear_load_failure
    unloaded_something || load_failure
  end
end