class Object
Public Instance Methods
call_graph(filename_rb)
click to toggle source
filename_rb [String] file with a ruby program @return a dot graph string
# 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)
click to toggle source
# File lib/code_explorer/call_graph.rb, line 89 def calls_from_def(ast) Defs.new.sends_from_ast(ast) end
def_location(node)
click to toggle source
# 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)
click to toggle source
# 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)
click to toggle source
# 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 = {})
click to toggle source
@param graph [Hash{String => Array<String>}] vertex -> reachable vertices @param hrefs [Hash{String => String}] vertex -> href
# 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)
click to toggle source
Convert plain text to HTML where lines are hyperlinkable. Emulate RFC 5147 fragment identifier: line=42
# 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)
click to toggle source
# File lib/code_explorer/call_graph.rb, line 46 def send_name(node) _receiver, name, *_args = *node name end