ruby_codex 0.0.3 → 0.0.4a
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/lib/ruby_codex.rb +65 -38
- metadata +8 -7
- checksums.yaml +0 -15
data/lib/ruby_codex.rb
CHANGED
@@ -2,10 +2,10 @@ load 'data_node.rb'
|
|
2
2
|
|
3
3
|
class Codex
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
def initialize(db,agg_db)
|
5
|
+
attr_reader :nodes
|
8
6
|
|
7
|
+
def initialize(db,agg_db)
|
8
|
+
@nodes = {}
|
9
9
|
# helper procs
|
10
10
|
info = Proc.new do |node|
|
11
11
|
normal_node(node) do |n, norm|
|
@@ -52,7 +52,7 @@ class Codex
|
|
52
52
|
:func_info => Proc.new { |v| v.first[:func_info] }
|
53
53
|
}
|
54
54
|
|
55
|
-
@block = DataNode.new(
|
55
|
+
@nodes[:block] = DataNode.new(
|
56
56
|
db, agg_db,
|
57
57
|
Proc.new { |x| x.type == :block},
|
58
58
|
key.merge({
|
@@ -83,18 +83,17 @@ class Codex
|
|
83
83
|
query_count = query.nil? ? 0 : query.count
|
84
84
|
blocks = db.where(:type => keys[:type], :func => keys[:func]).sum(:count)
|
85
85
|
rets = db.where(:type => keys[:type], :ret_val => keys[:ret_val]).sum(:count)
|
86
|
-
|
87
|
-
|
88
|
-
:
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
end
|
86
|
+
{ :keys => keys,
|
87
|
+
:message =>
|
88
|
+
"We've seen #{keys[:func]} blocks returning the #{keys[:ret_val]} type #{query_count.to_s} " +
|
89
|
+
"times, and we've seen #{keys[:func]} blocks #{blocks.to_s} times and #{keys[:ret_val]} " +
|
90
|
+
"returned #{rets.to_s} times.",
|
91
|
+
:unlikely => Proc.new { |gt=1,bt = 0,rt = 0| query_count < gt && blocks > bt && rets > rt}
|
92
|
+
}
|
94
93
|
}
|
95
94
|
)
|
96
95
|
|
97
|
-
@func = DataNode.new(
|
96
|
+
@nodes[:func] = DataNode.new(
|
98
97
|
db, agg_db,
|
99
98
|
Proc.new { |x| x.type == :send},
|
100
99
|
key.merge({
|
@@ -111,13 +110,14 @@ class Codex
|
|
111
110
|
alt_count = func.nil? ? 0 : func.count
|
112
111
|
{ :keys => keys,
|
113
112
|
:message =>
|
114
|
-
"Function call #{keys[:norm_code]} has appeared #{query_count.to_s} times,
|
115
|
-
"#{func.norm_code} has appeared #{alt_count.to_s} times."
|
116
|
-
|
113
|
+
"Function call #{keys[:norm_code]} has appeared #{query_count.to_s} times, and the most " +
|
114
|
+
"common alternative #{func.norm_code} has appeared #{alt_count.to_s} times.",
|
115
|
+
:unlikely => Proc.new { |t=10| alt_count > t * (query_count + 1)}
|
116
|
+
}
|
117
117
|
}
|
118
118
|
)
|
119
119
|
|
120
|
-
@func_chain =
|
120
|
+
@nodes[:func_chain] = DataNode.new(
|
121
121
|
db, agg_db,
|
122
122
|
Proc.new { |x| x.type == :send && type.call(x.children.first) == "send" },
|
123
123
|
key.merge({
|
@@ -132,19 +132,19 @@ class Codex
|
|
132
132
|
combine,
|
133
133
|
Proc.new do |db,keys,data|
|
134
134
|
query = db.where(keys).first
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
135
|
+
query_count = query.nil? ? 0 : query.count
|
136
|
+
fs = [:f1,:f2].map { |f| db.where(:type => "send", :func => keys[f]).size }
|
137
|
+
{ :keys => keys,
|
138
|
+
:message =>
|
139
|
+
"Function #{keys[:f1]} has appeared #{fs[0].to_s} times " +
|
140
|
+
"and #{keys[:f2]} has appeared #{fs[1].to_s} times, and " +
|
141
|
+
"they've appeared #{query_count} times together.",
|
142
|
+
:unlikely => Proc.new { |gt=1, t=10| query_count < gt && fs[0] > t && fs[1] > t }
|
143
|
+
}
|
144
144
|
end
|
145
145
|
)
|
146
146
|
|
147
|
-
@cond = DataNode.new(
|
147
|
+
@nodes[:cond] = DataNode.new(
|
148
148
|
db, agg_db,
|
149
149
|
Proc.new { |x| x.type == :if },
|
150
150
|
key.merge({
|
@@ -157,7 +157,7 @@ class Codex
|
|
157
157
|
combine
|
158
158
|
)
|
159
159
|
|
160
|
-
@ident = DataNode.new(
|
160
|
+
@nodes[:ident] = DataNode.new(
|
161
161
|
db, agg_db,
|
162
162
|
Proc.new { |x| [:lvasgn, :ivasgn, :cvasgn, :gvasgn].include?(x.type) },
|
163
163
|
key.merge({
|
@@ -177,21 +177,48 @@ class Codex
|
|
177
177
|
if query
|
178
178
|
types = query.ident_types.select { |k,v| ["str","int","float","array","hash"].include? k }
|
179
179
|
types.default = 0
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
:
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
end
|
180
|
+
best = types.select { |k,v| k != data[:ident_type] }.sort_by{ |k,v| v*-1 }.first
|
181
|
+
{ :keys => keys,
|
182
|
+
:message =>
|
183
|
+
"The identifier #{keys[:ident]} has appeared #{types[data[:ident_type]].to_s} " +
|
184
|
+
"times as #{data[:ident_type].to_s} and #{best[1].to_s} times as #{best[0].to_s}",
|
185
|
+
:unlikely => Proc.new { |t=5| best[1] > t * (types[keys[:ident_type]] + 1) }
|
186
|
+
}
|
187
|
+
else
|
188
|
+
{ :message => "Never Seen", :unlikely => Proc.new { false } }
|
190
189
|
end
|
191
190
|
}
|
192
191
|
)
|
193
192
|
end
|
194
193
|
|
194
|
+
def add_ast(ast, file, project, &block)
|
195
|
+
@nodes.each do |k,v|
|
196
|
+
v.add_ast(ast, file, project, &block)
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
def save_all!
|
201
|
+
@nodes.each do |k,v|
|
202
|
+
v.save!
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
def query(ast)
|
207
|
+
@nodes.each do |k,v|
|
208
|
+
yield k, v.query(ast)
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
def is_unlikely(ast, options = Hash.new([]))
|
213
|
+
unlikely = []
|
214
|
+
query(ast) do |k, message|
|
215
|
+
if message && message[:unlikely].call(*options[k])
|
216
|
+
unlikely.push(message)
|
217
|
+
end
|
218
|
+
end
|
219
|
+
unlikely
|
220
|
+
end
|
221
|
+
|
195
222
|
def without_caller(node)
|
196
223
|
node.updated(nil, node.children.map.with_index do |x,i|
|
197
224
|
i == 0 ? nil : x
|
metadata
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby_codex
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4a
|
5
|
+
prerelease: 5
|
5
6
|
platform: ruby
|
6
7
|
authors:
|
7
8
|
- Ethan Fast
|
@@ -22,26 +23,26 @@ files:
|
|
22
23
|
homepage: http://rubygems.org/gems/ruby-codex
|
23
24
|
licenses:
|
24
25
|
- MIT
|
25
|
-
metadata: {}
|
26
26
|
post_install_message:
|
27
27
|
rdoc_options: []
|
28
28
|
require_paths:
|
29
29
|
- lib
|
30
30
|
required_ruby_version: !ruby/object:Gem::Requirement
|
31
|
+
none: false
|
31
32
|
requirements:
|
32
33
|
- - ! '>='
|
33
34
|
- !ruby/object:Gem::Version
|
34
35
|
version: '0'
|
35
36
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
37
|
+
none: false
|
36
38
|
requirements:
|
37
|
-
- - ! '
|
39
|
+
- - ! '>'
|
38
40
|
- !ruby/object:Gem::Version
|
39
|
-
version:
|
41
|
+
version: 1.3.1
|
40
42
|
requirements: []
|
41
43
|
rubyforge_project:
|
42
|
-
rubygems_version:
|
44
|
+
rubygems_version: 1.8.25
|
43
45
|
signing_key:
|
44
|
-
specification_version:
|
46
|
+
specification_version: 3
|
45
47
|
summary: Analyze ruby ASTs with Codex
|
46
48
|
test_files: []
|
47
|
-
has_rdoc:
|
checksums.yaml
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
---
|
2
|
-
!binary "U0hBMQ==":
|
3
|
-
metadata.gz: !binary |-
|
4
|
-
MmQ3MDg3YzBkZjZmMmM5ZmI2ODEyMTMxYWI0MWU4MGI3N2VmMDBjMQ==
|
5
|
-
data.tar.gz: !binary |-
|
6
|
-
ZjEzZThiNmI4M2RjYjM5MGUwZmQzYzAzOWI0MjNmODRmN2Y0YzZiYQ==
|
7
|
-
!binary "U0hBNTEy":
|
8
|
-
metadata.gz: !binary |-
|
9
|
-
MWJjZTliOTQzMzU3NDM3OTRlYjI0OGRiMzMyZjA5YWM5MjBmYWMyMDcxNDI3
|
10
|
-
ZWM3OWE5ODhjZTU2YTBiNjlmMzI1YzQzMTMwODZlMTk3ZjljYzAyYzA2ZDQx
|
11
|
-
ZjUzMzNhZjk0ZjI0YjFiOGFmMWYzYTNkZTE4NmYzMzI0Y2E1MzE=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
NWQwMTBjNmY3NjAwZTNiOWYyNDliYmE3YjM4MWE4MDk2YmI2N2IxYTk1ZTE0
|
14
|
-
NzA1YzZhNjQwYjBiMzI4MmE1NTViODg0YWJkMTA3NTBlODFiMzAzZjc2ZDA4
|
15
|
-
Y2VlYzFiNDdhYmFkN2E3YzdmNDMzZmQxZThlMjFiNTA1ZDk4ODk=
|