rubocop 0.91.0 → 0.91.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 (61) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/config/default.yml +9 -1
  4. data/lib/rubocop.rb +1 -1
  5. data/lib/rubocop/comment_config.rb +9 -5
  6. data/lib/rubocop/cop/correctors/line_break_corrector.rb +1 -1
  7. data/lib/rubocop/cop/layout/case_indentation.rb +4 -7
  8. data/lib/rubocop/cop/layout/class_structure.rb +1 -1
  9. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +2 -2
  10. data/lib/rubocop/cop/layout/empty_line_after_multiline_condition.rb +4 -13
  11. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +14 -8
  12. data/lib/rubocop/cop/layout/empty_lines_around_attribute_accessor.rb +1 -1
  13. data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +1 -2
  14. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +10 -1
  15. data/lib/rubocop/cop/layout/space_around_equals_in_parameter_default.rb +2 -2
  16. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +7 -7
  17. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +4 -18
  18. data/lib/rubocop/cop/layout/space_inside_reference_brackets.rb +2 -2
  19. data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +2 -2
  20. data/lib/rubocop/cop/lint/constant_definition_in_block.rb +23 -3
  21. data/lib/rubocop/cop/lint/duplicate_rescue_exception.rb +2 -4
  22. data/lib/rubocop/cop/lint/identity_comparison.rb +5 -3
  23. data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +2 -5
  24. data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +22 -12
  25. data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +14 -4
  26. data/lib/rubocop/cop/lint/rescue_type.rb +0 -1
  27. data/lib/rubocop/cop/lint/shadowed_exception.rb +6 -6
  28. data/lib/rubocop/cop/lint/unreachable_loop.rb +1 -5
  29. data/lib/rubocop/cop/lint/useless_access_modifier.rb +3 -9
  30. data/lib/rubocop/cop/lint/useless_times.rb +11 -2
  31. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +25 -16
  32. data/lib/rubocop/cop/mixin/configurable_numbering.rb +3 -3
  33. data/lib/rubocop/cop/mixin/rescue_node.rb +1 -0
  34. data/lib/rubocop/cop/mixin/statement_modifier.rb +9 -3
  35. data/lib/rubocop/cop/mixin/visibility_help.rb +4 -16
  36. data/lib/rubocop/cop/style/combinable_loops.rb +5 -10
  37. data/lib/rubocop/cop/style/commented_keyword.rb +7 -8
  38. data/lib/rubocop/cop/style/hash_as_last_array_item.rb +15 -6
  39. data/lib/rubocop/cop/style/if_unless_modifier.rb +0 -4
  40. data/lib/rubocop/cop/style/keyword_parameters_order.rb +1 -6
  41. data/lib/rubocop/cop/style/multiline_block_chain.rb +2 -2
  42. data/lib/rubocop/cop/style/multiline_when_then.rb +1 -0
  43. data/lib/rubocop/cop/style/one_line_conditional.rb +3 -1
  44. data/lib/rubocop/cop/style/optional_boolean_parameter.rb +3 -0
  45. data/lib/rubocop/cop/style/random_with_offset.rb +3 -3
  46. data/lib/rubocop/cop/style/redundant_assignment.rb +1 -9
  47. data/lib/rubocop/cop/style/redundant_conditional.rb +4 -5
  48. data/lib/rubocop/cop/style/redundant_parentheses.rb +2 -3
  49. data/lib/rubocop/cop/style/redundant_percent_q.rb +9 -11
  50. data/lib/rubocop/cop/style/redundant_return.rb +17 -17
  51. data/lib/rubocop/cop/style/redundant_self.rb +7 -9
  52. data/lib/rubocop/cop/style/redundant_sort.rb +13 -24
  53. data/lib/rubocop/cop/style/redundant_sort_by.rb +5 -9
  54. data/lib/rubocop/cop/style/rescue_standard_error.rb +20 -16
  55. data/lib/rubocop/cop/style/ternary_parentheses.rb +1 -2
  56. data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +4 -3
  57. data/lib/rubocop/cop/util.rb +0 -1
  58. data/lib/rubocop/directive_comment.rb +32 -0
  59. data/lib/rubocop/version.rb +1 -1
  60. metadata +3 -3
  61. data/lib/rubocop/cop/tokens_util.rb +0 -84
