rubocop-performance 1.14.3 → 1.15.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7716dc36d8facd9d8604d89d117f85db5fed60efcad66ad8354d673492800140
4
- data.tar.gz: 59f4dd4e4df5afef36700a8951e8e91e18567ba978506d9aa02884abafc6d639
3
+ metadata.gz: 116e2f10caf814178e8afe49e7bac931cbb232dfd1ce8bb478057b7e0a0ce056
4
+ data.tar.gz: 0c9c7d2b6180607cc6988eca34ba7364a8295565ab07ddbeaa0c81027f5d3000
5
5
  SHA512:
6
- metadata.gz: 748977ac053ddab36afda43c709eee6424957a81ce18daf1048cf42399226e0d2d67f9964ba544594a03862d5650eff369a34b407d49892d72957ab3acf2ca11
7
- data.tar.gz: 9a785cd79f0e781643720fd19e2454d6b1cac890c215d5a44762e4173d69e9f6ec6adc57fe43646dba7b3e48bf86663842f595f54db1f51c7e251af75113ecee
6
+ metadata.gz: fd9c4b591e4193d5ef640a586c71b7cb0b27dbde63022128119297ebfc9e09741f5a26ee8ef2c1cea876c4f919f48b8fbd364285149c45b89818c6e0ecf1a3c6
7
+ data.tar.gz: 8984a58f416a279e7a6f74f4917600a9ba97a90fca81160b0899a66123612736576c870668e8b5e52bb5de0aae5c34ea5874105fa58f3aef63987d5cea319198
data/config/default.yml CHANGED
@@ -1,5 +1,9 @@
1
1
  # This is the default configuration file.
2
2
 
3
+ Performance:
4
+ Enabled: true
5
+ DocumentationBaseURL: https://docs.rubocop.org/rubocop-performance
6
+
3
7
  Performance/AncestorsInclude:
4
8
  Description: 'Use `A <= B` instead of `A.ancestors.include?(B)`.'
5
9
  Reference: 'https://github.com/JuanitoFatas/fast-ruby#ancestorsinclude-vs--code'
@@ -14,6 +14,13 @@ module RuboCop
14
14
  $send)
15
15
  PATTERN
16
16
 
17
+ def_node_matcher :sort_with_numblock?, <<~PATTERN
18
+ (numblock
19
+ $(send _ :sort)
20
+ $_arg_count
21
+ $send)
22
+ PATTERN
23
+
17
24
  def_node_matcher :replaceable_body?, <<~PATTERN
18
25
  (send (lvar %1) :<=> (lvar %2))
19
26
  PATTERN
@@ -41,11 +41,7 @@ module RuboCop
41
41
  end
42
42
  elsif (numeric_to_d = to_d?(node))
43
43
  add_offense(numeric_to_d.source_range) do |corrector|
44
- big_decimal_args = node
45
- .arguments
46
- .map(&:source)
47
- .unshift("'#{numeric_to_d.source}'")
48
- .join(', ')
44
+ big_decimal_args = node.arguments.map(&:source).unshift("'#{numeric_to_d.source}'").join(', ')
49
45
 
50
46
  corrector.replace(node, "BigDecimal(#{big_decimal_args})")
51
47
  end
@@ -26,8 +26,7 @@ module RuboCop
26
26
 
27
27
  minimum_target_ruby_version 2.7
28
28
 
29
- MSG = 'Use `bind_call(%<bind_arg>s%<comma>s%<call_args>s)` ' \
30
- 'instead of `bind(%<bind_arg>s).call(%<call_args>s)`.'
29
+ MSG = 'Use `bind_call(%<bind_arg>s%<comma>s%<call_args>s)` instead of `bind(%<bind_arg>s).call(%<call_args>s)`.'
31
30
  RESTRICT_ON_SEND = %i[call].freeze
32
31
 
33
32
  def_node_matcher :bind_with_call_method?, <<~PATTERN
@@ -99,8 +99,7 @@ module RuboCop
99
99
 
100
100
  def inline_fix_branch(corrector, when_node)
101
101
  conditions = when_node.conditions
102
- range = range_between(conditions[0].loc.expression.begin_pos,
103
- conditions[-1].loc.expression.end_pos)
102
+ range = range_between(conditions[0].loc.expression.begin_pos, conditions[-1].loc.expression.end_pos)
104
103
 
