flay 1.3.0 → 1.4.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.
- 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
|