rubocop-performance 1.4.1 → 1.6.1

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.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +5 -1
  4. data/config/default.yml +29 -10
  5. data/lib/rubocop/cop/mixin/regexp_metacharacter.rb +76 -0
  6. data/lib/rubocop/cop/performance/bind_call.rb +87 -0
  7. data/lib/rubocop/cop/performance/caller.rb +3 -3
  8. data/lib/rubocop/cop/performance/casecmp.rb +5 -3
  9. data/lib/rubocop/cop/performance/chain_array_allocation.rb +1 -1
  10. data/lib/rubocop/cop/performance/compare_with_block.rb +2 -2
  11. data/lib/rubocop/cop/performance/count.rb +3 -6
  12. data/lib/rubocop/cop/performance/delete_prefix.rb +96 -0
  13. data/lib/rubocop/cop/performance/delete_suffix.rb +96 -0
  14. data/lib/rubocop/cop/performance/detect.rb +1 -5
  15. data/lib/rubocop/cop/performance/double_start_end_with.rb +2 -2
  16. data/lib/rubocop/cop/performance/end_with.rb +36 -13
  17. data/lib/rubocop/cop/performance/fixed_size.rb +1 -1
  18. data/lib/rubocop/cop/performance/flat_map.rb +9 -2
  19. data/lib/rubocop/cop/performance/inefficient_hash_search.rb +1 -1
  20. data/lib/rubocop/cop/performance/open_struct.rb +1 -1
  21. data/lib/rubocop/cop/performance/range_include.rb +1 -1
  22. data/lib/rubocop/cop/performance/redundant_block_call.rb +3 -3
  23. data/lib/rubocop/cop/performance/redundant_match.rb +2 -2
  24. data/lib/rubocop/cop/performance/redundant_merge.rb +22 -9
  25. data/lib/rubocop/cop/performance/regexp_match.rb +13 -13
  26. data/lib/rubocop/cop/performance/reverse_each.rb +3 -2
  27. data/lib/rubocop/cop/performance/size.rb +2 -2
  28. data/lib/rubocop/cop/performance/start_with.rb +36 -16
  29. data/lib/rubocop/cop/performance/string_replacement.rb +4 -11
  30. data/lib/rubocop/cop/performance/times_map.rb +1 -1
  31. data/lib/rubocop/cop/performance/unfreeze_string.rb +3 -7
  32. data/lib/rubocop/cop/performance/uri_default_parser.rb +1 -1
  33. data/lib/rubocop/cop/performance_cops.rb +5 -0
  34. data/lib/rubocop/performance/inject.rb +1 -1
  35. data/lib/rubocop/performance/version.rb +1 -1
  36. metadata +13 -9
@@ -18,7 +18,7 @@ module RuboCop
18
18
  MSG = 'Use `reverse_each` instead of `reverse.each`.'
19
19
  UNDERSCORE = '_'
20
20
 
21
- def_node_matcher :reverse_each?, <<-MATCHER
21
+ def_node_matcher :reverse_each?, <<~MATCHER
22
22
  (send $(send _ :reverse) :each)
23
23
  MATCHER
24
24
 
@@ -34,7 +34,8 @@ module RuboCop
34
34
  end
35
35
 
36
36
  def autocorrect(node)
37
- ->(corrector) { corrector.replace(node.loc.dot, UNDERSCORE) }
37
+ range = range_between(node.loc.dot.begin_pos, node.loc.selector.begin_pos)
38
+ ->(corrector) { corrector.replace(range, UNDERSCORE) }
38
39
  end
39
40
  end
40
41
  end
@@ -60,7 +60,7 @@ module RuboCop
60
60
 
61
61
  _, constant = *node.receiver
62
62
 
63
- constant == :Array || node.method_name == :to_a
63
+ constant == :Array || node.method?(:to_a)
64
64
  end
65
65
 
66
66
  def hash?(node)
@@ -69,7 +69,7 @@ module RuboCop
69
69
 
70
70
  _, constant = *node.receiver
71
71
 
72
- constant == :Hash || node.method_name == :to_h
72
+ constant == :Hash || node.method?(:to_h)
73
73
  end
74
74
  end
75
75
  end