105
104
  corrector.replace(range, replacement(conditions))
106
105
  end
@@ -111,8 +110,7 @@ module RuboCop
111
110
  return if when_branches.one?
112
111
 
113
112
  corrector.remove(when_branch_range(when_node))
114
- corrector.insert_after(when_branches.last.source_range,
115
- reordering_correction(when_node))
113
+ corrector.insert_after(when_branches.last.source_range, reordering_correction(when_node))
116
114
  end
117
115
 
118
116
  def reordering_correction(when_node)
@@ -126,11 +124,9 @@ module RuboCop
126
124
  end
127
125
 
128
126
  def when_branch_range(when_node)
129
- next_branch =
130
- when_node.parent.when_branches[when_node.branch_index + 1]
127
+ next_branch = when_node.parent.when_branches[when_node.branch_index + 1]
131
128
 
132
- range_between(when_node.source_range.begin_pos,
133
- next_branch.source_range.begin_pos)
129
+ range_between(when_node.source_range.begin_pos, next_branch.source_range.begin_pos)
134
130
  end
135
131
 
136
132
  def new_condition_with_then(node, new_condition)
@@ -162,13 +158,11 @@ module RuboCop
162
158
  def non_splat?(condition)
163
159
  variable, = *condition
164
160
 
165
- (condition.splat_type? && variable.array_type?) ||
166
- !condition.splat_type?
161
+ (condition.splat_type? && variable.array_type?) || !condition.splat_type?
167
162
  end
168
163
 
169
164
  def needs_reorder?(when_node)
170
- following_branches =
171
- when_node.parent.when_branches[(when_node.branch_index + 1)..]
165
+ following_branches = when_node.parent.when_branches[(when_node.branch_index + 1)..]
172
166
 
173
167
  following_branches.any? do |when_branch|
174
168
  when_branch.conditions.any? do |condition|
@@ -104,9 +104,7 @@ module RuboCop
104
104
  end
105
105
 
106
106
  def loop?(ancestor, node)
107
- keyword_loop?(ancestor.type) ||
108
- kernel_loop?(ancestor) ||
109
- node_within_enumerable_loop?(node, ancestor)
107
+ keyword_loop?(ancestor.type) || kernel_loop?(ancestor) || node_within_enumerable_loop?(node, ancestor)
110
108
  end
111
109
 
112
110
  def keyword_loop?(type)
@@ -39,9 +39,7 @@ module RuboCop
39
39
  MSG = 'Extract this regexp into a constant, memoize it, or append an `/o` option to its options.'
40
40
 
41
41
  def on_regexp(node)
42
- return if within_allowed_assignment?(node) ||
43
- !include_interpolated_const?(node) ||
44
- node.single_interpolation?
42
+ return if within_allowed_assignment?(node) || !include_interpolated_const?(node) || node.single_interpolation?
45
43
 
46
44
  add_offense(node) do |corrector|
47
45
  corrector.insert_after(node, 'o')
@@ -79,12 +79,11 @@ module RuboCop
79
79
  def autocorrect(corrector, node, selector_node, selector)
80
80
  selector_loc = selector_node.loc.selector
81
81
 
82
- return if selector == :reject
83
-
84
82
  range = source_starting_at(node) { |n| n.loc.dot.begin_pos }
85
83
 
86
84
  corrector.remove(range)
87
85
  corrector.replace(selector_loc, 'count')
86
+ negate_reject(corrector, node) if selector == :reject
88
87
  end
89
88
 
90
89
  def eligible_node?(node)
@@ -100,6 +99,43 @@ module RuboCop
100
99
 
101
100
  range_between(begin_pos, node.source_range.end_pos)
102
101
  end
