code_node 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|