rubocop 0.20.1 → 0.21.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of rubocop might be problematic. Click here for more details.

Files changed (128) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +46 -0
  3. data/README.md +16 -4
  4. data/config/default.yml +37 -10
  5. data/config/enabled.yml +25 -7
  6. data/lib/rubocop.rb +15 -19
  7. data/lib/rubocop/cli.rb +2 -2
  8. data/lib/rubocop/config.rb +40 -3
  9. data/lib/rubocop/config_loader.rb +6 -37
  10. data/lib/rubocop/config_store.rb +0 -1
  11. data/lib/rubocop/cop/commissioner.rb +12 -9
  12. data/lib/rubocop/cop/cop.rb +17 -5
  13. data/lib/rubocop/cop/force.rb +41 -0
  14. data/lib/rubocop/cop/ignored_node.rb +10 -10
  15. data/lib/rubocop/cop/lint/ambiguous_operator.rb +1 -1
  16. data/lib/rubocop/cop/lint/ambiguous_regexp_literal.rb +2 -2
  17. data/lib/rubocop/cop/lint/block_alignment.rb +2 -2
  18. data/lib/rubocop/cop/lint/condition_position.rb +2 -0
  19. data/lib/rubocop/cop/lint/debugger.rb +17 -3
  20. data/lib/rubocop/cop/lint/end_alignment.rb +3 -11
  21. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +1 -1
  22. data/lib/rubocop/cop/lint/rescue_exception.rb +11 -0
  23. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +4 -6
  24. data/lib/rubocop/cop/lint/underscore_prefixed_variable_name.rb +39 -0
  25. data/lib/rubocop/cop/lint/unused_block_argument.rb +81 -0
  26. data/lib/rubocop/cop/lint/unused_method_argument.rb +52 -0
  27. data/lib/rubocop/cop/lint/useless_assignment.rb +6 -8
  28. data/lib/rubocop/cop/lint/useless_else_without_rescue.rb +6 -0
  29. data/lib/rubocop/cop/lint/useless_setter_call.rb +1 -1
  30. data/lib/rubocop/cop/lint/void.rb +1 -1
  31. data/lib/rubocop/cop/mixin/autocorrect_alignment.rb +2 -2
  32. data/lib/rubocop/cop/mixin/autocorrect_unless_changing_ast.rb +7 -3
  33. data/lib/rubocop/cop/mixin/check_assignment.rb +11 -0
  34. data/lib/rubocop/cop/mixin/check_methods.rb +12 -0
  35. data/lib/rubocop/cop/mixin/percent_literal.rb +26 -0
  36. data/lib/rubocop/cop/mixin/space_after_punctuation.rb +2 -2
  37. data/lib/rubocop/cop/mixin/string_help.rb +0 -4
  38. data/lib/rubocop/cop/rails/delegate.rb +109 -0
  39. data/lib/rubocop/cop/style/align_hash.rb +3 -3
  40. data/lib/rubocop/cop/style/class_and_module_children.rb +2 -2
  41. data/lib/rubocop/cop/style/colon_method_call.rb +2 -2
  42. data/lib/rubocop/cop/style/dot_position.rb +1 -1
  43. data/lib/rubocop/cop/style/encoding.rb +44 -16
  44. data/lib/rubocop/cop/style/indentation_width.rb +29 -19
  45. data/lib/rubocop/cop/style/lambda_call.rb +1 -1
  46. data/lib/rubocop/cop/style/line_end_concatenation.rb +1 -1
  47. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +3 -21
  48. data/lib/rubocop/cop/style/predicate_name.rb +1 -1
  49. data/lib/rubocop/cop/style/raise_args.rb +1 -1
  50. data/lib/rubocop/cop/style/redundant_begin.rb +18 -2
  51. data/lib/rubocop/cop/style/redundant_self.rb +2 -2
  52. data/lib/rubocop/cop/style/regexp_literal.rb +29 -37
  53. data/lib/rubocop/cop/style/space_after_method_name.rb +1 -1
  54. data/lib/rubocop/cop/style/string_literals.rb +1 -1
  55. data/lib/rubocop/cop/style/trailing_blank_lines.rb +37 -23
  56. data/lib/rubocop/cop/style/trailing_comma.rb +2 -3
  57. data/lib/rubocop/cop/style/trivial_accessors.rb +40 -4
  58. data/lib/rubocop/cop/style/unneeded_capital_w.rb +29 -0
  59. data/lib/rubocop/cop/team.rb +10 -2
  60. data/lib/rubocop/cop/util.rb +2 -2
  61. data/lib/rubocop/cop/{variable_inspector.rb → variable_force.rb} +45 -37
  62. data/lib/rubocop/cop/{variable_inspector → variable_force}/assignment.rb +1 -1
  63. data/lib/rubocop/cop/{variable_inspector → variable_force}/locatable.rb +1 -1
  64. data/lib/rubocop/cop/{variable_inspector → variable_force}/reference.rb +13 -1
  65. data/lib/rubocop/cop/{variable_inspector → variable_force}/scope.rb +9 -1
  66. data/lib/rubocop/cop/{variable_inspector → variable_force}/variable.rb +14 -4
  67. data/lib/rubocop/cop/{variable_inspector → variable_force}/variable_table.rb +1 -1
  68. data/lib/rubocop/file_inspector.rb +3 -1
  69. data/lib/rubocop/formatter/base_formatter.rb +1 -1
  70. data/lib/rubocop/formatter/disabled_config_formatter.rb +2 -2
  71. data/lib/rubocop/formatter/disabled_lines_formatter.rb +2 -2
  72. data/lib/rubocop/formatter/offense_count_formatter.rb +11 -10
  73. data/lib/rubocop/formatter/progress_formatter.rb +2 -2
  74. data/lib/rubocop/formatter/simple_text_formatter.rb +1 -1
  75. data/lib/rubocop/options.rb +74 -58
  76. data/lib/rubocop/path_util.rb +17 -2
  77. data/lib/rubocop/rake_task.rb +23 -5
  78. data/lib/rubocop/version.rb +1 -1
  79. data/relnotes/v0.21.0.md +45 -0
  80. data/rubocop-todo.yml +6 -6
  81. data/rubocop.gemspec +1 -1
  82. data/spec/rubocop/cli_spec.rb +170 -59
  83. data/spec/rubocop/config_spec.rb +48 -3
  84. data/spec/rubocop/config_store_spec.rb +3 -3
  85. data/spec/rubocop/cop/commissioner_spec.rb +9 -7
  86. data/spec/rubocop/cop/cop_spec.rb +0 -2
  87. data/spec/rubocop/cop/force_spec.rb +29 -0
  88. data/spec/rubocop/cop/lint/ambiguous_operator_spec.rb +2 -2
  89. data/spec/rubocop/cop/lint/ambiguous_regexp_literal_spec.rb +1 -1
  90. data/spec/rubocop/cop/lint/block_alignment_spec.rb +24 -24
  91. data/spec/rubocop/cop/lint/condition_position_spec.rb +7 -5
  92. data/spec/rubocop/cop/lint/debugger_spec.rb +26 -9
  93. data/spec/rubocop/cop/lint/end_alignment_spec.rb +6 -3
  94. data/spec/rubocop/cop/lint/invalid_character_literal_spec.rb +7 -6
  95. data/spec/rubocop/cop/lint/rescue_exception_spec.rb +36 -0
  96. data/spec/rubocop/cop/lint/shadowing_outer_local_variable_spec.rb +4 -4
  97. data/spec/rubocop/cop/lint/underscore_prefixed_variable_name_spec.rb +179 -0
  98. data/spec/rubocop/cop/lint/unused_block_argument_spec.rb +147 -0
  99. data/spec/rubocop/cop/lint/unused_method_argument_spec.rb +140 -0
  100. data/spec/rubocop/cop/lint/useless_assignment_spec.rb +50 -48
  101. data/spec/rubocop/cop/lint/useless_else_without_rescue_spec.rb +1 -1
  102. data/spec/rubocop/cop/lint/useless_setter_call_spec.rb +2 -0
  103. data/spec/rubocop/cop/rails/delegate_spec.rb +152 -0
  104. data/spec/rubocop/cop/style/encoding_spec.rb +131 -36
  105. data/spec/rubocop/cop/style/indentation_width_spec.rb +79 -0
  106. data/spec/rubocop/cop/style/redundant_begin_spec.rb +32 -0
  107. data/spec/rubocop/cop/style/regexp_literal_spec.rb +83 -13
  108. data/spec/rubocop/cop/style/string_literals_spec.rb +9 -3
  109. data/spec/rubocop/cop/style/trailing_blank_lines_spec.rb +65 -25
  110. data/spec/rubocop/cop/style/trivial_accessors_spec.rb +76 -0
  111. data/spec/rubocop/cop/style/unneeded_capital_w_spec.rb +85 -0
  112. data/spec/rubocop/cop/team_spec.rb +43 -0
  113. data/spec/rubocop/cop/{variable_inspector → variable_force}/assignment_spec.rb +3 -3
  114. data/spec/rubocop/cop/{variable_inspector → variable_force}/locatable_spec.rb +3 -3
  115. data/spec/rubocop/cop/{variable_inspector → variable_force}/scope_spec.rb +30 -2
  116. data/spec/rubocop/cop/{variable_inspector → variable_force}/variable_spec.rb +12 -27
  117. data/spec/rubocop/cop/{variable_inspector → variable_force}/variable_table_spec.rb +1 -1
  118. data/spec/rubocop/cop/{variable_inspector_spec.rb → variable_force_spec.rb} +4 -8
  119. data/spec/rubocop/formatter/base_formatter_spec.rb +2 -2
  120. data/spec/rubocop/formatter/offense_count_formatter_spec.rb +1 -1
  121. data/spec/rubocop/formatter/progress_formatter_spec.rb +1 -1
  122. data/spec/rubocop/options_spec.rb +2 -2
  123. data/spec/rubocop/path_util_spec.rb +47 -14
  124. data/spec/spec_helper.rb +9 -3
  125. data/spec/support/file_helper.rb +2 -0
  126. metadata +43 -26
  127. data/lib/rubocop/cop/style/final_newline.rb +0 -29
  128. data/spec/rubocop/cop/style/final_newline_spec.rb +0 -30