@@ -3,47 +3,67 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Performance
6
- # This cop identifies unnecessary use of a regex where
7
- # `String#start_with?` would suffice.
6
+ # This cop identifies unnecessary use of a regex where `String#start_with?` would suffice.
7
+ #
8
+ # This cop has `SafeMultiline` configuration option that `true` by default because
9
+ # `^start` is unsafe as it will behave incompatible with `start_with?`
10
+ # for receiver is multiline string.
8
11
  #
9
12
  # @example
10
13
  # # bad
11
14
  # 'abc'.match?(/\Aab/)
15
+ # /\Aab/.match?('abc')
12
16
  # 'abc' =~ /\Aab/
17
+ # /\Aab/ =~ 'abc'
13
18
  # 'abc'.match(/\Aab/)
19
+ # /\Aab/.match('abc')
14
20
  #
15
21
  # # good
16
22
  # 'abc'.start_with?('ab')
23
+ #
24
+ # @example SafeMultiline: true (default)
25
+ #
26
+ # # good
27
+ # 'abc'.match?(/^ab/)
28
+ # /^ab/.match?('abc')
29
+ # 'abc' =~ /^ab/
30
+ # /^ab/ =~ 'abc'
31
+ # 'abc'.match(/^ab/)
32
+ # /^ab/.match('abc')
33
+ #
34
+ # @example SafeMultiline: false
35
+ #
36
+ # # bad
37
+ # 'abc'.match?(/^ab/)
38
+ # /^ab/.match?('abc')
39
+ # 'abc' =~ /^ab/
40
+ # /^ab/ =~ 'abc'
41
+ # 'abc'.match(/^ab/)
42
+ # /^ab/.match('abc')
43
+ #
17
44
  class StartWith < Cop
45
+ include RegexpMetacharacter
46
+
18
47
  MSG = 'Use `String#start_with?` instead of a regex match anchored to ' \
19
48
  'the beginning of the string.'
20
- SINGLE_QUOTE = "'"
21
49
 
