flay 1.3.0 → 1.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +9 -0
- data/lib/flay.rb +7 -72
- data/test/test_flay.rb +10 -46
- metadata +5 -26
- data.tar.gz.sig +0 -2
- metadata.gz.sig +0 -0
data/History.txt
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
=== 1.4.0 / 2009-08-14
|
2
|
+
|
3
|
+
* 4 minor enhancements:
|
4
|
+
|
5
|
+
* Pushed Sexp#mass up to sexp_processor.
|
6
|
+
* Removed #similarity #compare_to, #intersection, #triangle, and other cruft.
|
7
|
+
* Renamed all_subhashes to all_structural_subhashes.
|
8
|
+
* Renamed fuzzy_hash to structural_hash.
|
9
|
+
|
1
10
|
=== 1.3.0 / 2009-06-23
|
2
11
|
|
3
12
|
* 5 minor enhancements:
|
data/lib/flay.rb
CHANGED
@@ -9,7 +9,7 @@ require 'sexp_processor'
|
|
9
9
|
require 'ruby_parser'
|
10
10
|
|
11
11
|
class Flay
|
12
|
-
VERSION = '1.
|
12
|
+
VERSION = '1.4.0'
|
13
13
|
|
14
14
|
def self.default_options
|
15
15
|
{
|
@@ -170,7 +170,7 @@ class Flay
|
|
170
170
|
next unless node.any? { |sub| Sexp === sub }
|
171
171
|
next if node.mass < self.mass_threshold
|
172
172
|
|
173
|
-
self.hashes[node.
|
173
|
+
self.hashes[node.structural_hash] << node
|
174
174
|
end
|
175
175
|
end
|
176
176
|
|
@@ -182,7 +182,7 @@ class Flay
|
|
182
182
|
all_hashes = {}
|
183
183
|
self.hashes.values.each do |nodes|
|
184
184
|
nodes.each do |node|
|
185
|
-
node.
|
185
|
+
node.all_structural_subhashes.each do |h|
|
186
186
|
all_hashes[h] = true
|
187
187
|
end
|
188
188
|
end
|
@@ -292,50 +292,14 @@ class String
|
|
292
292
|
end
|
293
293
|
|
294
294
|
class Sexp
|
295
|
-
def
|
296
|
-
@
|
295
|
+
def structural_hash
|
296
|
+
@structural_hash ||= self.structure.hash
|
297
297
|
end
|
298
298
|
|
299
|
-
|
300
|
-
def structure
|
301
|
-
@structure ||= self.uncached_structure
|
302
|
-
end
|
303
|
-
|
304
|
-
def similarity o
|
305
|
-
l, s, r = self.compare_to o
|
306
|
-
(2.0 * s) / (2.0 * s + l + r)
|
307
|
-
end
|
308
|
-
|
309
|
-
def compare_to they
|
310
|
-
l = s = r = 0
|
311
|
-
|
312
|
-
l_sexp, l_lits = self.partition { |o| Sexp === o }
|
313
|
-
r_sexp, r_lits = they.partition { |o| Sexp === o }
|
314
|
-
|
315
|
-
l += (l_lits - r_lits).size
|
316
|
-
s += (l_lits & r_lits).size
|
317
|
-
r += (r_lits - l_lits).size
|
318
|
-
|
319
|
-
# TODO: I think this is wrong, since it isn't positional. What to do?
|
320
|
-
l_sexp.zip(r_sexp).each do |l_sub, r_sub|
|
321
|
-
next unless l_sub && r_sub # HACK
|
322
|
-
l2, s2, r2 = l_sub.compare_to r_sub
|
323
|
-
l += l2
|
324
|
-
s += s2
|
325
|
-
r += r2
|
326
|
-
end
|
327
|
-
|
328
|
-
return l, s, r
|
329
|
-
end
|
330
|
-
|
331
|
-
def fuzzy_hash
|
332
|
-
@fuzzy_hash ||= self.structure.hash
|
333
|
-
end
|
334
|
-
|
335
|
-
def all_subhashes
|
299
|
+
def all_structural_subhashes
|
336
300
|
hashes = []
|
337
301
|
self.deep_each do |node|
|
338
|
-
hashes << node.
|
302
|
+
hashes << node.structural_hash
|
339
303
|
end
|
340
304
|
hashes
|
341
305
|
end
|
@@ -355,32 +319,3 @@ class Sexp
|
|
355
319
|
end
|
356
320
|
end
|
357
321
|
end
|
358
|
-
|
359
|
-
class Array
|
360
|
-
def intersection other
|
361
|
-
intersection, start = [], 0
|
362
|
-
other_size = other.length
|
363
|
-
self.each_with_index do |m, i|
|
364
|
-
(start...other_size).each do |j|
|
365
|
-
n = other.at j
|
366
|
-
if m == n then
|
367
|
-
intersection << m
|
368
|
-
start = j + 1
|
369
|
-
break
|
370
|
-
end
|
371
|
-
end
|
372
|
-
end
|
373
|
-
intersection
|
374
|
-
end
|
375
|
-
|
376
|
-
def triangle # TODO: use?
|
377
|
-
max = self.size
|
378
|
-
(0...max).each do |i|
|
379
|
-
o1 = at(i)
|
380
|
-
(i+1...max).each do |j|
|
381
|
-
o2 = at(j)
|
382
|
-
yield o1, o2
|
383
|
-
end
|
384
|
-
end
|
385
|
-
end
|
386
|
-
end
|
data/test/test_flay.rb
CHANGED
@@ -3,6 +3,8 @@
|
|
3
3
|
require 'test/unit'
|
4
4
|
require 'flay'
|
5
5
|
|
6
|
+
$: << "../../sexp_processor/dev/lib"
|
7
|
+
|
6
8
|
require 'pp' # TODO: remove
|
7
9
|
|
8
10
|
ON_1_9 = RUBY_VERSION =~ /1\.9/
|
@@ -28,36 +30,7 @@ class TestSexp < Test::Unit::TestCase
|
|
28
30
|
s(:call, nil, :d, s(:arglist)))
|
29
31
|
end
|
30
32
|
|
31
|
-
def
|
32
|
-
assert_equal 1, s(:a).mass
|
33
|
-
assert_equal 3, s(:a, s(:b), s(:c)).mass
|
34
|
-
assert_equal 7, @s.mass
|
35
|
-
end
|
36
|
-
|
37
|
-
def test_compare_to
|
38
|
-
s1 = s(:a, :b, :c)
|
39
|
-
s2 = s(:d, :e, :f)
|
40
|
-
assert_equal [3, 0, 3], s1.compare_to(s2), "100% different"
|
41
|
-
|
42
|
-
s1 = s(:a, :b, :c)
|
43
|
-
s2 = s(:a, :b, :c)
|
44
|
-
assert_equal [0, 3, 0], s1.compare_to(s2), "100% same"
|
45
|
-
|
46
|
-
s1 = s(:a, :b, :c, :d)
|
47
|
-
s2 = s(:a, :b, :c, :e)
|
48
|
-
assert_equal [1, 3, 1], s1.compare_to(s2), "1 element different on each"
|
49
|
-
|
50
|
-
s1 = s(:a, :d, :b, :c)
|
51
|
-
s2 = s(:a, :b, :c, :e)
|
52
|
-
assert_equal [1, 3, 1], s1.compare_to(s2), "positionally different"
|
53
|
-
|
54
|
-
|
55
|
-
s1 = s(:a, s(:d), :b, :c)
|
56
|
-
s2 = s(:a, :b, :c, s(:e))
|
57
|
-
assert_equal [1, 3, 1], s1.compare_to(s2), "simple subtree difference"
|
58
|
-
end
|
59
|
-
|
60
|
-
def test_fuzzy_hash
|
33
|
+
def test_structural_hash
|
61
34
|
s = s(:iter,
|
62
35
|
s(:call, nil, :a, s(:arglist, s(:lit, 1))),
|
63
36
|
s(:lasgn, :c),
|
@@ -65,22 +38,22 @@ class TestSexp < Test::Unit::TestCase
|
|
65
38
|
|
66
39
|
hash = 955256285
|
67
40
|
|
68
|
-
assert_equal hash, s.
|
69
|
-
assert_equal hash, @s.
|
70
|
-
assert_equal hash, @s.deep_clone.
|
71
|
-
assert_equal hash, s.deep_clone.
|
41
|
+
assert_equal hash, s.structural_hash, "hand copy"
|
42
|
+
assert_equal hash, @s.structural_hash, "ivar from setup"
|
43
|
+
assert_equal hash, @s.deep_clone.structural_hash, "deep clone"
|
44
|
+
assert_equal hash, s.deep_clone.structural_hash, "copy deep clone"
|
72
45
|
end unless SKIP_1_9
|
73
46
|
|
74
|
-
def
|
47
|
+
def test_all_structural_subhashes
|
75
48
|
expected = [-704571402, -282578980, -35395725,
|
76
49
|
160138040, 815971090, 927228382]
|
77
50
|
|
78
|
-
assert_equal expected, @s.
|
51
|
+
assert_equal expected, @s.all_structural_subhashes.sort.uniq
|
79
52
|
|
80
53
|
x = []
|
81
54
|
|
82
55
|
@s.deep_each do |o|
|
83
|
-
x << o.
|
56
|
+
x << o.structural_hash
|
84
57
|
end
|
85
58
|
|
86
59
|
assert_equal expected, x.sort.uniq
|
@@ -146,12 +119,3 @@ class TestSexp < Test::Unit::TestCase
|
|
146
119
|
assert flay.hashes.empty?
|
147
120
|
end
|
148
121
|
end
|
149
|
-
|
150
|
-
class ArrayIntersectionTests < Test::Unit::TestCase
|
151
|
-
def test_real_array_intersection
|
152
|
-
assert_equal [2], [2, 2, 2, 3, 7, 13, 49] & [2, 2, 2, 5, 11, 107]
|
153
|
-
assert_equal [2, 2, 2], [2, 2, 2, 3, 7, 13, 49].intersection([2, 2, 2, 5, 11, 107])
|
154
|
-
assert_equal ['a', 'c'], ['a', 'b', 'a', 'c'] & ['a', 'c', 'a', 'd']
|
155
|
-
assert_equal ['a', 'a'], ['a', 'b', 'a', 'c'].intersection(['a', 'c', 'a', 'd'])
|
156
|
-
end
|
157
|
-
end
|
metadata
CHANGED
@@ -1,36 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: flay
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryan Davis
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
|
-
cert_chain:
|
11
|
-
- |
|
12
|
-
-----BEGIN CERTIFICATE-----
|
13
|
-
MIIDPjCCAiagAwIBAgIBADANBgkqhkiG9w0BAQUFADBFMRMwEQYDVQQDDApyeWFu
|
14
|
-
ZC1ydWJ5MRkwFwYKCZImiZPyLGQBGRYJemVuc3BpZGVyMRMwEQYKCZImiZPyLGQB
|
15
|
-
GRYDY29tMB4XDTA5MDMwNjE4NTMxNVoXDTEwMDMwNjE4NTMxNVowRTETMBEGA1UE
|
16
|
-
AwwKcnlhbmQtcnVieTEZMBcGCgmSJomT8ixkARkWCXplbnNwaWRlcjETMBEGCgmS
|
17
|
-
JomT8ixkARkWA2NvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALda
|
18
|
-
b9DCgK+627gPJkB6XfjZ1itoOQvpqH1EXScSaba9/S2VF22VYQbXU1xQXL/WzCkx
|
19
|
-
taCPaLmfYIaFcHHCSY4hYDJijRQkLxPeB3xbOfzfLoBDbjvx5JxgJxUjmGa7xhcT
|
20
|
-
oOvjtt5P8+GSK9zLzxQP0gVLS/D0FmoE44XuDr3iQkVS2ujU5zZL84mMNqNB1znh
|
21
|
-
GiadM9GHRaDiaxuX0cIUBj19T01mVE2iymf9I6bEsiayK/n6QujtyCbTWsAS9Rqt
|
22
|
-
qhtV7HJxNKuPj/JFH0D2cswvzznE/a5FOYO68g+YCuFi5L8wZuuM8zzdwjrWHqSV
|
23
|
-
gBEfoTEGr7Zii72cx+sCAwEAAaM5MDcwCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAw
|
24
|
-
HQYDVR0OBBYEFEfFe9md/r/tj/Wmwpy+MI8d9k/hMA0GCSqGSIb3DQEBBQUAA4IB
|
25
|
-
AQAY59gYvDxqSqgC92nAP9P8dnGgfZgLxP237xS6XxFGJSghdz/nI6pusfCWKM8m
|
26
|
-
vzjjH2wUMSSf3tNudQ3rCGLf2epkcU13/rguI88wO6MrE0wi4ZqLQX+eZQFskJb/
|
27
|
-
w6x9W1ur8eR01s397LSMexySDBrJOh34cm2AlfKr/jokKCTwcM0OvVZnAutaovC0
|
28
|
-
l1SVZ0ecg88bsWHA0Yhh7NFxK1utWoIhtB6AFC/+trM0FQEB/jZkIS8SaNzn96Rl
|
29
|
-
n0sZEf77FLf5peR8TP/PtmIg7Cyqz23sLM4mCOoTGIy5OcZ8TdyiyINUHtb5ej/T
|
30
|
-
FBHgymkyj/AOSqKRIpXPhjC6
|
31
|
-
-----END CERTIFICATE-----
|
10
|
+
cert_chain: []
|
32
11
|
|
33
|
-
date: 2009-
|
12
|
+
date: 2009-08-14 00:00:00 -07:00
|
34
13
|
default_executable:
|
35
14
|
dependencies:
|
36
15
|
- !ruby/object:Gem::Dependency
|
@@ -61,7 +40,7 @@ dependencies:
|
|
61
40
|
requirements:
|
62
41
|
- - ">="
|
63
42
|
- !ruby/object:Gem::Version
|
64
|
-
version: 2.3.
|
43
|
+
version: 2.3.3
|
65
44
|
version:
|
66
45
|
description: |-
|
67
46
|
Flay analyzes code for structural similarities. Differences in literal
|
@@ -113,7 +92,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
113
92
|
requirements: []
|
114
93
|
|
115
94
|
rubyforge_project: seattlerb
|
116
|
-
rubygems_version: 1.3.
|
95
|
+
rubygems_version: 1.3.5
|
117
96
|
signing_key:
|
118
97
|
specification_version: 3
|
119
98
|
summary: Flay analyzes code for structural similarities
|
data.tar.gz.sig
DELETED
metadata.gz.sig
DELETED
Binary file
|