@@ -33,7 +33,8 @@ module RuboCop
33
33
  extend AutoCorrector
34
34
 
35
35
  def on_hash(node)
36
- return unless last_array_item?(node)
36
+ return unless (array = containing_array(node))
37
+ return unless last_array_item?(array, node) && explicit_array?(array)
37
38
 
38
39
  if braces_style?
39
40
  check_braces(node)
@@ -44,12 +45,20 @@ module RuboCop
44
45
 
45
46
  private
46
47
 
47
- def last_array_item?(node)
48
- parent = node.parent
49
- return false unless parent&.array_type?
50
- return false if parent.child_nodes.all?(&:hash_type?)
48
+ def containing_array(hash_node)
49
+ parent = hash_node.parent
50
+ parent if parent&.array_type?
51
+ end
52
+
53
+ def last_array_item?(array, node)
54
+ return false if array.child_nodes.all?(&:hash_type?)
55
+
56
+ array.children.last.equal?(node)
57
+ end
51
58
 
52
- parent.children.last.equal?(node)
59
+ def explicit_array?(array)
60
+ # an implicit array cannot have an "unbraced" hash
61
+ array.square_brackets?
53
62
  end
54
63
 
55
64
  def check_braces(node)
@@ -157,10 +157,6 @@ module RuboCop
157
157
  #{indentation}end
158
158
  RUBY
159
159
  end
160
-
161
- def first_line_comment(node)
162
- processed_source.comment_at_line(node.loc.line)&.text
163
- end
164
160
  end
165
161
  end
166
162
  end
@@ -28,7 +28,7 @@ module RuboCop
28
28
  MSG = 'Place optional keyword parameters at the end of the parameters list.'
29
29
 
30
30
  def on_kwoptarg(node)
31
- kwarg_nodes = right_siblings_of(node).select(&:kwarg_type?)
31
+ kwarg_nodes = node.right_siblings.select(&:kwarg_type?)
32
32
  return if kwarg_nodes.empty?
33
33
 
34
34
  add_offense(node) do |corrector|
@@ -41,11 +41,6 @@ module RuboCop
41
41
 
42
42
  private
43
43
 
44
- # TODO: Use API from `rubocop-ast` when released.
45
- def right_siblings_of(node)
46
- node.parent.children[node.sibling_index + 1..-1]
47
- end
48
-
49
44
  def remove_kwargs(kwarg_nodes, corrector)
50
45
  kwarg_nodes.each do |kwarg|
51
46
  with_space = range_with_surrounding_space(range: kwarg.source_range)
@@ -22,7 +22,7 @@ module RuboCop
22
22
  # alive_threads.map do |t|
23
23
  # t.object_id
24
24
  # end
25
- class MultilineBlockChain < Cop
25
+ class MultilineBlockChain < Base
26
26
  include RangeHelp
27
27
 
28
28
  MSG = 'Avoid multi-line chains of blocks.'
@@ -36,7 +36,7 @@ module RuboCop
36
36
  range = range_between(receiver.loc.end.begin_pos,
37
37
  node.send_node.source_range.end_pos)
38
38
 
39
- add_offense(nil, location: range)
39
+ add_offense(range)
40
40
 
41
41
  # Done. If there are more blocks in the chain, they will be
42
42
  # found by subsequent calls to on_block.
@@ -58,6 +58,7 @@ module RuboCop
58
58
  private
59
59
 
60
60
  def require_then?(when_node)
61
+ return true if when_node.conditions.count >= 2
61
62
  return false unless when_node.body
62
63
 