102
+
103
+ def negate_reject(corrector, node)
104
+ if node.receiver.send_type?
105
+ negate_block_pass_reject(corrector, node)
106
+ else
107
+ negate_block_reject(corrector, node)
108
+ end
109
+ end
110
+
111
+ def negate_block_pass_reject(corrector, node)
112
+ corrector.replace(
113
+ node.receiver.loc.expression.with(begin_pos: node.receiver.loc.begin.begin_pos),
114
+ negate_block_pass_as_inline_block(node.receiver)
115
+ )
116
+ end
117
+
118
+ def negate_block_reject(corrector, node)
119
+ target =
120
+ if node.receiver.body.begin_type?
121
+ node.receiver.body.children.last
122
+ else
123
+ node.receiver.body
124
+ end
125
+ corrector.replace(target, negate_expression(target))
126
+ end
127
+
128
+ def negate_expression(node)
129
+ "!(#{node.source})"
130
+ end
131
+
132
+ def negate_block_pass_as_inline_block(node)
133
+ if node.last_argument.children.first.sym_type?
134
+ " { |element| !element.#{node.last_argument.children.first.value} }"
135
+ else
136
+ " { !#{node.last_argument.children.first.source}.call }"
137
+ end
138
+ end
103
139
  end
104
140
  end
105
141
  end
@@ -41,8 +41,7 @@ module RuboCop
41
41
  class DoubleStartEndWith < Base
42
42
  extend AutoCorrector
43
43
 
44
- MSG = 'Use `%<receiver>s.%<method>s(%<combined_args>s)` ' \
45
- 'instead of `%<original_code>s`.'
44
+ MSG = 'Use `%<receiver>s.%<method>s(%<combined_args>s)` instead of `%<original_code>s`.'
46
45
 
47
46
  def on_or(node)
48
47
  receiver, method, first_call_args, second_call_args = process_source(node)
@@ -50,8 +50,7 @@ module RuboCop
50
50
  include RegexpMetacharacter
51
51
  extend AutoCorrector
52
52
 
53
- MSG = 'Use `String#end_with?` instead of a regex match anchored to ' \
54
- 'the end of the string.'
53
+ MSG = 'Use `String#end_with?` instead of a regex match anchored to the end of the string.'
55
54
  RESTRICT_ON_SEND = %i[match =~ match?].freeze
56
55
 
57
56
  def_node_matcher :redundant_regex?, <<~PATTERN
@@ -83,9 +83,7 @@ module RuboCop
83
83
 
84
84
  def use_long_method
85
85
  preferred_config = config.for_all_cops['Style/PreferredHashMethods']
86
- preferred_config &&
87
- preferred_config['EnforcedStyle'] == 'long' &&
88
- preferred_config['Enabled']
86
+ preferred_config && preferred_config['EnforcedStyle'] == 'long' && preferred_config['Enabled']
89
87
  end
90
88
 
91
89
  def autocorrect_argument(node)
@@ -67,7 +67,7 @@ module RuboCop
67
67
  def remove_compact_method(corrector, map_node, compact_node, chained_method)
68
68
  compact_method_range = compact_node.loc.selector
69
69
 
70
- if compact_node.multiline? && chained_method&.loc.respond_to?(:selector) && chained_method.dot? &&
70
+ if compact_node.multiline? && chained_method&.loc.respond_to?(:selector) && use_dot?(chained_method) &&
71
71
  !map_method_and_compact_method_on_same_line?(map_node, compact_node) &&
72
72
  !invoke_method_after_map_compact_on_same_line?(compact_node, chained_method)
73
73
  compact_method_range = compact_method_with_final_newline_range(compact_method_range)
@@ -78,6 +78,10 @@ module RuboCop
78
78
  corrector.remove(compact_method_range)
79
79
  end
80
80
 
81
+ def use_dot?(node)
82
+ node.respond_to?(:dot?) && node.dot?
83
+ end
84
+
81
85
  def map_method_and_compact_method_on_same_line?(map_node, compact_node)
82
86
  compact_node.loc.selector.line == map_node.loc.selector.line
83
87
  end
@@ -32,8 +32,7 @@ module RuboCop
32
32
  # end
33
33
  #
34
34
  class OpenStruct < Base
35
- MSG = 'Consider using `Struct` over `OpenStruct` ' \
36
- 'to optimize the performance.'
35
+ MSG = 'Consider using `Struct` over `OpenStruct` to optimize the performance.'
37
36
  RESTRICT_ON_SEND = %i[new].freeze
38
37
 
39
38
  def_node_matcher :open_struct, <<~PATTERN
@@ -20,8 +20,7 @@ module RuboCop
20
20
  class RedundantMatch < Base
21
21
  extend AutoCorrector
22
22
 
