Top Level Namespace

Defined Under Namespace

Modules: CodeExplorer Classes: Defs

Instance Method Summary collapse

Instance Method Details

#call_graph(filename_rb) ⇒ Object

filename_rb [String] file with a ruby program

Returns:

  • a dot graph string



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# File 'lib/code_explorer/call_graph.rb', line 9

def call_graph(filename_rb)
  ruby = File.read(filename_rb)
  ast = Parser::CurrentRuby.parse(ruby, filename_rb)
  defs = defs_from_ast(ast)
  def_names = defs.map {|d| def_name(d) }
  defs_to_hrefs = defs.map {|d| [def_name(d), "/files/" + def_location(d)] }.to_h

  defs_to_calls = {}
  defs.each do |d|
    calls = calls_from_def(d)
    call_names = calls.map {|c| send_name(c)}
    call_names = call_names.find_all{ |cn| def_names.include?(cn) }
    defs_to_calls[def_name(d)] = call_names
  end

  dot_from_hash(defs_to_calls, defs_to_hrefs)
end

#calls_from_def(ast) ⇒ Object



89
90
91
# File 'lib/code_explorer/call_graph.rb', line 89

def calls_from_def(ast)
  Defs.new.sends_from_ast(ast)
end

#def_location(node) ⇒ Object



39
40
41
42
43
44
# File 'lib/code_explorer/call_graph.rb', line 39

def def_location(node)
  range = node.loc.expression
  file = range.source_buffer.name
  line = range.line
  "#{file}#line=#{line}"
end

#def_name(node) ⇒ Object



27
28
29
30
31
32
33
34
35
36
37
# File 'lib/code_explorer/call_graph.rb', line 27

def def_name(node)
  case node.type
  when :def
    name, _args, _body = *node
  when :defs
    _obj, name, _args, _body = *node
  else
    raise
  end
  name
end

#defs_from_ast(ast) ⇒ Object



85
86
87
# File 'lib/code_explorer/call_graph.rb', line 85

def defs_from_ast(ast)
  Defs.new.defs_from_ast(ast)
end

#dot_from_hash(graph, hrefs = {}) ⇒ Object

Parameters:

  • graph (Hash{String => Array<String>})

    vertex -> reachable vertices

  • hrefs (Hash{String => String}) (defaults to: {})

    vertex -> href



4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# File 'lib/code_explorer/dot.rb', line 4

def dot_from_hash(graph, hrefs = {})
  dot = ""
  dot << "digraph g {\n"
  dot << "rankdir=LR;\n"
  graph.keys.sort.each do |vertex|
    href = hrefs[vertex]
    href = "href=\"#{href}\" " if href

    dot << "\"#{vertex}\"[#{href}];\n"
    destinations = graph[vertex].sort
    destinations.each do |d|
      dot << "\"#{vertex}\" -> \"#{d}\";\n"
    end
  end
  dot << "}\n"
  dot
end

#numbered_lines(text) ⇒ Object

Convert plain text to HTML where lines are hyperlinkable. Emulate RFC 5147 fragment identifier: #line=42



5
6
7
8
9
10
# File 'lib/code_explorer/numbered_lines.rb', line 5

def numbered_lines(text)
  # but CodeRay wants to remove the equal sign;
  tag = "lI" + "-Ne" # avoid the literal tag if we process our own source
  html = CodeRay.scan(text, :ruby).page(line_number_anchors: tag)
  html.gsub(tag, "line=")
end

#send_name(node) ⇒ Object



46
47
48
49
# File 'lib/code_explorer/call_graph.rb', line 46

def send_name(node)
  _receiver, name, *_args = *node
  name
end