code_node 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/cog/templates/code_node/generator.rb.erb +4 -0
- data/cog/templates/code_node/graph.dot.erb +25 -31
- data/cog/templates/code_node/node.dot.erb +1 -0
- data/lib/code_node.rb +5 -4
- data/lib/code_node/dsl/graph_definer.rb +27 -0
- data/lib/code_node/ir.rb +1 -2
- data/lib/code_node/ir/graph.rb +76 -11
- data/lib/code_node/ir/node.rb +129 -18
- data/lib/code_node/sexp_walker.rb +31 -12
- data/lib/code_node/version.rb +1 -1
- metadata +35 -8
- data/lib/code_node/ir/class_node.rb +0 -22
- data/lib/code_node/ir/module_node.rb +0 -26
@@ -3,46 +3,40 @@ digraph
|
|
3
3
|
graph [rankdir="LR"]
|
4
4
|
node [style="filled"]
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
6
|
+
/* Module nodes */
|
7
|
+
node [shape="box" fillcolor="#333333" fontcolor="#ffffff"];
|
8
|
+
<% @graph.each_module do |node| %>
|
9
|
+
<%= node.stamp 'code_node/node.dot' %>
|
10
10
|
<% end %>
|
11
11
|
|
12
|
-
/*
|
13
|
-
|
14
|
-
<% @graph.
|
15
|
-
|
16
|
-
<%= node.parent.key %> -> <%= node.key %>;
|
17
|
-
<% end %>
|
12
|
+
/* Class nodes */
|
13
|
+
node [shape="ellipse" fillcolor="#cccccc" fontcolor="#000000"];
|
14
|
+
<% @graph.each_class do |node| %>
|
15
|
+
<%= node.stamp 'code_node/node.dot' %>
|
18
16
|
<% end %>
|
19
17
|
|
20
|
-
/*
|
21
|
-
edge [color="#
|
22
|
-
<% @graph.
|
23
|
-
|
24
|
-
<% if node.should_render? && other.should_render? %>
|
25
|
-
<%= node.key %> -> <%= other.key %>;
|
26
|
-
<% end %>
|
27
|
-
<% end %>
|
18
|
+
/* A contains B */
|
19
|
+
edge [color="#e8e8e8"];
|
20
|
+
<% @graph.each_containment do |a, b| %>
|
21
|
+
<%= a.key %> -> <%= b.key %>;
|
28
22
|
<% end %>
|
29
23
|
|
30
|
-
/*
|
31
|
-
edge [color="#
|
32
|
-
<% @graph.
|
33
|
-
|
34
|
-
<% if node.should_render? && other.should_render? %>
|
35
|
-
<%= node.key %> -> <%= other.key %>;
|
36
|
-
<% end %>
|
37
|
-
<% end %>
|
24
|
+
/* A inherits from B */
|
25
|
+
edge [color="#996633"];
|
26
|
+
<% @graph.each_inheritance do |a, b| %>
|
27
|
+
<%= a.key %> -> <%= b.key %>;
|
38
28
|
<% end %>
|
39
29
|
|
40
|
-
/*
|
41
|
-
edge [color="#
|
42
|
-
<% @graph.
|
43
|
-
|
44
|
-
<%= node.key %> -> <%= node.inherits_from.key %>;
|
30
|
+
/* A includes B */
|
31
|
+
edge [color="#336699"];
|
32
|
+
<% @graph.each_inclusion do |a, b| %>
|
33
|
+
<%= a.key %> -> <%= b.key %>;
|
45
34
|
<% end %>
|
35
|
+
|
36
|
+
/* A extends B */
|
37
|
+
edge [color="#000000"];
|
38
|
+
<% @graph.each_extension do |a, b| %>
|
39
|
+
<%= a.key %> -> <%= b.key %>;
|
46
40
|
<% end %>
|
47
41
|
|
48
42
|
}
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= key %> [label="<%= label %>"];
|
data/lib/code_node.rb
CHANGED
@@ -28,8 +28,9 @@ module CodeNode
|
|
28
28
|
end
|
29
29
|
|
30
30
|
sexp = []
|
31
|
-
[:find_nodes, :find_relations].each_with_index do |
|
32
|
-
puts "#{(pass+1).ordinalize} pass: #{
|
31
|
+
[:find_nodes, :find_relations].each_with_index do |mode, pass|
|
32
|
+
puts "#{(pass+1).ordinalize} pass: #{mode.to_s.gsub('_', ' ')}".color(:cyan)
|
33
|
+
|
33
34
|
Dir.glob("#{root}/**/*.rb").each_with_index do |filename, i|
|
34
35
|
sexp[i] ||= begin
|
35
36
|
rp.parse(File.read filename)
|
@@ -38,8 +39,8 @@ module CodeNode
|
|
38
39
|
nil
|
39
40
|
end
|
40
41
|
if sexp[i]
|
41
|
-
walker = SexpWalker.new @graph, sexp[i]
|
42
|
-
walker.walk
|
42
|
+
walker = SexpWalker.new @graph, sexp[i], :mode => mode
|
43
|
+
walker.walk
|
43
44
|
end
|
44
45
|
end
|
45
46
|
end
|
@@ -1,12 +1,39 @@
|
|
1
1
|
module CodeNode
|
2
2
|
module DSL
|
3
3
|
|
4
|
+
# Specify rules for generating the graph
|
4
5
|
class GraphDefiner
|
5
6
|
|
7
|
+
# @api developer
|
8
|
+
# @param graph [IR::Graph] a graph for which rules can be defined
|
6
9
|
def initialize(graph)
|
7
10
|
@graph = graph
|
8
11
|
end
|
9
12
|
|
13
|
+
# Speficy an ignore rule for the graph.
|
14
|
+
# Nodes matching the ignore rule will not be included in the graph.
|
15
|
+
# Ignore rules can be given in one of three ways.
|
16
|
+
#
|
17
|
+
# * +String+ provide a fully qualified path
|
18
|
+
# * +Regexp+ provide a pattern that will be tested against the {IR::Node#path}
|
19
|
+
# * +Proc+ provide a block. If the block returns +true+ the node will be ignored
|
20
|
+
#
|
21
|
+
# @param name [String, Regexp, nil] fully qualified path or regular expression which will be compared to {IR::Node#path}
|
22
|
+
# @yield [Node] if provided, return +true+ to ignore the node
|
23
|
+
# @return [nil]
|
24
|
+
def ignore(name=nil, &block)
|
25
|
+
if (name.nil? && block.nil?) || (name && block)
|
26
|
+
raise ArgumentError.new('Provide either a name or a block')
|
27
|
+
end
|
28
|
+
if block
|
29
|
+
@graph.instance_eval {@exclude_procs << block}
|
30
|
+
elsif name.is_a? Regexp
|
31
|
+
@graph.instance_eval {@exclude_patterns << name}
|
32
|
+
else
|
33
|
+
@graph.instance_eval {@exclude_paths << name}
|
34
|
+
end
|
35
|
+
nil
|
36
|
+
end
|
10
37
|
end
|
11
38
|
|
12
39
|
end
|
data/lib/code_node/ir.rb
CHANGED
data/lib/code_node/ir/graph.rb
CHANGED
@@ -1,18 +1,23 @@
|
|
1
|
-
require 'code_node/ir/
|
2
|
-
require 'code_node/ir/module_node'
|
1
|
+
require 'code_node/ir/node'
|
3
2
|
|
4
3
|
module CodeNode
|
5
4
|
module IR
|
6
5
|
|
7
6
|
class Graph
|
8
7
|
|
8
|
+
# @api developer
|
9
9
|
attr_reader :scope
|
10
|
-
|
10
|
+
|
11
|
+
# @api developer
|
11
12
|
def initialize
|
13
|
+
@exclude_paths = []
|
14
|
+
@exclude_patterns = []
|
15
|
+
@exclude_procs = []
|
12
16
|
@nodes = {}
|
13
17
|
@scope = []
|
14
18
|
end
|
15
19
|
|
20
|
+
# @api developer
|
16
21
|
def node_for(node_type, s, opt={}, &block)
|
17
22
|
name = if s.is_a? Symbol
|
18
23
|
s
|
@@ -35,10 +40,10 @@ module CodeNode
|
|
35
40
|
if @scope.length > 1 && @scope[-2].find(name)
|
36
41
|
@scope[-2].find name
|
37
42
|
else
|
38
|
-
|
43
|
+
Node.new name, :node_type => node_type
|
39
44
|
end
|
40
45
|
else
|
41
|
-
|
46
|
+
Node.new name, :parent => @scope.last, :node_type => node_type
|
42
47
|
end
|
43
48
|
|
44
49
|
node = self << node
|
@@ -51,14 +56,74 @@ module CodeNode
|
|
51
56
|
end
|
52
57
|
|
53
58
|
def <<(node)
|
54
|
-
@nodes[node.
|
55
|
-
@nodes[node.
|
59
|
+
@nodes[node.path] ||= node
|
60
|
+
@nodes[node.path]
|
61
|
+
end
|
62
|
+
|
63
|
+
# Iterate through each {Node} with {Node#class?} in the graph
|
64
|
+
# @yield [Node] a class node. Does not yield ignored nodes.
|
65
|
+
# @return [nil]
|
66
|
+
def each_class(&block)
|
67
|
+
@nodes.values.select do |node|
|
68
|
+
node.class? && !should_exclude?(node)
|
69
|
+
end.sort.each &block
|
70
|
+
end
|
71
|
+
|
72
|
+
# Iterate through each {Node} with {Node#module?} in the graph
|
73
|
+
# @yield [Node] a module node. Does not yield ignored nodes.
|
74
|
+
# @return [nil]
|
75
|
+
def each_module(&block)
|
76
|
+
@nodes.values.select do |node|
|
77
|
+
node.module? && !should_exclude?(node)
|
78
|
+
end.sort.each &block
|
79
|
+
end
|
80
|
+
|
81
|
+
# Iterate through each containment relation in the graph
|
82
|
+
def each_containment(&block)
|
83
|
+
@nodes.values.sort.each do |node|
|
84
|
+
if node.parent && !should_exclude?(node) && !should_exclude?(node.parent)
|
85
|
+
block.call node.parent, node
|
86
|
+
end
|
87
|
+
end
|
56
88
|
end
|
57
|
-
|
58
|
-
|
89
|
+
|
90
|
+
# Iterate through each inheritance relation in the graph
|
91
|
+
def each_inheritance(&block)
|
92
|
+
@nodes.values.sort.each do |node|
|
93
|
+
if node.super_class_node && !should_exclude?(node) && !should_exclude?(node.super_class_node)
|
94
|
+
block.call node, node.super_class_node
|
95
|
+
end
|
96
|
+
end
|
59
97
|
end
|
60
|
-
|
61
|
-
|
98
|
+
|
99
|
+
# Iterate through each inclusion relation in the graph
|
100
|
+
def each_inclusion(&block)
|
101
|
+
@nodes.values.sort.each do |node|
|
102
|
+
node.inclusions.each do |other|
|
103
|
+
if !should_exclude?(node) && !should_exclude?(other)
|
104
|
+
block.call node, other
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
# Iterate through each extension relation in the graph
|
111
|
+
def each_extension(&block)
|
112
|
+
@nodes.values.sort.each do |node|
|
113
|
+
node.extensions.each do |other|
|
114
|
+
if !should_exclude?(node) && !should_exclude?(other)
|
115
|
+
block.call node, other
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
private
|
122
|
+
|
123
|
+
def should_exclude?(node)
|
124
|
+
@exclude_paths.any? {|path| path == node.path} ||
|
125
|
+
@exclude_patterns.any? {|pattern| pattern =~ node.path} ||
|
126
|
+
@exclude_procs.any? {|block| block.call(node)}
|
62
127
|
end
|
63
128
|
end
|
64
129
|
|
data/lib/code_node/ir/node.rb
CHANGED
@@ -1,51 +1,162 @@
|
|
1
|
+
require 'cog'
|
2
|
+
|
1
3
|
module CodeNode
|
2
4
|
module IR
|
3
5
|
|
6
|
+
# A node in the {Graph}
|
7
|
+
# Nodes come in two flavors: {#class?} and {#module?} nodes
|
4
8
|
class Node
|
5
|
-
|
6
|
-
|
7
|
-
|
9
|
+
|
10
|
+
include Cog::Generator
|
11
|
+
|
12
|
+
# @return [String] the name of the node. Not necessarilly unique.
|
13
|
+
# @see {#path}
|
14
|
+
attr_reader :name
|
15
|
+
|
16
|
+
# @return [Node] node which contains this node
|
17
|
+
# @example
|
18
|
+
# module Foo # Foo is the parent
|
19
|
+
# module Bar # to Bar
|
20
|
+
# end
|
21
|
+
# end
|
22
|
+
attr_reader :parent
|
23
|
+
|
24
|
+
# The child nodes of this node
|
25
|
+
# @return [Hash<String,Node>] a mapping from node {#path} names to nodes
|
26
|
+
# @example
|
27
|
+
# module Foo # Foo has children
|
28
|
+
# module Bar # Bar
|
29
|
+
# end # and
|
30
|
+
# class Car # Car
|
31
|
+
# end
|
32
|
+
# end
|
33
|
+
attr_reader :children
|
34
|
+
|
35
|
+
# @param name [String, Array]
|
36
|
+
# @option opt [Node] :parent (nil)
|
37
|
+
# @option opt [Symbol] :node_type (:module) either <tt>:module</tt> or <tt>:class</tt>
|
38
|
+
def initialize(name, opt={})
|
39
|
+
@node_type = opt[:node_type] || :module
|
40
|
+
@parent = opt[:parent]
|
41
|
+
parent_path = @parent ? @parent.instance_eval {@path} : []
|
8
42
|
@path = if name.is_a? Array
|
9
43
|
parent_path + name
|
10
44
|
else
|
11
45
|
parent_path + [name]
|
12
46
|
end
|
13
47
|
@name = @path.last
|
14
|
-
@parent = parent
|
15
|
-
parent.children[key] = self unless parent.nil?
|
48
|
+
@parent.children[path] = self unless @parent.nil?
|
16
49
|
@children = {}
|
50
|
+
@inherited_by = {}
|
17
51
|
@includes = {}
|
52
|
+
@included_by = {}
|
53
|
+
@extends = {}
|
18
54
|
@extended_by = {}
|
19
55
|
end
|
56
|
+
|
20
57
|
def find(name)
|
21
|
-
|
22
|
-
@children[
|
58
|
+
path = (@path + [name].flatten).join '::'
|
59
|
+
@children[path] || (@parent && @parent.find(name))
|
23
60
|
end
|
61
|
+
|
62
|
+
# @return [String] fully qualified identifier for the node in the form <tt>Foo_Bar_Car</tt>. Ideal for graphviz identifiers.
|
24
63
|
def key
|
25
64
|
@path.join '_'
|
26
65
|
end
|
66
|
+
|
67
|
+
# @return [String] fully qualified name of the node in the form <tt>'Foo::Bar::Car'</tt>. Not good as a graphviz identifier because of the colon (+:+) characters. Use {#key} for graphviz identifiers instead.
|
27
68
|
def path
|
28
69
|
@path.join '::'
|
29
70
|
end
|
71
|
+
|
72
|
+
# @return [String] how the node will be labelled in the graph. Nodes without parents display their full {#path}, while nodes with parents only display their {#name}.
|
30
73
|
def label
|
31
|
-
|
32
|
-
end
|
33
|
-
def to_s
|
34
|
-
path
|
74
|
+
@parent.nil? ? path : name
|
35
75
|
end
|
76
|
+
|
77
|
+
# @return [FixNum] order nodes by {#path}
|
36
78
|
def <=>(other)
|
37
79
|
path <=> other.path
|
38
80
|
end
|
39
|
-
|
40
|
-
|
81
|
+
|
82
|
+
# @return [Boolean] whether or not this node represents a module
|
83
|
+
def module?
|
84
|
+
@node_type == :module
|
85
|
+
end
|
86
|
+
|
87
|
+
# @return [Boolean] whether or not this node represents a class
|
88
|
+
def class?
|
89
|
+
@node_type == :class
|
90
|
+
end
|
91
|
+
|
92
|
+
# @param other [Node]
|
93
|
+
def inherits_from(other)
|
94
|
+
this = self
|
95
|
+
@inherits_from = other
|
96
|
+
other.instance_eval {@inherited_by[this.path] = this}
|
97
|
+
end
|
98
|
+
|
99
|
+
# @return [Node,nil] the super class of this class. Will be +nil+ for modules.
|
100
|
+
def super_class_node
|
101
|
+
@inherits_from
|
102
|
+
end
|
103
|
+
|
104
|
+
# @param other [Node]
|
105
|
+
def includes(other)
|
106
|
+
this = self
|
107
|
+
@includes[other.path] = other
|
108
|
+
other.instance_eval {@included_by[this.path] = this}
|
109
|
+
end
|
110
|
+
|
111
|
+
# @return [Array<Node>] module nodes for which this node has an +include+ statement
|
112
|
+
def inclusions
|
113
|
+
@includes.values.sort
|
114
|
+
end
|
115
|
+
|
116
|
+
# @param other [Node]
|
117
|
+
def extends(other)
|
118
|
+
this = self
|
119
|
+
@extends[other.path] = other
|
120
|
+
other.instance_eval {@extended_by[this.path] = this}
|
121
|
+
end
|
122
|
+
|
123
|
+
# @return [Array<Node>] module nodes for which this node has an +extend+ statement
|
124
|
+
def extensions
|
125
|
+
@extends.values.sort
|
126
|
+
end
|
127
|
+
|
128
|
+
# Set the given class node as the super class of this node
|
129
|
+
# @param super_node [Node] a {#class?} node
|
130
|
+
# @return [nil]
|
131
|
+
def inherits_from=(super_node)
|
132
|
+
throw :NodeNotAClass unless class?
|
133
|
+
throw :SuperNodeNotAClass unless super_node.class?
|
134
|
+
@inherits_from = super_node
|
135
|
+
end
|
136
|
+
|
137
|
+
# @return [Boolean] whether or not this node inherits from a given node. Note that a node does inherit from itself, according to this method. Recursively checks the ancestry of the node.
|
138
|
+
def inherits_from?(k)
|
139
|
+
key == k || @inherits_from && (@inherits_from.key == k || @inherits_from.inherits_from?(k))
|
140
|
+
end
|
141
|
+
|
142
|
+
# Mark this module node as a singleton
|
143
|
+
# @return [nil]
|
144
|
+
def mark_as_singleton
|
145
|
+
throw :NodeNotAModule unless module?
|
146
|
+
@singleton = true
|
41
147
|
end
|
42
|
-
|
43
|
-
|
148
|
+
|
149
|
+
# @return [Boolean] whether or not this node represents a singleton module
|
150
|
+
def singleton?
|
151
|
+
@singleton
|
44
152
|
end
|
45
|
-
|
46
|
-
|
153
|
+
|
154
|
+
# @return [Boolean] whether or not this node is an island. An island is a node with no connections to other nodes.
|
155
|
+
def island?
|
156
|
+
([@parent, @inherits_from].all?(&:nil?) &&
|
157
|
+
[@children, @inherited_by, @extends, @includes, @extended_by, @included_by].all?(&:empty?))
|
47
158
|
end
|
159
|
+
|
48
160
|
end
|
49
|
-
|
50
161
|
end
|
51
162
|
end
|
@@ -1,40 +1,59 @@
|
|
1
1
|
module CodeNode
|
2
2
|
|
3
|
+
# Walks a Sexp representing a ruby file looking for classes and modules.
|
3
4
|
class SexpWalker
|
4
|
-
|
5
|
+
|
6
|
+
# Initialize a walker with a graph and sexp
|
7
|
+
#
|
8
|
+
# All files in a code base should be walked once in <tt>:find_nodes</tt> mode, and then walked again in <tt>:find_relations</tt> mode.
|
9
|
+
#
|
10
|
+
# @param graph [Graph] a graph to which nodes and relations will be added
|
11
|
+
# @param sexp [Sexp] the root sexp of a ruby file
|
12
|
+
# @option opt [Symbol] :mode (:find_nodes) one of <tt>:find_nodes</tt> or <tt>:find_relations</tt>
|
13
|
+
def initialize(graph, sexp, opt={})
|
5
14
|
@graph = graph
|
6
15
|
@root = sexp
|
16
|
+
@mode = opt[:mode] || :find_nodes
|
7
17
|
end
|
8
|
-
|
18
|
+
|
19
|
+
# Walk the tree rooted at the given sexp
|
20
|
+
# @param s [Sexp] if +nil+ will be the root sexp
|
21
|
+
# @return [nil]
|
22
|
+
def walk(s = nil)
|
9
23
|
s ||= @root
|
10
24
|
if [:module, :class].member?(s[0])
|
11
25
|
@graph.node_for(s[0], s[1]) do |node|
|
12
|
-
if
|
26
|
+
if find_relations? && s[0] == :class && !s[2].nil?
|
13
27
|
super_node = @graph.node_for :class, s[2], :not_sure_if_nested => true
|
14
|
-
unless super_node.nil?
|
15
|
-
node.inherits_from = super_node
|
16
|
-
end
|
28
|
+
node.inherits_from super_node unless super_node.nil?
|
17
29
|
end
|
18
30
|
rest = s[0] == :module ? s.slice(2..-1) : s.slice(3..-1)
|
19
31
|
rest.each do |c|
|
20
|
-
walk(
|
32
|
+
walk(c) if c.class == Sexp
|
21
33
|
end
|
22
34
|
end
|
23
|
-
elsif
|
35
|
+
elsif find_relations? && s[0] == :call && s.length >= 4 && [:extend, :include].member?(s[2]) && !@graph.scope.empty?
|
24
36
|
node = @graph.node_for :module, s[3], :not_sure_if_nested => true
|
25
37
|
unless node.nil?
|
26
38
|
if s[2] == :extend
|
27
|
-
@graph.scope.last.
|
39
|
+
@graph.scope.last.extends node
|
28
40
|
else
|
29
|
-
@graph.scope.last.includes
|
41
|
+
@graph.scope.last.includes node
|
30
42
|
end
|
31
43
|
end
|
32
44
|
else
|
33
45
|
s.slice(1..-1).each do |c|
|
34
|
-
walk(
|
46
|
+
walk(c) if c.class == Sexp
|
35
47
|
end
|
36
48
|
end
|
37
49
|
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
# @return [Boolean] whether or not the walker should look for relations
|
54
|
+
def find_relations?
|
55
|
+
@mode == :find_relations
|
56
|
+
end
|
57
|
+
|
38
58
|
end
|
39
|
-
|
40
59
|
end
|
data/lib/code_node/version.rb
CHANGED
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: code_node
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 27
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 2
|
10
|
+
version: 0.0.2
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Kevin Tonon
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2012-11-
|
18
|
+
date: 2012-11-19 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
name: cog
|
@@ -60,7 +60,7 @@ dependencies:
|
|
60
60
|
type: :development
|
61
61
|
version_requirements: *id003
|
62
62
|
- !ruby/object:Gem::Dependency
|
63
|
-
name:
|
63
|
+
name: redcarpet
|
64
64
|
prerelease: false
|
65
65
|
requirement: &id004 !ruby/object:Gem::Requirement
|
66
66
|
none: false
|
@@ -73,6 +73,34 @@ dependencies:
|
|
73
73
|
version: "0"
|
74
74
|
type: :development
|
75
75
|
version_requirements: *id004
|
76
|
+
- !ruby/object:Gem::Dependency
|
77
|
+
name: rspec
|
78
|
+
prerelease: false
|
79
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
80
|
+
none: false
|
81
|
+
requirements:
|
82
|
+
- - ">="
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
hash: 3
|
85
|
+
segments:
|
86
|
+
- 0
|
87
|
+
version: "0"
|
88
|
+
type: :development
|
89
|
+
version_requirements: *id005
|
90
|
+
- !ruby/object:Gem::Dependency
|
91
|
+
name: yard
|
92
|
+
prerelease: false
|
93
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
94
|
+
none: false
|
95
|
+
requirements:
|
96
|
+
- - ">="
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
hash: 3
|
99
|
+
segments:
|
100
|
+
- 0
|
101
|
+
version: "0"
|
102
|
+
type: :development
|
103
|
+
version_requirements: *id006
|
76
104
|
description:
|
77
105
|
email: kevin@betweenconcepts.com
|
78
106
|
executables: []
|
@@ -85,18 +113,17 @@ files:
|
|
85
113
|
- LICENSE
|
86
114
|
- cog/templates/code_node/generator.rb.erb
|
87
115
|
- cog/templates/code_node/graph.dot.erb
|
116
|
+
- cog/templates/code_node/node.dot.erb
|
88
117
|
- lib/code_node/cog_tool.rb
|
89
118
|
- lib/code_node/dsl/graph_definer.rb
|
90
119
|
- lib/code_node/dsl.rb
|
91
|
-
- lib/code_node/ir/class_node.rb
|
92
120
|
- lib/code_node/ir/graph.rb
|
93
|
-
- lib/code_node/ir/module_node.rb
|
94
121
|
- lib/code_node/ir/node.rb
|
95
122
|
- lib/code_node/ir.rb
|
96
123
|
- lib/code_node/sexp_walker.rb
|
97
124
|
- lib/code_node/version.rb
|
98
125
|
- lib/code_node.rb
|
99
|
-
homepage:
|
126
|
+
homepage: https://github.com/ktonon/code_node
|
100
127
|
licenses: []
|
101
128
|
|
102
129
|
post_install_message:
|
@@ -1,22 +0,0 @@
|
|
1
|
-
require 'code_node/ir/node'
|
2
|
-
|
3
|
-
module CodeNode
|
4
|
-
module IR
|
5
|
-
|
6
|
-
class ClassNode < Node
|
7
|
-
def inherits_from=(super_node)
|
8
|
-
@inherits_from = super_node
|
9
|
-
end
|
10
|
-
def shape
|
11
|
-
:ellipse
|
12
|
-
end
|
13
|
-
def fillcolor
|
14
|
-
'#cccccc'
|
15
|
-
end
|
16
|
-
def fontcolor
|
17
|
-
'#000000'
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
end
|
22
|
-
end
|
@@ -1,26 +0,0 @@
|
|
1
|
-
require 'code_node/ir/node'
|
2
|
-
|
3
|
-
module CodeNode
|
4
|
-
module IR
|
5
|
-
|
6
|
-
class ModuleNode < Node
|
7
|
-
def shape
|
8
|
-
:box
|
9
|
-
end
|
10
|
-
def fillcolor
|
11
|
-
if children["#{key}_ClassMethods"] && extended_by['ActiveSupport_Concern']
|
12
|
-
'#000000'
|
13
|
-
else
|
14
|
-
'#666666'
|
15
|
-
end
|
16
|
-
end
|
17
|
-
def fontcolor
|
18
|
-
'#ffffff'
|
19
|
-
end
|
20
|
-
def mark_as_singleton
|
21
|
-
@singleton = true
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
end
|
26
|
-
end
|