23
- MSG = 'Use `=~` in places where the `MatchData` returned by ' \
24
- '`#match` will not be used.'
23
+ MSG = 'Use `=~` in places where the `MatchData` returned by `#match` will not be used.'
25
24
  RESTRICT_ON_SEND = %i[match].freeze
26
25
 
27
26
  # 'match' is a fairly generic name, so we don't flag it unless we see
@@ -41,21 +40,23 @@ module RuboCop
41
40
  !(node.parent && node.parent.block_type?)
42
41
 
43
42
  add_offense(node) do |corrector|
44
- autocorrect(corrector, node)
43
+ autocorrect(corrector, node) if autocorrectable?(node)
45
44
  end
46
45
  end
47
46
 
48
47
  private
49
48
 
50
49
  def autocorrect(corrector, node)
51
- # Regexp#match can take a second argument, but this cop doesn't
52
- # register an offense in that case
53
- return unless node.first_argument.regexp_type?
54
-
55
50
  new_source = "#{node.receiver.source} =~ #{node.first_argument.source}"
56
51
 
57
52
  corrector.replace(node.source_range, new_source)
58
53
  end
54
+
55
+ def autocorrectable?(node)
56
+ # Regexp#match can take a second argument, but this cop doesn't
57
+ # register an offense in that case
58
+ node.receiver.regexp_type? || node.first_argument.regexp_type?
59
+ end
59
60
  end
60
61
  end
61
62
  end
@@ -99,8 +99,7 @@ module RuboCop
99
99
  end
100
100
 
101
101
  def non_redundant_value_used?(receiver, node)
102
- node.value_used? &&
103
- !EachWithObjectInspector.new(node, receiver).value_used?
102
+ node.value_used? && !EachWithObjectInspector.new(node, receiver).value_used?
104
103
  end
105
104
 
106
105
  def correct_multiple_elements(corrector, node, parent, new_source)
@@ -125,9 +124,7 @@ module RuboCop
125
124
 
126
125
  key = key.sym_type? && pair.colon? ? ":#{key.source}" : key.source
127
126
 
128
- format(AREF_ASGN, receiver: receiver.source,
129
- key: key,
130
- value: value.source)
127
+ format(AREF_ASGN, receiver: receiver.source, key: key, value: value.source)
131
128
  end
132
129
  end
133
130
 
@@ -16,25 +16,33 @@ module RuboCop
16
16
  include SortBlock
17
17
  extend AutoCorrector
18
18
 
19
- MSG = 'Use `sort` instead of `%<bad_method>s`.'
19
+ MSG = 'Use `sort` without block.'
20
20
 
21
21
  def on_block(node)
22
22
  return unless (send, var_a, var_b, body = sort_with_block?(node))
23
23
 
24
24
  replaceable_body?(body, var_a, var_b) do
25
- range = sort_range(send, node)
25
+ register_offense(send, node)
26
+ end
27
+ end
28
+
29
+ def on_numblock(node)
30
+ return unless (send, arg_count, body = sort_with_numblock?(node))
31
+ return unless arg_count == 2
26
32
 
27
- add_offense(range, message: message(var_a, var_b)) do |corrector|
28
- corrector.replace(range, 'sort')
29
- end
33
+ replaceable_body?(body, :_1, :_2) do
34
+ register_offense(send, node)
30
35
  end
31
36
  end
32
37
 
33
38
  private
34
39
 
35
- def message(var_a, var_b)
36
- bad_method = "sort { |#{var_a}, #{var_b}| #{var_a} <=> #{var_b} }"
37
- format(MSG, bad_method: bad_method)
40
+ def register_offense(send, node)
41
+ range = sort_range(send, node)
42
+
43
+ add_offense(range) do |corrector|
44
+ corrector.replace(range, 'sort')
45
+ end
38
46
  end
39
47
  end
40
48
  end
@@ -217,8 +217,7 @@ module RuboCop
217
217
  def find_last_match(body, range, scope_root)
218
218
  last_matches(body).find do |ref|
219
219
  ref_pos = ref.loc.expression.begin_pos
220
- range.cover?(ref_pos) &&
221
- scope_root(ref) == scope_root
220
+ range.cover?(ref_pos) && scope_root(ref) == scope_root
222
221
  end
