flay 2.10.0 → 2.11.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/{History.txt → History.rdoc} +11 -0
- data/Manifest.txt +2 -2
- data/{README.txt → README.rdoc} +0 -0
- data/Rakefile +1 -0
- data/lib/flay.rb +10 -26
- data/test/test_flay.rb +175 -14
- metadata +18 -19
- metadata.gz.sig +3 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 8ba894eeca0c7966356ccb85f9252f47cf27e2ee34252288502cc70c50aa4d64
|
4
|
+
data.tar.gz: eb4552d71f43350ec698c3ef36a17d0b18b93c65e54666240af786952ed8e512
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 921301e4deb3c56b8eaf8fa1078ddb20f5bb9a3bf298ecea377df3440b8fc6e17f2475fbc31a1009b66042876289082bf61139bc982293c5530a51975966f793
|
7
|
+
data.tar.gz: 25e52c615125a7d06f59b41d1191dfca7c56a861d1c4a968f188dedd231b9d64fe84ab6c223526af10785e70b488600be4a4840754291b5408056cd9e11f7a82
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
@@ -1,3 +1,14 @@
|
|
1
|
+
=== 2.11.0 / 2018-04-05
|
2
|
+
|
3
|
+
* 2 minor enhancements:
|
4
|
+
|
5
|
+
* Added `filters` option to skip processing subtrees that match given patterns.
|
6
|
+
* Switched structural_hash to use crc32 to calculate node type values. Thanks to codeclimate.com!
|
7
|
+
|
8
|
+
* 1 bug fix:
|
9
|
+
|
10
|
+
* Merge options w/ defaults. Mostly to fix testing.
|
11
|
+
|
1
12
|
=== 2.10.0 / 2017-07-17
|
2
13
|
|
3
14
|
* 1 minor enhancement:
|
data/Manifest.txt
CHANGED
data/{README.txt → README.rdoc}
RENAMED
File without changes
|
data/Rakefile
CHANGED
data/lib/flay.rb
CHANGED
@@ -6,6 +6,7 @@ require "sexp_processor"
|
|
6
6
|
require "ruby_parser"
|
7
7
|
require "path_expander"
|
8
8
|
require "timeout"
|
9
|
+
require "zlib"
|
9
10
|
|
10
11
|
class File
|
11
12
|
RUBY19 = "<3".respond_to? :encoding unless defined? RUBY19 # :nodoc:
|
@@ -16,7 +17,7 @@ class File
|
|
16
17
|
end
|
17
18
|
|
18
19
|
class Flay
|
19
|
-
VERSION = "2.
|
20
|
+
VERSION = "2.11.0" # :nodoc:
|
20
21
|
|
21
22
|
class Item < Struct.new(:structural_hash, :name, :bonus, :mass, :locations)
|
22
23
|
alias identical? bonus
|
@@ -51,7 +52,8 @@ class Flay
|
|
51
52
|
:timeout => 10,
|
52
53
|
:liberal => false,
|
53
54
|
:fuzzy => false,
|
54
|
-
:only
|
55
|
+
:only => nil,
|
56
|
+
:filters => [],
|
55
57
|
}
|
56
58
|
end
|
57
59
|
|
@@ -169,8 +171,8 @@ class Flay
|
|
169
171
|
##
|
170
172
|
# Create a new instance of Flay with +option+s.
|
171
173
|
|
172
|
-
def initialize option =
|
173
|
-
@option =
|
174
|
+
def initialize option = {}
|
175
|
+
@option = Flay.default_options.merge option
|
174
176
|
@hashes = Hash.new { |h,k| h[k] = [] }
|
175
177
|
|
176
178
|
self.identical = {}
|
@@ -283,8 +285,9 @@ class Flay
|
|
283
285
|
|
284
286
|
def process_sexp pt
|
285
287
|
pt.deep_each do |node|
|
286
|
-
next
|
287
|
-
next if node.mass < self.mass_threshold
|
288
|
+
next :skip if node.none? { |sub| Sexp === sub }
|
289
|
+
next :skip if node.mass < self.mass_threshold
|
290
|
+
next :skip if option[:filters].any? { |pattern| pattern.satisfy? node }
|
288
291
|
|
289
292
|
self.hashes[node.structural_hash] << node
|
290
293
|
|
@@ -632,26 +635,7 @@ class Sexp
|
|
632
635
|
end
|
633
636
|
|
634
637
|
class Sexp # straight from flay-persistent
|
635
|
-
|
636
|
-
begin block block_pass break call case cdecl class colon2
|
637
|
-
colon3 const cvar cvasgn cvdecl defined defn defs dot2
|
638
|
-
dot3 dregx dregx_once dstr dsym dxstr ensure evstr false
|
639
|
-
flip2 flip3 for gasgn gvar hash iasgn if iter ivar lasgn
|
640
|
-
lit lvar masgn match match2 match3 module next nil not
|
641
|
-
nth_ref op_asgn op_asgn1 op_asgn2 op_asgn_and op_asgn_or or
|
642
|
-
postexe redo resbody rescue retry return sclass self
|
643
|
-
splat str super svalue to_ary true undef until valias
|
644
|
-
when while xstr yield zsuper kwarg kwsplat safe_call)
|
645
|
-
|
646
|
-
##
|
647
|
-
# All ruby_parser nodes in an index hash. Used by jenkins algorithm.
|
648
|
-
|
649
|
-
NODE_NAMES = Hash[names.each_with_index.map {|n, i| [n.to_sym, i] }]
|
650
|
-
|
651
|
-
NODE_NAMES.default_proc = lambda { |h, k|
|
652
|
-
$stderr.puts "ERROR: couldn't find node type #{k} in Sexp::NODE_NAMES."
|
653
|
-
h[k] = NODE_NAMES.size
|
654
|
-
}
|
638
|
+
NODE_NAMES = Hash.new { |h,k| h[k] = Zlib.crc32(k.to_s) }
|
655
639
|
|
656
640
|
MAX_INT32 = 2 ** 32 - 1 # :nodoc:
|
657
641
|
|
data/test/test_flay.rb
CHANGED
@@ -19,7 +19,7 @@ class TestSexp < Minitest::Test
|
|
19
19
|
end
|
20
20
|
|
21
21
|
def test_structural_hash
|
22
|
-
hash =
|
22
|
+
hash = 3381710114
|
23
23
|
|
24
24
|
assert_equal hash, @s.deep_clone.structural_hash
|
25
25
|
assert_equal hash, @s.structural_hash
|
@@ -98,18 +98,7 @@ class TestSexp < Minitest::Test
|
|
98
98
|
end
|
99
99
|
RUBY
|
100
100
|
|
101
|
-
def register_node_types
|
102
|
-
# Register these node types to remove warnings in test
|
103
|
-
capture_io do
|
104
|
-
[:a, :b, :c, :d, :e].each do |s|
|
105
|
-
Sexp::NODE_NAMES[s]
|
106
|
-
end
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
101
|
def test_prune
|
111
|
-
register_node_types
|
112
|
-
|
113
102
|
contained = s(:a, s(:b,s(:c)), s(:d,s(:e)))
|
114
103
|
container = s(:d, contained)
|
115
104
|
|
@@ -146,8 +135,6 @@ class TestSexp < Minitest::Test
|
|
146
135
|
end
|
147
136
|
|
148
137
|
def test_prune_liberal
|
149
|
-
register_node_types
|
150
|
-
|
151
138
|
contained = s(:a, s(:b,s(:c)), s(:d,s(:e)))
|
152
139
|
container = s(:d, contained)
|
153
140
|
|
@@ -448,4 +435,178 @@ class TestSexp < Minitest::Test
|
|
448
435
|
|
449
436
|
assert_equal exp, flay.n_way_diff(*dog_and_cat).gsub(/^ {3}$/, "")
|
450
437
|
end
|
438
|
+
|
439
|
+
attr_accessor :flay
|
440
|
+
|
441
|
+
def refute_nodes type
|
442
|
+
assert flay.hashes.values.flatten(1).none? { |s| s.sexp_type == type }, "Found #{type} nodes!"
|
443
|
+
end
|
444
|
+
|
445
|
+
def assert_nodes type
|
446
|
+
assert flay.hashes.values.flatten(1).any? { |s| s.sexp_type == type }, "Did not find #{type} nodes!"
|
447
|
+
end
|
448
|
+
|
449
|
+
def test_prune_and_filter_conflict_separate_trees
|
450
|
+
exp_foo = s(:begin,
|
451
|
+
s(:begin,
|
452
|
+
s(:filter_me,
|
453
|
+
s(:a, s(:b)))))
|
454
|
+
|
455
|
+
exp_bar = s(:begin,
|
456
|
+
s(:begin,
|
457
|
+
s(:filter_me,
|
458
|
+
s(:a, s(:b)),
|
459
|
+
s(:c))))
|
460
|
+
|
461
|
+
filter = Sexp::Matcher.parse("(filter_me ___)")
|
462
|
+
options = Flay.default_options.merge(mass: 0, filters: [filter])
|
463
|
+
self.flay = Flay.new(options)
|
464
|
+
|
465
|
+
flay.process_sexp exp_foo
|
466
|
+
flay.process_sexp exp_bar
|
467
|
+
|
468
|
+
refute_nodes :filter_me
|
469
|
+
|
470
|
+
flay.prune
|
471
|
+
|
472
|
+
assert_empty flay.hashes
|
473
|
+
end
|
474
|
+
|
475
|
+
def test_prune_and_filter_conflict_different_tree_shapes
|
476
|
+
exp_foo = s(:filter_me,
|
477
|
+
s(:a, s(:b)))
|
478
|
+
|
479
|
+
exp_bar = s(:filter_me,
|
480
|
+
s(:a, s(:b)),
|
481
|
+
s(:c))
|
482
|
+
|
483
|
+
filter = Sexp::Matcher.parse("(filter_me ___)")
|
484
|
+
options = Flay.default_options.merge(mass: 0, filters: [filter])
|
485
|
+
self.flay = Flay.new(options)
|
486
|
+
|
487
|
+
flay.process_sexp s(:begin,
|
488
|
+
s(:begin,
|
489
|
+
exp_foo,
|
490
|
+
exp_bar))
|
491
|
+
|
492
|
+
refute_nodes :filter_me
|
493
|
+
|
494
|
+
flay.prune
|
495
|
+
|
496
|
+
assert_empty flay.hashes
|
497
|
+
end
|
498
|
+
|
499
|
+
def test_prune_and_filter_conflict_different_literals
|
500
|
+
exp_foo = s(:filter_me,
|
501
|
+
s(:a, s(:b, 1)))
|
502
|
+
|
503
|
+
exp_bar = s(:filter_me,
|
504
|
+
s(:a, s(:b, 2)))
|
505
|
+
|
506
|
+
filter = Sexp::Matcher.parse("(filter_me ___)")
|
507
|
+
options = Flay.default_options.merge(mass: 0, filters: [filter])
|
508
|
+
self.flay = Flay.new(options)
|
509
|
+
|
510
|
+
flay.process_sexp s(:begin,
|
511
|
+
s(:begin,
|
512
|
+
exp_foo,
|
513
|
+
exp_bar))
|
514
|
+
|
515
|
+
refute_nodes :filter_me
|
516
|
+
|
517
|
+
flay.prune
|
518
|
+
|
519
|
+
assert_empty flay.hashes
|
520
|
+
end
|
521
|
+
|
522
|
+
def test_prune_and_filter_conflict_shape_and_literals
|
523
|
+
exp_foo = s(:filter_me,
|
524
|
+
s(:a, s(:b, 1)))
|
525
|
+
|
526
|
+
exp_bar = s(:filter_me,
|
527
|
+
s(:a, s(:b, 2)),
|
528
|
+
s(:c))
|
529
|
+
|
530
|
+
filter = Sexp::Matcher.parse("(filter_me ___)")
|
531
|
+
options = Flay.default_options.merge(mass: 0, filters: [filter])
|
532
|
+
self.flay = Flay.new(options)
|
533
|
+
|
534
|
+
flay.process_sexp s(:begin,
|
535
|
+
s(:begin,
|
536
|
+
exp_foo,
|
537
|
+
exp_bar))
|
538
|
+
|
539
|
+
refute_nodes :filter_me
|
540
|
+
|
541
|
+
flay.prune
|
542
|
+
|
543
|
+
assert_empty flay.hashes
|
544
|
+
end
|
545
|
+
|
546
|
+
def test_prune_and_filter_conflict_must_keep_nonfiltered_trees
|
547
|
+
exp_foo = s(:filter_me,
|
548
|
+
s(:a, s(:b, 1)))
|
549
|
+
|
550
|
+
exp_bar = s(:filter_me,
|
551
|
+
s(:a, s(:b, 2)))
|
552
|
+
|
553
|
+
exp_baz = s(:begin,
|
554
|
+
s(:keep,
|
555
|
+
s(:a, s(:b, 1))),
|
556
|
+
s(:keep,
|
557
|
+
s(:a, s(:b, 2))))
|
558
|
+
|
559
|
+
filter = Sexp::Matcher.parse("(filter_me ___)")
|
560
|
+
options = Flay.default_options.merge(mass: 0, filters: [filter])
|
561
|
+
self.flay = Flay.new(options)
|
562
|
+
|
563
|
+
flay.process_sexp s(:begin,
|
564
|
+
s(:begin,
|
565
|
+
exp_baz,
|
566
|
+
exp_foo,
|
567
|
+
exp_bar))
|
568
|
+
|
569
|
+
refute_nodes :filter_me
|
570
|
+
assert_nodes :keep
|
571
|
+
|
572
|
+
flay.prune
|
573
|
+
|
574
|
+
refute_empty flay.hashes
|
575
|
+
refute_nodes :filter_me
|
576
|
+
assert_nodes :keep
|
577
|
+
end
|
578
|
+
|
579
|
+
def test_prune_and_filter_conflict_must_keep_nonfiltered_trees2
|
580
|
+
exp_foo = s(:filter_me,
|
581
|
+
s(:a, s(:b, 1)))
|
582
|
+
|
583
|
+
exp_bar = s(:filter_me,
|
584
|
+
s(:a, s(:b, 2)))
|
585
|
+
|
586
|
+
exp_baz = s(:begin,
|
587
|
+
s(:keep,
|
588
|
+
s(:a, s(:b, 1))),
|
589
|
+
s(:keep,
|
590
|
+
s(:a, s(:b, 2))))
|
591
|
+
|
592
|
+
filter = Sexp::Matcher.parse("(filter_me ___)")
|
593
|
+
options = Flay.default_options.merge(mass: 0, filters: [filter])
|
594
|
+
self.flay = Flay.new(options)
|
595
|
+
|
596
|
+
flay.process_sexp s(:begin,
|
597
|
+
s(:begin,
|
598
|
+
exp_foo,
|
599
|
+
exp_bar,
|
600
|
+
exp_baz))
|
601
|
+
|
602
|
+
refute_nodes :filter_me
|
603
|
+
assert_nodes :keep
|
604
|
+
|
605
|
+
flay.prune
|
606
|
+
|
607
|
+
refute_empty flay.hashes
|
608
|
+
refute_nodes :filter_me
|
609
|
+
assert_nodes :keep
|
610
|
+
end
|
611
|
+
|
451
612
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: flay
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.11.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryan Davis
|
@@ -10,9 +10,9 @@ bindir: bin
|
|
10
10
|
cert_chain:
|
11
11
|
- |
|
12
12
|
-----BEGIN CERTIFICATE-----
|
13
|
-
|
13
|
+
MIIDPjCCAiagAwIBAgIBAjANBgkqhkiG9w0BAQUFADBFMRMwEQYDVQQDDApyeWFu
|
14
14
|
ZC1ydWJ5MRkwFwYKCZImiZPyLGQBGRYJemVuc3BpZGVyMRMwEQYKCZImiZPyLGQB
|
15
|
-
|
15
|
+
GRYDY29tMB4XDTE3MTEyMTIxMTExMFoXDTE4MTEyMTIxMTExMFowRTETMBEGA1UE
|
16
16
|
AwwKcnlhbmQtcnVieTEZMBcGCgmSJomT8ixkARkWCXplbnNwaWRlcjETMBEGCgmS
|
17
17
|
JomT8ixkARkWA2NvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALda
|
18
18
|
b9DCgK+627gPJkB6XfjZ1itoOQvpqH1EXScSaba9/S2VF22VYQbXU1xQXL/WzCkx
|
@@ -20,17 +20,16 @@ cert_chain:
|
|
20
20
|
oOvjtt5P8+GSK9zLzxQP0gVLS/D0FmoE44XuDr3iQkVS2ujU5zZL84mMNqNB1znh
|
21
21
|
GiadM9GHRaDiaxuX0cIUBj19T01mVE2iymf9I6bEsiayK/n6QujtyCbTWsAS9Rqt
|
22
22
|
qhtV7HJxNKuPj/JFH0D2cswvzznE/a5FOYO68g+YCuFi5L8wZuuM8zzdwjrWHqSV
|
23
|
-
gBEfoTEGr7Zii72cx+
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
fO6tdKQc/5RfA8oQEkg8hrxA5PQSz4TOFJGLpFvIapEk6tMruQ0bHgkhr9auXg==
|
23
|
+
gBEfoTEGr7Zii72cx+sCAwEAAaM5MDcwCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAw
|
24
|
+
HQYDVR0OBBYEFEfFe9md/r/tj/Wmwpy+MI8d9k/hMA0GCSqGSIb3DQEBBQUAA4IB
|
25
|
+
AQAfAXSQpsW7YSxd1csRtA/M4Zt0AMXFMd76GJ8Lgtg8G0+VFbdChRyDuDb0kPlW
|
26
|
+
h9QQX/YABfCW8vxmssbMGrP+VGBAn7BbdTcfTlgCWrvMX1uL5aRL74nA4urKXqdW
|
27
|
+
a0nP70K4958P3GffBdtE3KGkU5xstFnXGajxuBRnL66E15KU0BNehVxdG258bdPu
|
28
|
+
EKN6MqBPftFiev3tuwqDV11r2GquDpniYcT+Mi8/PgeAgVT/afBeVgbB3KaZeTRR
|
29
|
+
AhXhF6Wi2GTMezlj5jlI5XV7WsJUSwTp/YiVvcmT74ZaCRvexm6EnNhkrvJJ1Xeu
|
30
|
+
V+HB+LYYhXWitInO/eXxDrFB
|
32
31
|
-----END CERTIFICATE-----
|
33
|
-
date:
|
32
|
+
date: 2018-04-05 00:00:00.000000000 Z
|
34
33
|
dependencies:
|
35
34
|
- !ruby/object:Gem::Dependency
|
36
35
|
name: sexp_processor
|
@@ -154,13 +153,13 @@ executables:
|
|
154
153
|
- flay
|
155
154
|
extensions: []
|
156
155
|
extra_rdoc_files:
|
157
|
-
- History.
|
156
|
+
- History.rdoc
|
158
157
|
- Manifest.txt
|
159
|
-
- README.
|
158
|
+
- README.rdoc
|
160
159
|
files:
|
161
|
-
- History.
|
160
|
+
- History.rdoc
|
162
161
|
- Manifest.txt
|
163
|
-
- README.
|
162
|
+
- README.rdoc
|
164
163
|
- Rakefile
|
165
164
|
- bin/flay
|
166
165
|
- lib/flay.rb
|
@@ -175,7 +174,7 @@ metadata: {}
|
|
175
174
|
post_install_message:
|
176
175
|
rdoc_options:
|
177
176
|
- "--main"
|
178
|
-
- README.
|
177
|
+
- README.rdoc
|
179
178
|
require_paths:
|
180
179
|
- lib
|
181
180
|
required_ruby_version: !ruby/object:Gem::Requirement
|
@@ -190,7 +189,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
190
189
|
version: '0'
|
191
190
|
requirements: []
|
192
191
|
rubyforge_project:
|
193
|
-
rubygems_version: 2.
|
192
|
+
rubygems_version: 2.7.3
|
194
193
|
signing_key:
|
195
194
|
specification_version: 4
|
196
195
|
summary: Flay analyzes code for structural similarities
|
metadata.gz.sig
CHANGED
@@ -1 +1,3 @@
|
|
1
|
-
|
1
|
+
9�l����J5u���6��tO�
|
2
|
+
7���ٞ�g��� ��}6��Lf�{���h탸��C�/�o�'V��IwHC6�
|
3
|
+
�m@���VxfwQ���M��]2�Ј���4�>?v㤺���fE���$]!��1}-F���`��ܨ���y4q\�5�\��MG�����G�2ޭŔ�����%K���_�z�_�^�8|��U�<p�%�+��:�Wg%h�fΥ7���zB�1���F��![B尗L-%��w���
|