Class: ClassSource::Locator

Inherits:
Object
  • Object
show all
Defined in:
lib/class_source/locator.rb

Instance Method Summary collapse

Constructor Details

#initialize(target_class, options = {}) ⇒ Locator

Returns a new instance of Locator.



6
7
8
9
# File 'lib/class_source/locator.rb', line 6

def initialize(target_class, options={})
  @klass = target_class
  @options=options
end

Instance Method Details

#dynamic_class_declared(id, classname, file, line) ⇒ Object



56
57
58
59
# File 'lib/class_source/locator.rb', line 56

def dynamic_class_declared(id, classname, file, line)
  return unless id == :new && classname == Class 
  File.read(file).lines.to_a[line-1][/[A-Z][\w_:]*/, 0]
end

#files(options = {}) ⇒ Object



19
20
21
22
23
# File 'lib/class_source/locator.rb', line 19

def files(options={})
  @source_files ||= methods.locations.map(&:first).uniq
  return @source_files + [@options[:file]] if @options[:file]
  @source_files
end

#methodsObject



15
16
17
# File 'lib/class_source/locator.rb', line 15

def methods
  MethodIndex.new(@klass)
end

#silence_warningsObject



67
68
69
70
71
72
# File 'lib/class_source/locator.rb', line 67

def silence_warnings
  old_verbose, $VERBOSE = $VERBOSE, nil
  yield
ensure
  $VERBOSE = old_verbose
end

#source_locations(options = {}) ⇒ Object



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/class_source/locator.rb', line 25

def source_locations(options={})
  return @locations if @locations
  t = Tempfile.new('class_creation_events')
  fork do
    declarations = files(options).inject({}) do |declarations, source_file|
      trace_declarations(source_file, declarations)
    end
    YAML.dump(declarations, t)
  end
  Process.wait
  Declarations.save YAML.load_file(t.path)
  t.close
  @locations = if !Declarations[@klass.name].nil?
    Declarations[@klass.name].uniq 
  else
    Guesser.new(@klass, files).locations || [] 
  end
end

#standard_class_declared(event, binding) ⇒ Object



61
62
63
64
65
# File 'lib/class_source/locator.rb', line 61

def standard_class_declared(event, binding)
  return unless event == 'class'
  event_class = eval( "Module.nesting", binding )
  event_class.first
end

#to_aObject



11
12
13
# File 'lib/class_source/locator.rb', line 11

def to_a
  source_locations
end

#trace_declarations(source_file, declarations) ⇒ Object



44
45
46
47
48
49
50
51
52
53
54
# File 'lib/class_source/locator.rb', line 44

def trace_declarations(source_file, declarations)
  set_trace_func lambda { |event, file, line, id, binding, classname|
    defined_class = standard_class_declared(event, binding) || dynamic_class_declared(id, classname, file, line)
    break unless defined_class
    defined_class_name = defined_class.is_a?(String) ? defined_class : defined_class.name
    declarations[defined_class_name] ||= []
    declarations[defined_class_name] << [ file, line ]
  }
  silence_warnings { load source_file }
  declarations
end