223
222
  end
224
223
 
@@ -241,14 +240,7 @@ module RuboCop
241
240
  end
242
241
 
243
242
  def match_gvar?(sym)
244
- %i[
245
- $~
246
- $MATCH
247
- $PREMATCH
248
- $POSTMATCH
249
- $LAST_PAREN_MATCH
250
- $LAST_MATCH_INFO
251
- ].include?(sym)
243
+ %i[$~ $MATCH $PREMATCH $POSTMATCH $LAST_PAREN_MATCH $LAST_MATCH_INFO].include?(sym)
252
244
  end
253
245
 
254
246
  def correct_operator(corrector, recv, arg, oper = nil)
@@ -17,27 +17,36 @@ module RuboCop
17
17
  include SortBlock
18
18
  extend AutoCorrector
19
19
 
20
- MSG = 'Use `sort.reverse` instead of `%<bad_method>s`.'
20
+ MSG = 'Use `sort.reverse` instead.'
21
21
 
22
22
  def on_block(node)
23
23
  sort_with_block?(node) do |send, var_a, var_b, body|
24
24
  replaceable_body?(body, var_b, var_a) do
25
- range = sort_range(send, node)
25
+ register_offense(send, node)
26
+ end
27
+ end
28
+ end
26
29
 
27
- add_offense(range, message: message(var_a, var_b)) do |corrector|
28
- replacement = 'sort.reverse'
30
+ def on_numblock(node)
31
+ sort_with_numblock?(node) do |send, arg_count, body|
32
+ next unless arg_count == 2
29
33
 
30
- corrector.replace(range, replacement)
31
- end
34
+ replaceable_body?(body, :_2, :_1) do
35
+ register_offense(send, node)
32
36
  end
33
37
  end
34
38
  end
35
39
 
36
40
  private
37
41
 
38
- def message(var_a, var_b)
39
- bad_method = "sort { |#{var_a}, #{var_b}| #{var_b} <=> #{var_a} }"
40
- format(MSG, bad_method: bad_method)
42
+ def register_offense(send, node)
43
+ range = sort_range(send, node)
44
+
45
+ add_offense(range) do |corrector|
46
+ replacement = 'sort.reverse'
47
+
48
+ corrector.replace(range, replacement)
49
+ end
41
50
  end
42
51
  end
43
52
  end
@@ -24,10 +24,7 @@ module RuboCop
24
24
  MSG = 'Use `%<prefer>s` instead of `%<current>s`.'
25
25
  RESTRICT_ON_SEND = %i[gsub gsub!].freeze
26
26
 
27
- PREFERRED_METHODS = {
28
- gsub: :squeeze,
29
- gsub!: :squeeze!
30
- }.freeze
27
+ PREFERRED_METHODS = { gsub: :squeeze, gsub!: :squeeze! }.freeze
31
28
 
32
29
  def_node_matcher :squeeze_candidate?, <<~PATTERN
