class LoadTracer
Constants
- FileSpec
- LOAD_METHODS
- VERSION
Public Class Methods
new(format: nil, exclude_files: [])
click to toggle source
# File lib/load_tracer.rb, line 52 def initialize(format: nil, exclude_files: []) @exclude_files = exclude_files end
trace(format: nil, exclude_files: [], &block)
click to toggle source
# File lib/load_tracer.rb, line 48 def self.trace(format: nil, exclude_files: [], &block) new(exclude_files: exclude_files).trace(format: format, &block) end
Public Instance Methods
report(format:, dependencies:, reverse_dependencies:)
click to toggle source
# File lib/load_tracer.rb, line 107 def report(format:, dependencies:, reverse_dependencies:) case format when :dot DotFormatter.export( dependencies: dependencies ) when :json JsonFormatter.export( dependencies: dependencies, reverse_dependencies: reverse_dependencies ) else DefaultFormatter.export( dependencies: dependencies, reverse_dependencies: reverse_dependencies ) end end
trace(format: nil) { || ... }
click to toggle source
# File lib/load_tracer.rb, line 56 def trace(format: nil) @dependencies = Hash.new { |hash, key| hash[key] = [] } @reverse_dependencies = Hash.new { |hash, key| hash[key] = [] } @load_checked_features = Hash.new @not_found_features = [] bl = caller_locations[1] @exclude_files << bl.absolute_path tracer.enable { yield } report(format: format, dependencies: @dependencies, reverse_dependencies: @reverse_dependencies) end
tracer()
click to toggle source
# File lib/load_tracer.rb, line 69 def tracer TracePoint.new(:return) do |tp| next unless LOAD_METHODS.include?(tp.method_id) next if tp.defined_class != ::Kernel next if tp.path != __FILE__ bl = caller_locations[1] feature = get_feature(tp) if bl.absolute_path.nil? bl = find_caller_of_internal_library(feature) end next if @exclude_files.include?(bl.absolute_path) path = find_path(feature) || find_path(File.expand_path(feature, File.dirname(bl.absolute_path))) if path.nil? @not_found_features << feature next end @load_checked_features[bl.absolute_path] = true @dependencies[bl.absolute_path] << path @reverse_dependencies[path] << bl.absolute_path if !tp.return_value && !@load_checked_features[path] file_specs = StaticChecker.parse_file(path) file_specs.each do |fs| @dependencies[fs.path] |= fs.dependencies @reverse_dependencies[fs.path] |= fs.reverse_dependencies end end end end
Private Instance Methods
find_caller_of_internal_library(feature)
click to toggle source
# File lib/load_tracer.rb, line 145 def find_caller_of_internal_library(feature) index = caller_locations.find_index { |bl| bl.base_label == feature && bl.path == '<internal:prelude>' } caller_locations[index + 1] end
find_path(feature)
click to toggle source
# File lib/load_tracer.rb, line 139 def find_path(feature) RubyVM.resolve_feature_path(feature).last rescue LoadError nil end
get_feature(tp)
click to toggle source
# File lib/load_tracer.rb, line 128 def get_feature(tp) params = tp.self.method(tp.method_id).parameters case tp.method_id when :require, :require_relative, :load tp.binding.local_variable_get(params.first.last) when :autoload tp.binding.local_variable_get(params.last.last) end end