Module: CodeNode

Extended by:
Cog::Generator
Defined in:
lib/code_node.rb,
lib/code_node/ir.rb,
lib/code_node/dsl.rb,
lib/code_node/ir/node.rb,
lib/code_node/ir/graph.rb,
lib/code_node/sexp_walker.rb,
lib/code_node/ir/node_matcher.rb,
lib/code_node/dsl/graph_definer.rb

Overview

Create Class and Module graphs for Ruby prjects

Defined Under Namespace

Modules: DSL, IR Classes: SexpWalker

Class Method Summary collapse

Class Method Details

.graph(graph_name, opt = {}) {|GraphDefinition| ... } ⇒ Object

Parameters:

  • graph_name (String)

    name of the dot file to generate (without .dot extension)

  • opt (Hash) (defaults to: {})

    a customizable set of options

Options Hash (opt):

  • :ruby_version (Symbol) — default: :ruby19

    either :ruby18 or :ruby19, indicating which parser to use

Yields:

  • (GraphDefinition)

    define rules for creating the graph



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/code_node.rb', line 17

def self.graph(graph_name, opt={}, &block)
  feedback_color = :white
  root = Cog::Config.instance.project_source_path
  @graph = IR::Graph.new
  graph_definer = DSL::GraphDefiner.new @graph
  block.call graph_definer

  rp = case opt[:ruby_version]
  when :ruby18
    Ruby18Parser.new
  else
    Ruby19Parser.new
  end

  sexp = []
  [:find_nodes, :find_relations].each_with_index do |mode, pass|
    puts "#{(pass+1).ordinalize} pass: #{mode.to_s.gsub('_', ' ')}".color(feedback_color)
    Dir.glob("#{root}/**/*.rb").each_with_index do |filename, i|
      sexp[i] ||= begin
        rp.parse(File.read filename)
      rescue Racc::ParseError
        STDERR.write "#{filename.relative_to_project_root}, skipped...\n".color(:yellow)
        nil
      end
      if sexp[i]
        walker = SexpWalker.new @graph, sexp[i], :mode => mode
        walker.walk
      end
    end
  end

  # Apply styles before pruning because some relations may be destroyed while pruning
  puts "Applying styles".color(feedback_color)
  @graph.apply_styles

  # Prune the graph according to ignore rules.
  # We keep pruning until there are no more changes because some rules don't apply the first time (for example: &:island?)
  puts "Pruning nodes".color(feedback_color)
  i = 1
  while (x = @graph.prune) > 0
    puts "  #{x} nodes pruned on #{i.ordinalize} pass".color(feedback_color)
    i += 1
  end
  
  # Activate code_node while rendering templates
  # so that cog will be able to find code_node templates
  Cog::Config.instance.activate_tool 'code_node' do
    stamp 'code_node/graph.dot', "#{graph_name}.dot"
  end
  
  nil
end