33
30
  (send
@@ -50,8 +50,7 @@ module RuboCop
50
50
  include RegexpMetacharacter
51
51
  extend AutoCorrector
52
52
 
53
- MSG = 'Use `String#start_with?` instead of a regex match anchored to ' \
54
- 'the beginning of the string.'
53
+ MSG = 'Use `String#start_with?` instead of a regex match anchored to the beginning of the string.'
55
54
  RESTRICT_ON_SEND = %i[match =~ match?].freeze
56
55
 
57
56
  def_node_matcher :redundant_regex?, <<~PATTERN
@@ -86,8 +86,7 @@ module RuboCop
86
86
 
87
87
  unless first_param.str_type?
88
88
  return true if options
89
- return true unless first_source.is_a?(String) &&
90
- first_source =~ DETERMINISTIC_REGEX
89
+ return true unless first_source.is_a?(String) && first_source =~ DETERMINISTIC_REGEX
91
90
 
92
91
  # This must be done after checking DETERMINISTIC_REGEX
93
92
  # Otherwise things like \s will trip us up
@@ -141,8 +140,7 @@ module RuboCop
141
140
  end
142
141
 
143
142
  def message(node, first_source, second_source)
144
- replacement_method =
145
- replacement_method(node, first_source, second_source)
143
+ replacement_method = replacement_method(node, first_source, second_source)
146
144
 
147
145
  format(MSG, prefer: replacement_method, current: node.method_name)
148
146
  end
@@ -152,8 +150,7 @@ module RuboCop
152
150
  end
153
151
 
154
152
  def remove_second_param(corrector, node, first_param)
155
- end_range = range_between(first_param.source_range.end_pos,
156
- node.source_range.end_pos)
153
+ end_range = range_between(first_param.source_range.end_pos, node.source_range.end_pos)
157
154
 
158
155
  corrector.replace(end_range, method_suffix(node))
159
156
  end
@@ -32,8 +32,7 @@ module RuboCop
32
32
  class TimesMap < Base
33
33
  extend AutoCorrector
34
34
 
35
- MESSAGE = 'Use `Array.new(%<count>s)` with a block ' \
36
- 'instead of `.times.%<map_or_collect>s`'
35
+ MESSAGE = 'Use `Array.new(%<count>s)` with a block instead of `.times.%<map_or_collect>s`'
37
36
  MESSAGE_ONLY_IF = 'only if `%<count>s` is always 0 or more'
38
37
  RESTRICT_ON_SEND = %i[map collect].freeze
39
38
 
@@ -44,14 +43,14 @@ module RuboCop
44
43
  def on_block(node)
45
44
  check(node)
46
45
  end
46
+ alias on_numblock on_block
47
47
 
48
48
  private
49
49
 
50
50
  def check(node)
51
51
  times_map_call(node) do |map_or_collect, count|
52
52
  add_offense(node, message: message(map_or_collect, count)) do |corrector|
53
- replacement = "Array.new(#{count.source}" \
54
- "#{map_or_collect.arguments.map { |arg| ", #{arg.source}" }.join})"
53
+ replacement = "Array.new(#{count.source}#{map_or_collect.arguments.map { |arg| ", #{arg.source}" }.join})"
55
54
 
56
55
  corrector.replace(map_or_collect.loc.expression, replacement)
57
56
  end
@@ -68,7 +67,7 @@ module RuboCop
68
67
  end
69
68
 
70
69
  def_node_matcher :times_map_call, <<~PATTERN
71
- {(block $(send (send $!nil? :times) {:map :collect}) ...)
70
+ {({block numblock} $(send (send $!nil? :times) {:map :collect}) ...)
72
71
  $(send (send $!nil? :times) {:map :collect} (block_pass ...))}
73
72
  PATTERN
74
73
  end
@@ -15,8 +15,7 @@ module RuboCop
15
15
  class UriDefaultParser < Base
16
16
  extend AutoCorrector
17
17
 
18
- MSG = 'Use `%<double_colon>sURI::DEFAULT_PARSER` instead of ' \
19
- '`%<double_colon>sURI::Parser.new`.'
18
+ MSG = 'Use `%<double_colon>sURI::DEFAULT_PARSER` instead of `%<double_colon>sURI::Parser.new`.'
20
19
  RESTRICT_ON_SEND = %i[new].freeze
21
20
 
22
21
  def_node_matcher :uri_parser_new?, <<~PATTERN
@@ -4,7 +4,7 @@ module RuboCop
4
4
  module Performance
5
5
  # This module holds the RuboCop Performance version information.
6
6
  module Version
7
- STRING = '1.14.3'
7
+ STRING = '1.15.1'
8
8
 
9
9
  def self.document_version
10
10
  STRING.match('\d+\.\d+').to_s
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.14.3
4
+ version: 1.15.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: 2022-07-17 00:00:00.000000000 Z
13
+ date: 2022-11-16 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rubocop
@@ -123,7 +123,7 @@ metadata:
123
123
  homepage_uri: https://docs.rubocop.org/rubocop-performance/
124
124
  changelog_uri: https://github.com/rubocop/rubocop-performance/blob/master/CHANGELOG.md
125
125
  source_code_uri: https://github.com/rubocop/rubocop-performance/
126
- documentation_uri: https://docs.rubocop.org/rubocop-performance/1.14/
126
+ documentation_uri: https://docs.rubocop.org/rubocop-performance/1.15/
127
127
  bug_tracker_uri: https://github.com/rubocop/rubocop-performance/issues
128
128
  rubygems_mfa_required: 'true'
129
129
  post_install_message: