Class: CallGraph::Instrument

Inherits:
Object
  • Object
show all
Defined in:
lib/call_graph/instrument.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(file_path: default_file_path, ignore_paths: default_ignore_paths, ignore_methods: default_ignore_methods) ⇒ Instrument

Returns a new instance of Instrument.



8
9
10
11
12
13
# File 'lib/call_graph/instrument.rb', line 8

def initialize(file_path: default_file_path, ignore_paths: default_ignore_paths, ignore_methods: default_ignore_methods)
  @file_path      = file_path
  @ignore_paths   = ignore_paths
  @ignore_methods = ignore_methods
  @set            = Set.new
end

Instance Attribute Details

#file_pathObject

Returns the value of attribute file_path.



6
7
8
# File 'lib/call_graph/instrument.rb', line 6

def file_path
  @file_path
end

#ignore_methodsObject

Returns the value of attribute ignore_methods.



6
7
8
# File 'lib/call_graph/instrument.rb', line 6

def ignore_methods
  @ignore_methods
end

#ignore_pathsObject

Returns the value of attribute ignore_paths.



6
7
8
# File 'lib/call_graph/instrument.rb', line 6

def ignore_paths
  @ignore_paths
end

#setObject

Returns the value of attribute set.



6
7
8
# File 'lib/call_graph/instrument.rb', line 6

def set
  @set
end

Instance Method Details

#default_file_pathObject



19
20
21
# File 'lib/call_graph/instrument.rb', line 19

def default_file_path
  'call_graph'
end

#default_ignore_methodsObject



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/call_graph/instrument.rb', line 33

def default_ignore_methods
  [
    :require,
    :set_encoding,
    :initialize,
    :new,
    :attr_reader,
    :method_added,
    :private,
    :inherited,
    :singleton_method_added,
    :set_trace_func,
    :call
  ]
end

#default_ignore_pathsObject



23
24
25
26
27
28
29
30
31
# File 'lib/call_graph/instrument.rb', line 23

def default_ignore_paths
  [
    /#{RUBY_VERSION}/,
    /\(eval\)/,
    /bundle\/gems/,
    /spec/,
    /test/
  ]
end

#path(kind) ⇒ Object



15
16
17
# File 'lib/call_graph/instrument.rb', line 15

def path(kind)
  "#{file_path}.#{kind}"
end

#startObject



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/call_graph/instrument.rb', line 49

def start
  set_trace_func ->(event, file, _line, id, receiver_binding, classname) do
    # :nocov:
    return if ignore_paths.any? { |path| file && file[path] }

    case event
    when 'call', 'c-call'
      caller_binding = receiver_binding.of_caller(2)

      caller_class = caller_binding.eval('self.class == Class ? self.name : self.class.name')
      caller_class = caller_binding.frame_description unless caller_class
      caller_class = caller_class + ' ' + caller_binding.eval("self.class == Class ? '(Class)' : '(Instance)'")


      receiver_class = receiver_binding.eval('self.class == Class ? self.name : self.class.name')
      receiver_class = caller_binding.frame_description if receiver_class.nil?
      receiver_class = receiver_class + ' ' + receiver_binding.eval("self.class == Class ? '(Class)' : '(Instance)'")

      return if classname == CallGraph
      return if classname == CallGraph::Instrument
      return if caller_class == receiver_class
      return if ignore_methods.include?(id)

      set.add("#{caller_class},#{receiver_class},#{id}")
    end
    #:nocov:
  end
end

#stopObject



78
79
80
81
82
83
84
# File 'lib/call_graph/instrument.rb', line 78

def stop
  set_trace_func nil

  File.open(path(:tmp), 'w') { |fd| fd.write set.to_a.compact.join("\n") }

  set.clear
end