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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 73416b286d8de1583c4861f2da639893f0012111
4
- data.tar.gz: 31671f4f0671c63d9432e3651d850796aacbbce3
2
+ SHA256:
3
+ metadata.gz: 8ba894eeca0c7966356ccb85f9252f47cf27e2ee34252288502cc70c50aa4d64
4
+ data.tar.gz: eb4552d71f43350ec698c3ef36a17d0b18b93c65e54666240af786952ed8e512
5
5
  SHA512:
6
- metadata.gz: a6574f751315f6d8da0857c7b13d0e0ba4becfbece092e86b310c9a393f0f801700a1a4a3904a0afdaca967bb618187569eecad6ec7a8bd01574748dbee7f09e
7
- data.tar.gz: 161a7012a55cf51110f7d535f768f8d1e5ab7eba061ec5fce660cb6595ac67751ad58cb15b4200e62a214e0022d550ada00d52352a805fece333bd4061add125
6
+ metadata.gz: 921301e4deb3c56b8eaf8fa1078ddb20f5bb9a3bf298ecea377df3440b8fc6e17f2475fbc31a1009b66042876289082bf61139bc982293c5530a51975966f793
7
+ data.tar.gz: 25e52c615125a7d06f59b41d1191dfca7c56a861d1c4a968f188dedd231b9d64fe84ab6c223526af10785e70b488600be4a4840754291b5408056cd9e11f7a82
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:
@@ -1,6 +1,6 @@
1
- History.txt
1
+ History.rdoc
2
2
  Manifest.txt
3
- README.txt
3
+ README.rdoc
4
4
  Rakefile
5
5
  bin/flay
6
6
  lib/flay.rb
File without changes
data/Rakefile CHANGED
@@ -12,6 +12,7 @@ Hoe::add_include_dirs("../../sexp_processor/dev/lib",
12
12
 
13
13
  Hoe.plugin :seattlerb
14
14
  Hoe.plugin :isolate
15
+ Hoe.plugin :rdoc
15
16
  Hoe.plugin :bundler
16
17
 
17
18
  Hoe.spec "flay" do
@@ -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.10.0" # :nodoc:
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 => nil,
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 = nil
173
- @option = option || Flay.default_options
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 unless node.any? { |sub| Sexp === sub }
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
- names = %w(alias and arglist args array attrasgn attrset back_ref
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
 
@@ -19,7 +19,7 @@ class TestSexp < Minitest::Test
19
19
  end
20
20
 
21
21
  def test_structural_hash
22
- hash = 3336573932
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.10.0
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
- MIIDijCCAnKgAwIBAgIBATANBgkqhkiG9w0BAQUFADBFMRMwEQYDVQQDDApyeWFu
13
+ MIIDPjCCAiagAwIBAgIBAjANBgkqhkiG9w0BAQUFADBFMRMwEQYDVQQDDApyeWFu
14
14
  ZC1ydWJ5MRkwFwYKCZImiZPyLGQBGRYJemVuc3BpZGVyMRMwEQYKCZImiZPyLGQB
15
- GRYDY29tMB4XDTE2MDkyNjAxNTczNVoXDTE3MDkyNjAxNTczNVowRTETMBEGA1UE
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+sCAwEAAaOBhDCBgTAJBgNVHRMEAjAAMAsGA1UdDwQEAwIE
24
- sDAdBgNVHQ4EFgQUR8V72Z3+v+2P9abCnL4wjx32T+EwIwYDVR0RBBwwGoEYcnlh
25
- bmQtcnVieUB6ZW5zcGlkZXIuY29tMCMGA1UdEgQcMBqBGHJ5YW5kLXJ1YnlAemVu
26
- c3BpZGVyLmNvbTANBgkqhkiG9w0BAQUFAAOCAQEAIGzgp0aZ2W9+v96ujmBcQHoC
27
- buy0iU68MVj2VlxMyfr1KPZIh1OyhU4UO4zrkREcH8ML70v9cYHNvOd9oynRHnvC
28
- l2tj/fD3YJ0AEkJxGrYwRWQmvMfC4bJ02bC1+rVOUIXXKp3+cUmiN4sTniof8VFo
29
- bo/YYP4c7erpERa+9hrqygg6WQbJlk2YRlH3JXPFjmu869i2dcbR5ZLOAeEy+axH
30
- E4oJcnPkJAr0rw504JGtlZtONZQblwmRJOIdXzolaE3NRGUzGVOUSptZppAKiavY
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: 2017-07-17 00:00:00.000000000 Z
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.txt
156
+ - History.rdoc
158
157
  - Manifest.txt
159
- - README.txt
158
+ - README.rdoc
160
159
  files:
161
- - History.txt
160
+ - History.rdoc
162
161
  - Manifest.txt
163
- - README.txt
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.txt
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.6.8
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
- �����S���"C� �4uC7����l�#���=+5�B���u� ޞAdʏ�&tdL��&�(/v`�`/ooP�[��a�Uح����|��%��>Ǜ���.�pyXUM6I@���cH�-`�W�DfK�[g���Xi�7F�c_h����]�[���&���:���+�o�tP�A��kZ
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���