22
- def_node_matcher :redundant_regex?, <<-PATTERN
50
+ def_node_matcher :redundant_regex?, <<~PATTERN
23
51
  {(send $!nil? {:match :=~ :match?} (regexp (str $#literal_at_start?) (regopt)))
24
- (send (regexp (str $#literal_at_start?) (regopt)) {:match :=~} $_)}
52
+ (send (regexp (str $#literal_at_start?) (regopt)) {:match :match?} $_)
53
+ (match-with-lvasgn (regexp (str $#literal_at_start?) (regopt)) $_)}
25
54
  PATTERN
26
55
 
27
- def literal_at_start?(regex_str)
28
- # is this regexp 'literal' in the sense of only matching literal
29
- # chars, rather than using metachars like `.` and `*` and so on?
30
- # also, is it anchored at the start of the string?
31
- # (tricky: \s, \d, and so on are metacharacters, but other characters
32
- # escaped with a slash are just literals. LITERAL_REGEX takes all
33
- # that into account.)
34
- regex_str =~ /\A\\A(?:#{LITERAL_REGEX})+\z/
35
- end
36
-
37
56
  def on_send(node)
38
57
  return unless redundant_regex?(node)
39
58
 
40
59
  add_offense(node)
41
60
  end
61
+ alias on_match_with_lvasgn on_send
42
62
 
43
63
  def autocorrect(node)
44
64
  redundant_regex?(node) do |receiver, regex_str|
45
65
  receiver, regex_str = regex_str, receiver if receiver.is_a?(String)
46
- regex_str = regex_str[2..-1] # drop \A anchor
66
+ regex_str = drop_start_metacharacter(regex_str)
47
67
  regex_str = interpret_string_escapes(regex_str)
48
68
 
49
69
  lambda do |corrector|
@@ -26,9 +26,8 @@ module RuboCop
26
26
  DELETE = 'delete'
27
27
  TR = 'tr'
28
28
  BANG = '!'
29
- SINGLE_QUOTE = "'"
30
29
 
31
- def_node_matcher :string_replacement?, <<-PATTERN
30
+ def_node_matcher :string_replacement?, <<~PATTERN
32
31
  (send _ {:gsub :gsub!}
33
32
  ${regexp str (send (const nil? :Regexp) {:new :compile} _)}
34
33
  $str)
@@ -48,9 +47,7 @@ module RuboCop
48
47
  first_source, = first_source(first_param)
49
48
  second_source, = *second_param
50
49
 
51
- unless first_param.str_type?
52
- first_source = interpret_string_escapes(first_source)
53
- end
50
+ first_source = interpret_string_escapes(first_source) unless first_param.str_type?
54
51
 
55
52
  replacement_method =
56
53
  replacement_method(node, first_source, second_source)
@@ -67,9 +64,7 @@ module RuboCop
67
64
  to_string_literal(first))
68
65
  end
69
66
 
70
- if second.empty? && first.length == 1
71
- remove_second_param(corrector, node, first_param)
72
- end
67
+ remove_second_param(corrector, node, first_param) if second.empty? && first.length == 1
73
68
  end
74
69
  end
75
70
 
@@ -99,9 +94,7 @@ module RuboCop
99
94
 
100
95
  def offense(node, first_param, second_param)
101
96
  first_source, = first_source(first_param)
102
- unless first_param.str_type?
103
- first_source = interpret_string_escapes(first_source)
104
- end
97
+ first_source = interpret_string_escapes(first_source) unless first_param.str_type?
105
98
  second_source, = *second_param
106
99
  message = message(node, first_source, second_source)
107
100
 
@@ -61,7 +61,7 @@ module RuboCop
61
61
  map_or_collect: map_or_collect.method_name)
62
62
  end
63
63
 
64
- def_node_matcher :times_map_call, <<-PATTERN
64
+ def_node_matcher :times_map_call, <<~PATTERN
65
65
  {(block $(send (send $!nil? :times) {:map :collect}) ...)
66
66
  $(send (send $!nil? :times) {:map :collect} (block_pass ...))}
67
67
  PATTERN
@@ -7,7 +7,7 @@ module RuboCop
7
7
  # literal instead of `String#dup` and `String.new`.
8
8
  # Unary plus operator is faster than `String#dup`.
9
9
  #
10
- # Note: `String.new` (without operator) is not exactly the same as `+''`.
10
+ # NOTE: `String.new` (without operator) is not exactly the same as `+''`.
11
11
  # These differ in encoding. `String.new.encoding` is always `ASCII-8BIT`.
12
12
  # However, `(+'').encoding` is the same as script encoding(e.g. `UTF-8`).
13
13
  # So, if you expect `ASCII-8BIT` encoding, disable this cop.
@@ -24,17 +24,13 @@ module RuboCop
24
24
  # +'something'
25
25
  # +''
26
26
  class UnfreezeString < Cop
27
- extend TargetRubyVersion
28
-
29
- minimum_target_ruby_version 2.3
30
-
31
27
  MSG = 'Use unary plus to get an unfrozen string literal.'
32
28
 
33
- def_node_matcher :dup_string?, <<-PATTERN
29
+ def_node_matcher :dup_string?, <<~PATTERN
34
30
  (send {str dstr} :dup)
35
31
  PATTERN
36
32
 
37
- def_node_matcher :string_new?, <<-PATTERN
33
+ def_node_matcher :string_new?, <<~PATTERN
38
34
  {
39
35
  (send (const nil? :String) :new {str dstr})
40
36
  (send (const nil? :String) :new)
@@ -17,7 +17,7 @@ module RuboCop
17
17
  MSG = 'Use `%<double_colon>sURI::DEFAULT_PARSER` instead of ' \
18
18
  '`%<double_colon>sURI::Parser.new`.'
19
19
 
20
- def_node_matcher :uri_parser_new?, <<-PATTERN
20
+ def_node_matcher :uri_parser_new?, <<~PATTERN
21
21
  (send
22
22
  (const
23
23
  (const ${nil? cbase} :URI) :Parser) :new)
@@ -1,10 +1,15 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative 'mixin/regexp_metacharacter'
4
+
5
+ require_relative 'performance/bind_call'
3
6
  require_relative 'performance/caller'
4
7
  require_relative 'performance/case_when_splat'
5
8
  require_relative 'performance/casecmp'
6
9
  require_relative 'performance/compare_with_block'
7
10
  require_relative 'performance/count'
11
+ require_relative 'performance/delete_prefix'
12
+ require_relative 'performance/delete_suffix'
8
13
  require_relative 'performance/detect'
9
14
  require_relative 'performance/double_start_end_with'
10
15
  require_relative 'performance/end_with'
@@ -8,7 +8,7 @@ module RuboCop
8
8
  def self.defaults!
9
9
  path = CONFIG_DEFAULT.to_s
10
10
  hash = ConfigLoader.send(:load_yaml_configuration, path)
11
- config = Config.new(hash, path)
11
+ config = Config.new(hash, path).tap(&:make_excludes_absolute)
12
12
  puts "configuration from #{path}" if ConfigLoader.debug?
13
13
  config = ConfigLoader.merge_with_default(config, path)
14
14
  ConfigLoader.instance_variable_set(:@default_configuration, config)
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Performance
5
5
  module Version
6
- STRING = '1.4.1'
6
+ STRING = '1.6.1'
7
7
  end
8
8
  end
9
9
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubocop-performance
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.1
4
+ version: 1.6.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bozhidar Batsov
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2019-07-29 00:00:00.000000000 Z
13
+ date: 2020-06-05 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rubocop
@@ -40,9 +40,9 @@ dependencies:
40
40
  - - ">="
41
41
  - !ruby/object:Gem::Version
42
42
  version: '0'
43
- description: |2
44
- A collection of RuboCop cops to check for performance optimizations
45
- in Ruby code.
43
+ description: |
44
+ A collection of RuboCop cops to check for performance optimizations
45
+ in Ruby code.
46
46
  email: rubocop@googlegroups.com
47
47
  executables: []
48
48
  extensions: []
@@ -54,12 +54,16 @@ files:
54
54
  - README.md
55
55
  - config/default.yml
56
56
  - lib/rubocop-performance.rb
57
+ - lib/rubocop/cop/mixin/regexp_metacharacter.rb
58
+ - lib/rubocop/cop/performance/bind_call.rb
57
59
  - lib/rubocop/cop/performance/caller.rb
58
60
  - lib/rubocop/cop/performance/case_when_splat.rb
59
61
  - lib/rubocop/cop/performance/casecmp.rb
60
62
  - lib/rubocop/cop/performance/chain_array_allocation.rb
61
63
  - lib/rubocop/cop/performance/compare_with_block.rb
62
64
  - lib/rubocop/cop/performance/count.rb
65
+ - lib/rubocop/cop/performance/delete_prefix.rb
66
+ - lib/rubocop/cop/performance/delete_suffix.rb
63
67
  - lib/rubocop/cop/performance/detect.rb
64
68
  - lib/rubocop/cop/performance/double_start_end_with.rb
65
69
  - lib/rubocop/cop/performance/end_with.rb
@@ -87,10 +91,10 @@ homepage: https://github.com/rubocop-hq/rubocop-performance
87
91
  licenses:
88
92
  - MIT
89
93
  metadata:
90
- homepage_uri: https://docs.rubocop.org/projects/performance
94
+ homepage_uri: https://docs.rubocop.org/rubocop-performance/
91
95
  changelog_uri: https://github.com/rubocop-hq/rubocop-performance/blob/master/CHANGELOG.md
92
96
  source_code_uri: https://github.com/rubocop-hq/rubocop-performance/
93
- documentation_uri: https://docs.rubocop.org/projects/performance
97
+ documentation_uri: https://docs.rubocop.org/rubocop-performance/
94
98
  bug_tracker_uri: https://github.com/rubocop-hq/rubocop-performance/issues
95
99
  post_install_message:
96
100
  rdoc_options: []
@@ -100,14 +104,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
100
104
  requirements:
101
105
  - - ">="
102
106
  - !ruby/object:Gem::Version
103
- version: 2.3.0
107
+ version: 2.4.0
104
108
  required_rubygems_version: !ruby/object:Gem::Requirement
105
109
  requirements:
106
110
  - - ">="
107
111
  - !ruby/object:Gem::Version
108
112
  version: '0'
109
113
  requirements: []
110
- rubygems_version: 3.0.4
114
+ rubygems_version: 3.1.3
111
115
  signing_key:
112
116
  specification_version: 4
113
117
  summary: Automatic performance checking tool for Ruby code.