ruby_codex 0.0.6 → 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/ruby_codex.rb +54 -38
- metadata +1 -1
data/lib/ruby_codex.rb
CHANGED
@@ -28,15 +28,15 @@ class Codex
|
|
28
28
|
end
|
29
29
|
|
30
30
|
key = {
|
31
|
-
:type => type
|
31
|
+
:type => type,
|
32
|
+
:info => info,
|
33
|
+
:func_info => func_info
|
32
34
|
}
|
33
35
|
|
34
36
|
data_core = {
|
35
37
|
:file => Proc.new { |node, f, p| f },
|
36
38
|
:project => Proc.new { |node, f, p| p },
|
37
39
|
:line => Proc.new { |node, f, p| node.loc ? node.loc.line : nil },
|
38
|
-
:info => info,
|
39
|
-
:func_info => func_info,
|
40
40
|
:orig_code => Proc.new { |node, f, p| Unparser.unparse(node) rescue nil },
|
41
41
|
}
|
42
42
|
|
@@ -49,8 +49,6 @@ class Codex
|
|
49
49
|
{:code => x[:orig_code], :file => x[:file], :line => x[:line]}
|
50
50
|
end.uniq },
|
51
51
|
:count => Proc.new { |v| v.map { |x| x[:orig_code] }.count },
|
52
|
-
:info => Proc.new { |v| v.first[:info] }, # some process may overwrite
|
53
|
-
:func_info => Proc.new { |v| v.first[:func_info] }
|
54
52
|
}
|
55
53
|
|
56
54
|
@nodes[:block] = DataNode.new(
|
@@ -60,18 +58,17 @@ class Codex
|
|
60
58
|
:func => Proc.new { |x| func_name.call(x.children.first) },
|
61
59
|
:body => Proc.new { |x| normalize_nodes(x.children.last) },
|
62
60
|
:arg_size => Proc.new { |x| x.children[1].children.size },
|
61
|
+
:info => Proc.new { |x| info.call(block_without_caller(x)) },
|
62
|
+
:func_info => Proc.new { |x| func_info.call(block_without_caller(x)) },
|
63
63
|
:ret_val => Proc.new do |x|
|
64
64
|
body = x.children.last
|
65
65
|
ret = type.call(body) == "begin" ? body.children.last : body
|
66
66
|
typ = type.call(ret)
|
67
67
|
typ == "send" ? func_name.call(ret) : typ
|
68
68
|
end,
|
69
|
-
:norm_code => Proc.new
|
70
|
-
normal_node(x)
|
71
|
-
|
72
|
-
i == 0 ? without_caller(y) : y
|
73
|
-
end)) rescue nil
|
74
|
-
end }
|
69
|
+
:norm_code => Proc.new do |x|
|
70
|
+
normal_node(x) { |x| Unparser.unparse(block_without_caller(x)) rescue nil }
|
71
|
+
end
|
75
72
|
}),
|
76
73
|
data_core.merge({
|
77
74
|
:args => Proc.new { |x| x.children[1].children.map{ |y| y.children[0].to_s }}
|
@@ -89,7 +86,7 @@ class Codex
|
|
89
86
|
"We've seen #{keys[:func]} blocks returning the #{keys[:ret_val]} type #{query_count.to_s} " +
|
90
87
|
"times, and we've seen #{keys[:func]} blocks #{blocks.to_s} times and #{keys[:ret_val]} " +
|
91
88
|
"returned #{rets.to_s} times.",
|
92
|
-
:unlikely => Proc.new { |gt=1,bt =
|
89
|
+
:unlikely => Proc.new { |gt=1,bt = 5,rt = 5| query_count < gt && blocks > bt && rets > rt}
|
93
90
|
}
|
94
91
|
}
|
95
92
|
)
|
@@ -100,28 +97,34 @@ class Codex
|
|
100
97
|
key.merge({
|
101
98
|
:func => Proc.new { |x| func_name.call(x) },
|
102
99
|
:norm_code => Proc.new { |x| normal_node(x) { |x| Unparser.unparse(without_caller(x)) rescue nil } },
|
103
|
-
:sig => Proc.new { |x| x.children.drop(2).map { |y| type.call(y) } }
|
100
|
+
:sig => Proc.new { |x| x.children.drop(2).map { |y| type.call(y) } },
|
101
|
+
:info => Proc.new { |x| info.call(without_caller(x)) },
|
102
|
+
:func_info => Proc.new { |x| func_info.call(without_caller(x)) }
|
104
103
|
}),
|
105
104
|
data_core,
|
106
105
|
combine,
|
107
106
|
Proc.new { |db,keys,values|
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
:
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
107
|
+
if keys[:norm_code] != nil # Hack for binary operators that disappear
|
108
|
+
query = db.where(keys).first
|
109
|
+
query_count = query.nil? ? 0 : query.count
|
110
|
+
func = db.where(:type => keys[:type], :func => keys[:func]).sort(:count => -1).limit(1).first
|
111
|
+
alt_text =
|
112
|
+
if func
|
113
|
+
alt_count = func.count
|
114
|
+
"and the most common alternative #{func.norm_code} has appeared #{alt_count.to_s} times."
|
115
|
+
else
|
116
|
+
alt_count = 0
|
117
|
+
"and we've seen no known alternative."
|
118
|
+
end
|
119
|
+
{ :keys => keys,
|
120
|
+
:message =>
|
121
|
+
"Function call #{keys[:norm_code]} has appeared #{query_count.to_s} times, " +
|
122
|
+
alt_text,
|
123
|
+
:unlikely => Proc.new { |t=10| alt_count > t * (query_count + 1)}
|
124
|
+
}
|
125
|
+
else
|
126
|
+
{ :message => "Never Seen", :unlikely => Proc.new { false } }
|
127
|
+
end
|
125
128
|
}
|
126
129
|
)
|
127
130
|
|
@@ -131,12 +134,11 @@ class Codex
|
|
131
134
|
key.merge({
|
132
135
|
:type => Proc.new { "func_chain" },
|
133
136
|
:f1 => Proc.new { |x| func_name.call(x) },
|
134
|
-
:f2 => Proc.new { |x| func_name.call(x.children.first) }
|
135
|
-
}),
|
136
|
-
data_core.merge({
|
137
|
+
:f2 => Proc.new { |x| func_name.call(x.children.first) },
|
137
138
|
:info => Proc.new { 0 },
|
138
139
|
:func_info => Proc.new { 0 }
|
139
140
|
}),
|
141
|
+
data_core,
|
140
142
|
combine,
|
141
143
|
Proc.new do |db,keys,data|
|
142
144
|
query = db.where(keys).first
|
@@ -171,19 +173,20 @@ class Codex
|
|
171
173
|
key.merge({
|
172
174
|
:type => Proc.new { "ident" },
|
173
175
|
:ident => Proc.new { |x| x.children.first.to_s },
|
174
|
-
}),
|
175
|
-
data_core.merge({
|
176
|
-
:ident_type => Proc.new { |x| type.call(x.children[1]) rescue nil },
|
177
176
|
:info => Proc.new { 0 },
|
178
177
|
:func_info => Proc.new { 0 }
|
179
178
|
}),
|
179
|
+
data_core.merge({
|
180
|
+
:ident_type => Proc.new { |x| type.call(x.children[1]) rescue nil }
|
181
|
+
}),
|
180
182
|
combine.merge({
|
181
183
|
:ident_types => Proc.new { |v| v.group_by { |y| y[:ident_type] }.map_hash { |x| x.size } }
|
182
184
|
}),
|
183
185
|
Proc.new { |db, keys, data|
|
186
|
+
primatives = ["str","int","float","array","hash"]
|
184
187
|
query = db.where(keys).first
|
185
|
-
if query
|
186
|
-
types = query.ident_types.select { |k,v|
|
188
|
+
if query && primatives.include?(keys[:ident_type])
|
189
|
+
types = query.ident_types.select { |k,v| primatives.include? k }
|
187
190
|
types.default = 0
|
188
191
|
best = types.select { |k,v| k != data[:ident_type] }.sort_by{ |k,v| v*-1 }.first
|
189
192
|
best_str = best ? "#{best[1].to_s} times as #{best[0].to_s}" : "never as anything else."
|
@@ -228,11 +231,24 @@ class Codex
|
|
228
231
|
unlikely
|
229
232
|
end
|
230
233
|
|
234
|
+
def tree_walk(ast, &block)
|
235
|
+
if ast.is_a?(AST::Node)
|
236
|
+
yield ast if block
|
237
|
+
ast.children.each { |node| tree_walk(node, &block) }
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
231
241
|
def without_caller(node)
|
232
242
|
node.updated(nil, node.children.map.with_index do |x,i|
|
233
243
|
i == 0 ? nil : x
|
234
244
|
end)
|
235
245
|
end
|
246
|
+
|
247
|
+
def block_without_caller(node)
|
248
|
+
node.updated(nil, node.children.map.with_index do |y,i|
|
249
|
+
i == 0 ? without_caller(y) : y
|
250
|
+
end)
|
251
|
+
end
|
236
252
|
|
237
253
|
def normal_node(node)
|
238
254
|
norm = ASTNormalizer.new
|