analyst 0.14.2 → 0.15.0
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.
- checksums.yaml +4 -4
- data/analyst.gemspec +3 -2
- data/lib/analyst/entities/array.rb +15 -0
- data/lib/analyst/entities/class.rb +6 -59
- data/lib/analyst/entities/code_block.rb +18 -0
- data/lib/analyst/entities/conditional.rb +19 -0
- data/lib/analyst/entities/constant.rb +41 -0
- data/lib/analyst/entities/entity.rb +68 -12
- data/lib/analyst/entities/file.rb +42 -0
- data/lib/analyst/entities/hash.rb +16 -3
- data/lib/analyst/entities/interpolated_string.rb +3 -0
- data/lib/analyst/entities/method.rb +15 -1
- data/lib/analyst/entities/method_call.rb +20 -4
- data/lib/analyst/entities/module.rb +11 -14
- data/lib/analyst/entities/pair.rb +3 -0
- data/lib/analyst/entities/root.rb +28 -4
- data/lib/analyst/entities/singleton_class.rb +2 -0
- data/lib/analyst/entities/source.rb +42 -0
- data/lib/analyst/entities/string.rb +15 -2
- data/lib/analyst/entities/symbol.rb +15 -2
- data/lib/analyst/entities/{empty.rb → unhandled.rb} +3 -1
- data/lib/analyst/parser.rb +33 -30
- data/lib/analyst/processor.rb +25 -0
- data/lib/analyst/version.rb +1 -1
- data/lib/analyst.rb +18 -29
- data/spec/class_spec.rb +1 -1
- data/spec/constant_spec.rb +26 -0
- data/spec/entity_spec.rb +118 -0
- data/spec/fixtures/music.rb +19 -3
- data/spec/parser_spec.rb +3 -2
- data/spec/spec_helper.rb +3 -0
- metadata +39 -30
- data/lib/analyst/analyzer.rb +0 -162
- data/lib/analyst/entities/begin.rb +0 -13
data/lib/analyst/analyzer.rb
DELETED
@@ -1,162 +0,0 @@
|
|
1
|
-
require 'parser/current'
|
2
|
-
|
3
|
-
class Analyzer
|
4
|
-
|
5
|
-
CONDITIONALS = [:if, :or_asgn, :and_asgn, :or, :and]
|
6
|
-
|
7
|
-
attr_accessor :content, :class_name, :edges, :nodes, :exits
|
8
|
-
|
9
|
-
DEFAULT_CLASS_NAME = "Unknown"
|
10
|
-
|
11
|
-
def initialize(content)
|
12
|
-
self.content = content
|
13
|
-
self.edges = 0
|
14
|
-
self.nodes = 1
|
15
|
-
self.exits = 1
|
16
|
-
end
|
17
|
-
|
18
|
-
def complexity
|
19
|
-
return unless traverse(parsed)
|
20
|
-
self.edges - self.nodes + exits
|
21
|
-
end
|
22
|
-
|
23
|
-
def class_name
|
24
|
-
find_class(parsed) || DEFAULT_CLASS_NAME
|
25
|
-
end
|
26
|
-
|
27
|
-
def methods
|
28
|
-
@methods ||= methods_from(parsed)
|
29
|
-
end
|
30
|
-
|
31
|
-
def constants
|
32
|
-
@constants ||= constants_from(parsed)
|
33
|
-
end
|
34
|
-
|
35
|
-
def method_names
|
36
|
-
@method_names ||= method_names_from(parsed)
|
37
|
-
end
|
38
|
-
|
39
|
-
def extract_methods
|
40
|
-
@methods ||= methods_from(parsed)
|
41
|
-
end
|
42
|
-
|
43
|
-
def extract_class_name
|
44
|
-
return self.class_name if self.class_name && ! self.class_name.empty?
|
45
|
-
found = find_class(parsed)
|
46
|
-
self.class_name = ! found.empty? && found || DEFAULT_CLASS_NAME
|
47
|
-
end
|
48
|
-
|
49
|
-
private
|
50
|
-
|
51
|
-
def method_list
|
52
|
-
@method_list ||= method_names
|
53
|
-
end
|
54
|
-
|
55
|
-
def method_names_from(node, found=[])
|
56
|
-
return found unless node.respond_to?(:type)
|
57
|
-
if node.type == :def || node.type == :defs
|
58
|
-
name = node.loc.name
|
59
|
-
found << content[name.begin_pos..name.end_pos - 1].to_sym
|
60
|
-
end
|
61
|
-
node.children.each do |child|
|
62
|
-
method_names_from(child, found) if parent_node?(child)
|
63
|
-
end
|
64
|
-
found
|
65
|
-
end
|
66
|
-
|
67
|
-
def constants_from(node, found=[])
|
68
|
-
if node.type == :const
|
69
|
-
expression = node.loc.expression
|
70
|
-
found << content[expression.begin_pos..expression.end_pos - 1]
|
71
|
-
end
|
72
|
-
node.children.each do |child|
|
73
|
-
constants_from(child, found) if parent_node?(child)
|
74
|
-
end
|
75
|
-
found.reject{ |constant| constant == class_name }
|
76
|
-
end
|
77
|
-
|
78
|
-
def extract_references_from(node, found=[])
|
79
|
-
return found unless node && node.respond_to?(:type)
|
80
|
-
if node.type == :send
|
81
|
-
reference = node.loc.expression
|
82
|
-
found << node.children.last
|
83
|
-
end
|
84
|
-
node.children.each do |child|
|
85
|
-
extract_references_from(child, found)
|
86
|
-
end
|
87
|
-
found.select{|name| method_list.include?(name)}
|
88
|
-
end
|
89
|
-
|
90
|
-
def text_at(start_pos, end_pos)
|
91
|
-
content[start_pos..end_pos - 1]
|
92
|
-
end
|
93
|
-
|
94
|
-
def find_class(node)
|
95
|
-
return unless node && node.respond_to?(:type)
|
96
|
-
concat = []
|
97
|
-
if node.type == :module || node.type == :class
|
98
|
-
concat << text_at(node.loc.name.begin_pos, node.loc.name.end_pos)
|
99
|
-
end
|
100
|
-
concat << node.children.map{|child| find_class(child)}.compact
|
101
|
-
concat.flatten.select(&:present?).join('::')
|
102
|
-
end
|
103
|
-
|
104
|
-
def extend_graph
|
105
|
-
self.edges += 2
|
106
|
-
self.nodes += 2
|
107
|
-
self.exits += 1
|
108
|
-
end
|
109
|
-
|
110
|
-
def methods_from(node, methods=[])
|
111
|
-
if node.type == :def || node.type == :defs
|
112
|
-
name = node.loc.name
|
113
|
-
expression = node.loc.expression
|
114
|
-
type = case(node.type)
|
115
|
-
when :defs
|
116
|
-
:class
|
117
|
-
when :def
|
118
|
-
:instance
|
119
|
-
when :class
|
120
|
-
:none
|
121
|
-
end
|
122
|
-
methods << ParsedMethod.new(
|
123
|
-
name: content[name.begin_pos..name.end_pos - 1],
|
124
|
-
content: content[expression.begin_pos..expression.end_pos - 1],
|
125
|
-
type: type,
|
126
|
-
refs: extract_references_from(node)
|
127
|
-
)
|
128
|
-
end
|
129
|
-
node.children.each do |child|
|
130
|
-
if parent_node?(child)
|
131
|
-
methods_from(child, methods)
|
132
|
-
end
|
133
|
-
end
|
134
|
-
methods.reject{ |m| m.name.empty? }
|
135
|
-
end
|
136
|
-
|
137
|
-
def parent_node?(node)
|
138
|
-
node.respond_to?(:type) || node.respond_to?(:children)
|
139
|
-
end
|
140
|
-
|
141
|
-
def parse!
|
142
|
-
traverse(parsed) && complexity
|
143
|
-
end
|
144
|
-
|
145
|
-
def parsed
|
146
|
-
@parsed ||= Parser::CurrentRuby.parse(content)
|
147
|
-
end
|
148
|
-
|
149
|
-
def traverse(node, accumulator=[], extract_methods=false)
|
150
|
-
accumulator << node.type
|
151
|
-
extend_graph if CONDITIONALS.include?(node.type)
|
152
|
-
node.children.each do |child|
|
153
|
-
if parent_node?(child)
|
154
|
-
accumulator << child.type
|
155
|
-
traverse(child, accumulator)
|
156
|
-
end
|
157
|
-
end
|
158
|
-
accumulator
|
159
|
-
end
|
160
|
-
|
161
|
-
end
|
162
|
-
|