flay 2.10.0 → 2.11.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.
- 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���
|