63
64
  when_node.loc.line == when_node.body.loc.line
@@ -89,7 +89,9 @@ module RuboCop
89
89
  end
90
90
 
91
91
  def else_branch_to_multiline(else_branch, indentation)
92
- if else_branch.if_type? && else_branch.elsif?
92
+ if else_branch.nil?
93
+ 'end'
94
+ elsif else_branch.if_type? && else_branch.elsif?
93
95
  multiline_replacement(else_branch, indentation)
94
96
  else
95
97
  <<~RUBY.chomp
@@ -26,8 +26,11 @@ module RuboCop
26
26
  class OptionalBooleanParameter < Base
27
27
  MSG = 'Use keyword arguments when defining method with boolean argument.'
28
28
  BOOLEAN_TYPES = %i[true false].freeze
29
+ METHODS_EXCLUDED = %i[respond_to_missing?].freeze
29
30
 
30
31
  def on_def(node)
32
+ return if METHODS_EXCLUDED.include?(node.method_name)
33
+
31
34
  node.arguments.each do |arg|
32
35
  next unless arg.optarg_type?
33
36
 
@@ -36,7 +36,7 @@ module RuboCop
36
36
  (send
37
37
  {nil? (const {nil? cbase} :Random) (const {nil? cbase} :Kernel)}
38
38
  :rand
39
- {int irange erange}))
39
+ {int (irange int int) (erange int int)}))
40
40
  PATTERN
41
41
 
42
42
  def_node_matcher :rand_op_integer?, <<~PATTERN
@@ -44,7 +44,7 @@ module RuboCop
44
44
  (send
45
45
  {nil? (const {nil? cbase} :Random) (const {nil? cbase} :Kernel)}
46
46
  :rand
47
- {int irange erange})
47
+ {int (irange int int) (erange int int)})
48
48
  {:+ :-}
49
49
  int)
50
50
  PATTERN
@@ -54,7 +54,7 @@ module RuboCop
54
54
  (send
55
55
  {nil? (const {nil? cbase} :Random) (const {nil? cbase} :Kernel)}
56
56
  :rand
57
- {int irange erange})
57
+ {int (irange int int) (erange int int)})
58
58
  {:succ :pred :next})
59
59
  PATTERN
60
60
 
@@ -94,21 +94,13 @@ module RuboCop
94
94
  add_offense(assignment) do |corrector|
95
95
  expression = assignment.children[1]
96
96
  corrector.replace(assignment, expression.source)
97
- corrector.remove(right_sibling_of(assignment))
97
+ corrector.remove(assignment.right_sibling)
98
98
  end
99
99
  else
100
100
  last_expr = node.children.last
101
101
  check_branch(last_expr)
102
102
  end
103
103
  end
104
-
105
- def right_sibling_of(node)
106
- siblings_of(node)[node.sibling_index + 1]
107
- end
108
-
109
- def siblings_of(node)
110
- node.parent.children
111
- end
112
104
  end
113
105
  end
114
106
  end
@@ -24,8 +24,9 @@ module RuboCop
24
24
  #
25
25
  # # good
26
26
  # x != y
27
- class RedundantConditional < Cop
27
+ class RedundantConditional < Base
28
28
  include Alignment
29
+ extend AutoCorrector
29
30
 
30
31
  operators = RuboCop::AST::Node::COMPARISON_OPERATORS.to_a
31
32
  COMPARISON_OPERATOR_MATCHER = "{:#{operators.join(' :')}}"
@@ -36,11 +37,9 @@ module RuboCop
36
37
  def on_if(node)
37
38
  return unless offense?(node)
38
39
 
39
- add_offense(node)
40
- end
40
+ message = message(node)
41
41
 
42
- def autocorrect(node)
43
- lambda do |corrector|
42
+ add_offense(node, message: message) do |corrector|
44
43
  corrector.replace(node, replacement_condition(node))
45
44
  end
46
45
  end