@@ -15,7 +15,7 @@ module Rubocop
15
15
  true
16
16
  end
17
17
 
18
- def deltas_for_first_pair(*_)
18
+ def deltas_for_first_pair(*)
19
19
  {} # The first pair is always considered correct.
20
20
  end
21
21
 
@@ -35,7 +35,7 @@ module Rubocop
35
35
  !any_pairs_on_the_same_line?(node) && all_have_same_sparator?(node)
36
36
  end
37
37
 
38
- def deltas(first_pair, prev_pair, current_pair)
38
+ def deltas(first_pair, _prev_pair, current_pair)
39
39
  key_delta = key_delta(first_pair, current_pair)
40
40
  current_separator = current_pair.loc.operator
41
41
  separator_delta = separator_delta(first_pair, current_separator,
@@ -117,7 +117,7 @@ module Rubocop
117
117
 
118
118
  # Handles calculation of deltas when the enforced style is 'separator'.
119
119
  class SeparatorAlignment < AlignmentOfValues
120
- def deltas_for_first_pair(first_pair, node)
120
+ def deltas_for_first_pair(*)
121
121
  {} # The first pair is always considered correct.
122
122
  end
123
123
 
@@ -52,11 +52,11 @@ module Rubocop
52
52
  end
53
53
 
54
54
  def check_compact_style(node, body)
55
- return unless one_child?(node, body) && !compact_node_name?(node)
55
+ return unless one_child?(body) && !compact_node_name?(node)
56
56
  add_offense(node, :name, COMPACT_MSG)
57
57
  end
58
58
 
59
- def one_child?(node, body)
59
+ def one_child?(body)
60
60
  body && body.type != :begin
61
61
  end
62
62
 
@@ -9,11 +9,11 @@ module Rubocop
9
9
  MSG = 'Do not use `::` for method calls.'
10
10
 
11
11
  def on_send(node)
12
- receiver, _method_name, *_args = *node
12
+ receiver, method_name, *_args = *node
13
13
 
14
14
  # discard methods with nil receivers and op methods(like [])
15
15
  return unless receiver && node.loc.dot && node.loc.dot.is?('::')
16
- return if allowed_name(_method_name.to_s)
16
+ return if allowed_name(method_name.to_s)
17
17
 
18
18
  add_offense(node, :dot)
19
19
  end
@@ -19,7 +19,7 @@ module Rubocop
19
19
 
20
20
  private
21
21
 
22
- def message(node)
22
+ def message(_node)
23
23
  'Place the . on the ' +
24
24
  case style
25
25
  when :leading
@@ -3,27 +3,55 @@
3
3
  module Rubocop
4
4
  module Cop
5
5
  module Style
6
- # This cop checks whether the source file has a
7
- # utf-8 encoding comment. This check makes sense only
8
- # in Ruby 1.9, since in 2.0+ utf-8 is the default source file
9
- # encoding.
6
+ # This cop checks whether the source file has a utf-8 encoding comment or
7
+ # not. This check makes sense only in Ruby 1.9, since in 2.0+ utf-8 is
8
+ # the default source file encoding. There are two style:
9
+ #
10
+ # when_needed - only enforce an encoding comment if there are non ASCII
11
+ # characters, otherwise report an offense
12
+ # always - enforce encoding comment in all files
10
13
  class Encoding < Cop
11
- MSG = 'Missing utf-8 encoding comment.'
14
+ include ConfigurableEnforcedStyle
15
+
16
+ MSG_MISSING = 'Missing utf-8 encoding comment.'
17
+ MSG_UNNECESSARY = 'Unnecessary utf-8 encoding comment.'
12
18
 
13
19
  def investigate(processed_source)
14
- unless RUBY_VERSION >= '2.0.0'
15
- line_number = 0
16
- line_number += 1 if processed_source[line_number] =~ /^#!/
17
- line = processed_source[line_number]
18
- unless line =~ /#.*coding\s?[:=]\s?(UTF|utf)-8/
19
- add_offense(nil,
20
- source_range(processed_source.buffer,
21
- processed_source[0...line_number],
22
- 0, 1),
23
- MSG)
24
- end
20
+ return if RUBY_VERSION >= '2.0.0'
21
+ return if processed_source.buffer.source.empty?
22
+
23
+ line_number = encoding_line_number(processed_source)
24
+ message = offense(processed_source, line_number)
25
+
26
+ if message
27
+ add_offense(nil,
28
+ source_range(processed_source.buffer,
29
+ processed_source[0...line_number],
30
+ 0, 1),
31
+ message)
32
+ end
33
+ end
34
+
35
+ private
36
+
37
+ def offense(processed_source, line_number)
38
+ line = processed_source[line_number]
39
+ encoding_present = line =~ /#.*coding\s?[:=]\s?(UTF|utf)-8/
40
+ ascii_only = processed_source.buffer.source.ascii_only?
41
+ always_encode = style == :always
42
+
43
+ if !encoding_present && (always_encode || !ascii_only)
44
+ MSG_MISSING
45
+ elsif !always_encode && ascii_only && encoding_present
46
+ MSG_UNNECESSARY
25
47
  end
26
48
  end
49
+
50
+ def encoding_line_number(processed_source)
51
+ line_number = 0
52
+ line_number += 1 if processed_source[line_number] =~ /^#!/
53
+ line_number
54
+ end
27
55
  end
28
56
  end
29
57
  end
@@ -27,8 +27,10 @@ module Rubocop
27
27
  def on_block(node)
28
28
  _method, _args, body = *node
29
29
  # Check body against end/} indentation. Checking against variable
30
- # assignments, etc, would be more difficult.
31
- check_indentation(node.loc.end, body)
30
+ # assignments, etc, would be more difficult. The end/} must be at the
31
+ # beginning of its line.
32
+ loc = node.loc
33
+ check_indentation(loc.end, body) if begins_its_line?(loc.end)
32
34
  end
33
35
 
34
36
  def on_module(node)
@@ -41,8 +43,19 @@ module Rubocop
41
43
  members.each { |m| check_indentation(node.loc.keyword, m) }
42
44
  end
43
45
 
46
+ def on_send(node)
47
+ super
48
+ receiver, method_name, *args = *node
49
+
50
+ if visibility_and_def_on_same_line?(receiver, method_name, args)
51
+ _method_name, _args, body = *args.first
52
+ check_indentation(node.loc.expression, body)
53
+ ignore_node(args.first)
54
+ end
55
+ end
56
+
44
57
  def check(node, _method_name, _args, body)
45
- check_indentation(node.loc.keyword, body)
58
+ check_indentation(node.loc.keyword, body) unless ignored_node?(node)
46
59
  end
47
60
 
48
61
  def on_for(node)
@@ -92,6 +105,11 @@ module Rubocop
92
105
 
93
106
  private
94
107
 
108
+ def begins_its_line?(range)
109
+ source_before_end = range.source_buffer.source[0...range.begin_pos]
110
+ source_before_end =~ /\n\s*\Z/
111
+ end
112
+
95
113
  def check_assignment(node, rhs)
96
114
  # If there are method calls chained to the right hand side of the
97
115
  # assignment, we let rhs be the receiver of those method calls before
@@ -99,12 +117,8 @@ module Rubocop
99
117
  rhs = first_part_of_call_chain(rhs)
100
118
 
101
119
  if rhs
102
- end_alignment_config = config.for_cop('EndAlignment')
103
- style = if end_alignment_config['Enabled']
104
- end_alignment_config['AlignWith']
105
- else
106
- 'keyword'
107
- end
120
+ end_config = config.for_cop('EndAlignment')
121
+ style = end_config['Enabled'] ? end_config['AlignWith'] : 'keyword'
108
122
  base = style == 'variable' ? node : rhs
109
123
 
110
124
  case rhs.type
@@ -141,7 +155,7 @@ module Rubocop
141
155
  return if starts_with_access_modifier?(body_node)
142
156
 
143
157
  # Don't check indentation if the line doesn't start with the body.
144
- # For example lines like "else do_something".
158
+ # For example, lines like "else do_something".
145
159
  first_char_pos_on_line = body_node.loc.expression.source_line =~ /\S/
146
160
  return unless body_node.loc.column == first_char_pos_on_line
147
161
 
@@ -154,15 +168,11 @@ module Rubocop
154
168
  body_node = body_node.children.first if body_node.type == :begin
155
169
 
156
170
  expr = body_node.loc.expression
157
- pos = if indentation >= 0
158
- (expr.begin_pos - indentation)..expr.begin_pos
159
- else
160
- expr.begin_pos..(expr.begin_pos - indentation)
161
- end
162
-
163
- add_offense(body_node,
164
- Parser::Source::Range.new(expr.source_buffer,
165
- pos.begin, pos.end),
171
+ begin_pos, ind = expr.begin_pos, expr.begin_pos - indentation
172
+ pos = indentation >= 0 ? ind..begin_pos : begin_pos..ind
173
+
174
+ r = Parser::Source::Range.new(expr.source_buffer, pos.begin, pos.end)
175
+ add_offense(body_node, r,
166
176
  format("Use #{CORRECT_INDENTATION} (not %d) spaces " \
167
177
  'for indentation.', indentation))
168
178
  end
@@ -50,7 +50,7 @@ module Rubocop
50
50
  end
51
51
  end
52
52
 
53
- def message(node)
53
+ def message(_node)
54
54
  if style == :call
55
55
  'Prefer the use of `lambda.call(...)` over `lambda.(...)`.'
56
56
  else
@@ -20,7 +20,7 @@ module Rubocop
20
20
  # 'bala'
21
21
  #
22
22
  class LineEndConcatenation < Cop
23
- MSG = 'Use \\ instead of + to concatenate those strings.'
23
+ MSG = 'Use \\ instead of + or << to concatenate those strings.'
24
24
 
25
25
  def on_send(node)
26
26
  add_offense(node, :selector) if offending_node?(node)
@@ -3,8 +3,10 @@
3
3
  module Rubocop
4
4
  module Cop
5
5
  module Style
6
- # This cop enforces the consitent useage of `%`-literal delimiters.
6
+ # This cop enforces the consistent usage of `%`-literal delimiters.
7
7
  class PercentLiteralDelimiters < Cop
8
+ include PercentLiteral
9
+
8
10
  def on_array(node)
9
11
  process(node, '%w', '%W', '%i')
10
12
  end
@@ -57,16 +59,6 @@ module Rubocop
57
59
  end
58
60
  end
59
61
 
60
- def process(node, *types)
61
- on_percent_literal(node, types) if percent_literal?(node)
62
- end
63
-
64
- def percent_literal?(node)
65
- if (begin_source = begin_source(node))
66
- begin_source.start_with?('%')
67
- end
68
- end
69
-
70
62
  def on_percent_literal(node, types)
71
63
  type = type(node)
72
64
  if types.include?(type) &&
@@ -76,10 +68,6 @@ module Rubocop
76
68
  end
77
69
  end
78
70
 
79
- def type(node)
80
- node.loc.begin.source[0..-2]
81
- end
82
-
83
71
  def preferred_delimiters(type)
84
72
  cop_config['PreferredDelimiters'][type].split(//)
85
73
  end
@@ -125,12 +113,6 @@ module Rubocop
125
113
  .any? { |s| preferred_delimiters.any? { |d| s.include?(d) } }
126
114
  end
127
115
 
128
- def begin_source(node)
129
- if node.loc.respond_to?(:begin) && node.loc.begin
130
- node.loc.begin.source
131
- end
132
- end
133
-
134
116
  def string_source(node)
135
117
  if node.is_a?(String)
136
118
  node
@@ -22,7 +22,7 @@ module Rubocop
22
22
 
23
23
  private
24
24
 
25
- def check(node, method_name, args, _body)
25
+ def check(node, method_name, _args, _body)
26
26
  prefix_blacklist.each do |prefix|
27
27
  if method_name.to_s.start_with?(prefix)
28
28
  add_offense(node, :name,
@@ -58,7 +58,7 @@ module Rubocop
58
58
  when :compact
59
59
  "Provide an exception object as an argument to `#{method}`."
60
60
  when :exploded
61
- "Provide an exception class and message as " \
61
+ 'Provide an exception class and message as ' \
62
62
  "arguments to `#{method}`."
63
63
  end
64
64
  end
@@ -22,13 +22,29 @@ module Rubocop
22
22
 
23
23
  MSG = 'Redundant `begin` block detected.'
24
24
 
25
- private
26
-
27
25
  def check(_node, _method_name, _args, body)
28
26
  return unless body && body.type == :kwbegin
29
27
 
30
28
  add_offense(body, :begin)
31
29
  end
30
+
31
+ def autocorrect(node)
32
+ @corrections << lambda do |corrector|
33
+ child = node.children.first
34
+
35
+ begin_indent = node.loc.column
36
+ child_indent = child.loc.column
37
+
38
+ indent_diff = child_indent - begin_indent
39
+
40
+ corrector.replace(
41
+ range_with_surrounding_space(node.loc.expression),
42
+ range_with_surrounding_space(
43
+ child.loc.expression
44
+ ).source.gsub(/^\s{#{indent_diff}}/, '')
45
+ )
46
+ end
47
+ end
32
48
  end
33
49
  end
34
50
  end
@@ -67,11 +67,11 @@ module Rubocop
67
67
 
68
68
  # Using self.x to distinguish from local variable x
69
69
 
70
- def on_def(node)
70
+ def on_def(_node)
71
71
  @local_variables = []
72
72
  end
73
73
 
74
- def on_defs(node)
74
+ def on_defs(_node)
75
75
  @local_variables = []
76
76
  end
77
77
 
@@ -11,17 +11,17 @@ module Rubocop
11
11
  string_parts = node.children.select { |child| child.type == :str }
12
12
  total_string = string_parts.map { |s| s.loc.expression.source }.join
13
13
  slashes = total_string.count('/')
14
- if node.loc.begin.is?('/')
14
+ delimiter_start = node.loc.begin.source[0]
15
+
16
+ if delimiter_start == '/'
15
17
  if slashes > max_slashes
16
- add_offense(node, :expression, error_message('')) do
17
- self.slash_count_in_slashes_regexp = slashes
18
- end
18
+ add_offense(node, :expression, error_message(''))
19
19
  end
20
20
  elsif slashes <= max_slashes
21
- add_offense(node, :expression, error_message('only ')) do
22
- self.slash_count_in_percent_r_regexp = slashes
23
- end
21
+ add_offense(node, :expression, error_message('only '))
24
22
  end
23
+
24
+ configure_max(delimiter_start, slashes) if @options[:auto_gen_config]
25
25
  end
26
26
 
27
27
  private
@@ -34,38 +34,30 @@ module Rubocop
34
34
  m
35
35
  end
36
36
 
37
- # MaxSlashes must be set equal to the highest number of slashes used
38
- # within // to avoid reports.
39
- def slash_count_in_slashes_regexp=(value)
40
- configure_slashes(value) { |current| [current, value].max }
41
- end
42
-
43
- # MaxSlashes must be set one less than the highest number of slashes
44
- # used within %r{} to avoid reports.
45
- def slash_count_in_percent_r_regexp=(value)
46
- configure_slashes(value - 1) { |current| [current, value - 1].min }
47
- end
37
+ def configure_max(delimiter_start, value)
38
+ @slash_count ||= { '/' => Set.new([0]), '%' => Set.new([100_000]) }
39
+ @slash_count[delimiter_start].add(value)
48
40
 
49
- def configure_slashes(value)
50
- cfg = self.config_to_allow_offenses ||= {}
51
- return if cfg.key?('Enabled')
41
+ # To avoid reports, MaxSlashes must be set equal to the highest
42
+ # number of slashes used within //, and also one less than the
43
+ # highest number of slashes used within %r{}. If no value can satisfy
44
+ # both requirements, just disable.
45
+ max = @slash_count['/'].max
46
+ min = @slash_count['%'].min
52
47
 
53
- if cfg['MaxSlashes']
54
- value = yield cfg['MaxSlashes']
55
- if cfg['MaxSlashes'] > max_slashes && value < max_slashes ||
56
- cfg['MaxSlashes'] < max_slashes && value > max_slashes
57
- # We can't both increase and decrease MaxSlashes to avoid
58
- # reports. This means that the only option is to disable the cop.
59
- cfg = self.config_to_allow_offenses = { 'Enabled' => false }
60
- return
61
- end
62
- end
63
-
64
- if value >= 0
65
- cfg['MaxSlashes'] = value
66
- else
67
- self.config_to_allow_offenses = { 'Enabled' => false }
68
- end
48
+ self.config_to_allow_offenses = if max > max_slashes
49
+ if max < min
50
+ { 'MaxSlashes' => max }
51
+ else
52
+ { 'Enabled' => false }
53
+ end
54
+ elsif min < max_slashes + 1
55
+ if max < min
56
+ { 'MaxSlashes' => min - 1 }
57
+ else
58
+ { 'Enabled' => false }
59
+ end
60
+ end
69
61
  end
70
62
 
71
63
  def error_message(word)