@@ -175,10 +175,9 @@ module RuboCop
175
175
  def raised_to_power_negative_numeric?(begin_node, node)
176
176
  return false unless node.numeric_type?
177
177
 
178
- siblings = begin_node.parent&.children
179
- return false if siblings.nil?
178
+ next_sibling = begin_node.right_sibling
179
+ return false unless next_sibling
180
180
 
181
- next_sibling = siblings[begin_node.sibling_index + 1]
182
181
  base_value = node.children.first
183
182
 
184
183
  base_value.negative? && next_sibling == :**
@@ -17,7 +17,9 @@ module RuboCop
17
17
  # time = "8 o'clock"
18
18
  # question = '"What did you say?"'
19
19
  #
20
- class RedundantPercentQ < Cop
20
+ class RedundantPercentQ < Base
21
+ extend AutoCorrector
22
+
21
23
  MSG = 'Use `%<q_type>s` only for strings that contain both ' \
22
24
  'single quotes and double quotes%<extra>s.'
23
25
  DYNAMIC_MSG = ', or for dynamic strings that contain ' \
@@ -45,22 +47,18 @@ module RuboCop
45
47
  check(node)
46
48
  end
47
49
 
48
- def autocorrect(node)
49
- delimiter =
50
- /^%Q[^"]+$|'/.match?(node.source) ? QUOTE : SINGLE_QUOTE
51
- lambda do |corrector|
52
- corrector.replace(node.loc.begin, delimiter)
53
- corrector.replace(node.loc.end, delimiter)
54
- end
55
- end
56
-
57
50
  private
58
51
 
59
52
  def check(node)
60
53
  return unless start_with_percent_q_variant?(node)
61
54
  return if interpolated_quotes?(node) || allowed_percent_q?(node)
62
55
 
63
- add_offense(node)
56
+ add_offense(node) do |corrector|
57
+ delimiter = /^%Q[^"]+$|'/.match?(node.source) ? QUOTE : SINGLE_QUOTE
58
+
59
+ corrector.replace(node.loc.begin, delimiter)
60
+ corrector.replace(node.loc.end, delimiter)
61
+ end
64
62
  end
65
63
 
66
64
  def interpolated_quotes?(node)
@@ -47,8 +47,9 @@ module RuboCop
47
47
  # return x, y
48
48
  # end
49
49
  #
50
- class RedundantReturn < Cop
50
+ class RedundantReturn < Base
51
51
  include RangeHelp
52
+ extend AutoCorrector
52
53
 
53
54
  MSG = 'Redundant `return` detected.'
54
55
  MULTI_RETURN_MSG = 'To return multiple values, use an array.'
@@ -58,16 +59,6 @@ module RuboCop
58
59
  end
59
60
  alias on_defs on_def
60
61
 
61
- def autocorrect(node)
62
- lambda do |corrector|
63
- if node.arguments?
64
- correct_with_arguments(node, corrector)
65
- else
66
- correct_without_arguments(node, corrector)
67
- end
68
- end
69
- end
70
-
71
62
  private
72
63
 
73
64
  def correct_without_arguments(return_node, corrector)
@@ -108,8 +99,8 @@ module RuboCop
108
99
  when :return then check_return_node(node)
109
100
  when :case then check_case_node(node)
110
101
  when :if then check_if_node(node)
111
- when :rescue, :resbody
112
- check_rescue_node(node)
102
+ when :rescue then check_rescue_node(node)
103
+ when :resbody then check_resbody_node(node)
113
104
  when :ensure then check_ensure_node(node)
114
105
  when :begin, :kwbegin
115
106
  check_begin_node(node)
@@ -121,7 +112,13 @@ module RuboCop
121
112
  return if cop_config['AllowMultipleReturnValues'] &&
122
113
  node.children.size > 1
123
114
 
124
- add_offense(node, location: :keyword)
115
+ add_offense(node.loc.keyword, message: message(node)) do |corrector|
116
+ if node.arguments?
117
+ correct_with_arguments(node, corrector)
118
+ else
119
+ correct_without_arguments(node, corrector)
120
+ end
121
+ end
125
122
  end
126
123
 
127
124
  def check_case_node(node)
@@ -137,9 +134,12 @@ module RuboCop
137
134
  end
138
135
 
139
136
  def check_rescue_node(node)
140
- node.child_nodes.each do |child_node|
141
- check_branch(child_node)
142
- end
137
+ node.branches.each { |branch| check_branch(branch) }
138
+ check_branch(node.body) unless node.else?
139
+ end
140
+
141
+ def check_resbody_node(node)
142
+ check_branch(node.body)
143
143
  end
144
144
 
145
145
  def check_ensure_node(node)
@@ -41,7 +41,9 @@ module RuboCop
41
41
  # self.bar == bar # Resolves name clash with argument of the block.
42
42
  # end
43
43
  # end
44
- class RedundantSelf < Cop
44
+ class RedundantSelf < Base
45
+ extend AutoCorrector
46
+
45
47
  MSG = 'Redundant `self` detected.'
46
48
  KERNEL_METHODS = Kernel.methods(false)
47
49
  KEYWORDS = %i[alias and begin break case class def defined? do
@@ -106,20 +108,16 @@ module RuboCop
106
108
 
107
109
  return if allowed_send_node?(node)
108
110
 
109
- add_offense(node)
111
+ add_offense(node) do |corrector|
112
+ corrector.remove(node.receiver)
113
+ corrector.remove(node.loc.dot)
114
+ end
110
115
  end
111
116
 
112
117
  def on_block(node)
113
118
  add_scope(node, @local_variables_scopes[node])
114
119
  end
115
120
 
116
- def autocorrect(node)
117
- lambda do |corrector|
118
- corrector.remove(node.receiver)
119
- corrector.remove(node.loc.dot)
120
- end
121
- end
122
-
123
121
  private
124
122
 
125
123
  def add_scope(node, local_variables = [])
@@ -49,8 +49,9 @@ module RuboCop
49
49
  # # good
50
50
  # arr.max_by(&:foo)
51
51
  #
52
- class RedundantSort < Cop
52
+ class RedundantSort < Base
53
53
  include RangeHelp
54
+ extend AutoCorrector
54
55
 
55
56
  MSG = 'Use `%<suggestion>s` instead of '\
56
57
  '`%<sorter>s...%<accessor_source>s`.'
@@ -82,35 +83,23 @@ module RuboCop
82
83
  return
83
84
  end
84
85
 
85
- add_offense(ancestor,
86
- location: offense_range(sort_node, ancestor),
87
- message: message(ancestor,
88
- sorter,
89
- accessor))
90
- end
91
-
92
- def autocorrect(node)
93
- sort_node, sorter, accessor = redundant_sort?(node)
94
-
95
- lambda do |corrector|
96
- # Remove accessor, e.g. `first` or `[-1]`.
97
- corrector.remove(
98
- range_between(
99
- accessor_start(node),
100
- node.loc.expression.end_pos
101
- )
102
- )
86
+ message = message(ancestor, sorter, accessor)
103
87
 
104
- # Replace "sort" or "sort_by" with the appropriate min/max method.
105
- corrector.replace(
106
- sort_node.loc.selector,
107
- suggestion(sorter, accessor, arg_value(node))
108
- )
88
+ add_offense(offense_range(sort_node, ancestor), message: message) do |corrector|
89
+ autocorrect(corrector, ancestor, sort_node, sorter, accessor)
109
90
  end
110
91
  end
111
92
 
112
93
  private
113
94
 
95
+ def autocorrect(corrector, node, sort_node, sorter, accessor)
96
+ # Remove accessor, e.g. `first` or `[-1]`.
97
+ corrector.remove(range_between(accessor_start(node), node.loc.expression.end_pos))
98
+
99
+ # Replace "sort" or "sort_by" with the appropriate min/max method.
100
+ corrector.replace(sort_node.loc.selector, suggestion(sorter, accessor, arg_value(node)))
101
+ end
102
+
114
103
  def offense_range(sort_node, ancestor)
115
104
  range_between(sort_node.loc.selector.begin_pos, ancestor.loc.expression.end_pos)
116
105
  end
@@ -15,8 +15,9 @@ module RuboCop
15
15
  #
16
16
  # # good
17
17
  # array.sort
18
- class RedundantSortBy < Cop
18
+ class RedundantSortBy < Base
19
19
  include RangeHelp
20
+ extend AutoCorrector
20
21
 
21
22
  MSG = 'Use `sort` instead of `sort_by { |%<var>s| %<var>s }`.'
22
23
 
@@ -28,17 +29,12 @@ module RuboCop
28
29
  redundant_sort_by(node) do |send, var_name|
29
30
  range = sort_by_range(send, node)
30
31
 
31
- add_offense(node,
32
- location: range,
33
- message: format(MSG, var: var_name))
32
+ add_offense(range, message: format(MSG, var: var_name)) do |corrector|
33
+ corrector.replace(range, 'sort')
34
+ end
34
35
  end
35
36
  end
36
37
 
37
- def autocorrect(node)
38
- send = node.send_node
39
- ->(corrector) { corrector.replace(sort_by_range(send, node), 'sort') }
40
- end
41
-
42
38
  private
43
39
 
44
40
  def sort_by_range(send, node)
@@ -70,10 +70,11 @@ module RuboCop
70
70
  # rescue StandardError, SecurityError
71
71
  # bar
72
72
  # end
73
- class RescueStandardError < Cop
73
+ class RescueStandardError < Base
74
74
  include RescueNode
75
75
  include ConfigurableEnforcedStyle
76
76
  include RangeHelp
77
+ extend AutoCorrector
77
78
 
78
79
  MSG_IMPLICIT = 'Omit the error class when rescuing ' \
79
80
  '`StandardError` by itself.'
@@ -94,28 +95,31 @@ module RuboCop
94
95
  case style
95
96
  when :implicit
96
97
  rescue_standard_error?(node) do |error|
97
- add_offense(node,
98
- location: node.loc.keyword.join(error.loc.expression),
99
- message: MSG_IMPLICIT)
98
+ offense_for_implicit_enforced_style(node, error)
100
99
  end
101
100
  when :explicit
102
101
  rescue_without_error_class?(node) do
103
- add_offense(node, location: :keyword, message: MSG_EXPLICIT)
102
+ offense_for_exlicit_enforced_style(node)
104
103
  end
105
104
  end
106
105
  end
107
106
 
108
- def autocorrect(node)
109
- lambda do |corrector|
110
- case style
111
- when :implicit
112
- error = rescue_standard_error?(node)
113
- range = range_between(node.loc.keyword.end_pos,
114
- error.loc.expression.end_pos)
115
- corrector.remove(range)
116
- when :explicit
117
- corrector.insert_after(node.loc.keyword, ' StandardError')
118
- end
107
+ private
108
+
109
+ def offense_for_implicit_enforced_style(node, error)
110
+ range = node.loc.keyword.join(error.loc.expression)
111
+
112
+ add_offense(range, message: MSG_IMPLICIT) do |corrector|
113
+ error = rescue_standard_error?(node)
114
+ range = range_between(node.loc.keyword.end_pos, error.loc.expression.end_pos)
115
+
116
+ corrector.remove(range)
117
+ end
118
+ end
119
+
120
+ def offense_for_exlicit_enforced_style(node)
121
+ add_offense(node.loc.keyword, message: MSG_EXPLICIT) do |corrector|
122
+ corrector.insert_after(node.loc.keyword, ' StandardError')
119
123
  end
120
124
  end
121
125
  end