rubocop 0.69.0 → 0.70.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.
Files changed (32) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/config/default.yml +17 -1
  4. data/lib/rubocop.rb +1 -0
  5. data/lib/rubocop/ast/builder.rb +37 -37
  6. data/lib/rubocop/ast/node/mixin/method_dispatch_node.rb +10 -0
  7. data/lib/rubocop/cached_data.rb +2 -2
  8. data/lib/rubocop/config.rb +9 -1
  9. data/lib/rubocop/config_loader.rb +2 -2
  10. data/lib/rubocop/config_loader_resolver.rb +3 -2
  11. data/lib/rubocop/cop/generator.rb +7 -1
  12. data/lib/rubocop/cop/layout/align_hash.rb +74 -31
  13. data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +6 -6
  14. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +75 -4
  15. data/lib/rubocop/cop/layout/indentation_width.rb +1 -7
  16. data/lib/rubocop/cop/lint/ambiguous_operator.rb +5 -5
  17. data/lib/rubocop/cop/lint/handle_exceptions.rb +47 -8
  18. data/lib/rubocop/cop/lint/number_conversion.rb +7 -0
  19. data/lib/rubocop/cop/lint/useless_else_without_rescue.rb +3 -0
  20. data/lib/rubocop/cop/mixin/configurable_naming.rb +1 -1
  21. data/lib/rubocop/cop/mixin/configurable_numbering.rb +2 -2
  22. data/lib/rubocop/cop/mixin/ignored_method_patterns.rb +19 -0
  23. data/lib/rubocop/cop/rails/refute_methods.rb +13 -13
  24. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +17 -3
  25. data/lib/rubocop/cop/variable_force/scope.rb +3 -3
  26. data/lib/rubocop/formatter/formatter_set.rb +13 -13
  27. data/lib/rubocop/formatter/html_formatter.rb +4 -4
  28. data/lib/rubocop/formatter/json_formatter.rb +16 -16
  29. data/lib/rubocop/formatter/simple_text_formatter.rb +4 -4
  30. data/lib/rubocop/options.rb +89 -83
  31. data/lib/rubocop/version.rb +1 -1
  32. metadata +4 -24
@@ -117,9 +117,9 @@ module RuboCop
117
117
 
118
118
  add_offense(right_paren,
119
119
  location: right_paren,
120
- message: message(correct_column,
121
- left_paren,
122
- right_paren))
120
+ message: message(correct_column,
121
+ left_paren,
122
+ right_paren))
123
123
  end
124
124
 
125
125
  def check_for_no_elements(node)
@@ -137,9 +137,9 @@ module RuboCop
137
137
  @column_delta = correct_column - right_paren.column
138
138
  add_offense(right_paren,
139
139
  location: right_paren,
140
- message: message(correct_column,
141
- left_paren,
142
- right_paren))
140
+ message: message(correct_column,
141
+ left_paren,
142
+ right_paren))
143
143
  end
144
144
 
145
145
  def expected_column(left_paren, elements)
@@ -5,7 +5,7 @@ module RuboCop
5
5
  module Layout
6
6
  # Access modifiers should be surrounded by blank lines.
7
7
  #
8
- # @example
8
+ # @example EnforcedStyle: around (default)
9
9
  #
10
10
  # # bad
11
11
  # class Foo
@@ -22,13 +22,35 @@ module RuboCop
22
22
  #
23
23
  # def baz; end
24
24
  # end
25
+ #
26
+ # @example EnforcedStyle: only_before
27
+ #
28
+ # # bad
29
+ # class Foo
30
+ # def bar; end
31
+ # private
32
+ # def baz; end
33
+ # end
34
+ #
35
+ # # good
36
+ # class Foo
37
+ # def bar; end
38
+ #
39
+ # private
40
+ # def baz; end
41
+ # end
42
+ #
25
43
  class EmptyLinesAroundAccessModifier < Cop
44
+ include ConfigurableEnforcedStyle
26
45
  include RangeHelp
27
46
 
28
47
  MSG_AFTER = 'Keep a blank line after `%<modifier>s`.'
29
48
  MSG_BEFORE_AND_AFTER = 'Keep a blank line before and after ' \
30
49
  '`%<modifier>s`.'
31
50
 
51
+ MSG_BEFORE_FOR_ONLY_BEFORE = 'Keep a blank line before `%<modifier>s`.'
52
+ MSG_AFTER_FOR_ONLY_BEFORE = 'Remove a blank line after `%<modifier>s`.'
53
+
32
54
  def initialize(config = nil, options = nil)
33
55
  super
34
56
 
@@ -63,7 +85,12 @@ module RuboCop
63
85
  def on_send(node)
64
86
  return unless node.bare_access_modifier?
65
87
 
66
- return if empty_lines_around?(node)
88
+ case style
89
+ when :around
90
+ return if empty_lines_around?(node)
91
+ when :only_before
92
+ return if allowed_only_before_style?(node)
93
+ end
67
94
 
68
95
  add_offense(node)
69
96
  end
@@ -76,14 +103,35 @@ module RuboCop
76
103
  corrector.insert_before(line, "\n")
77
104
  end
78
105
 
106
+ correct_next_line_if_denied_style(corrector, node, line)
107
+ end
108
+ end
109
+
110
+ private
111
+
112
+ def allowed_only_before_style?(node)
113
+ if node.special_modifier?
114
+ return false if next_line_empty?(node.last_line)
115
+ end
116
+
117
+ previous_line_empty?(node.first_line)
118
+ end
119
+
120
+ def correct_next_line_if_denied_style(corrector, node, line)
121
+ case style
122
+ when :around
79
123
  unless next_line_empty?(node.last_line)
80
124
  corrector.insert_after(line, "\n")
81
125
  end
126
+ when :only_before
127
+ if next_line_empty?(node.last_line)
128
+ range = next_empty_line_range(node)
129
+
130
+ corrector.remove(range)
131
+ end
82
132
  end
83
133
  end
84
134
 
85
- private
86
-
87
135
  def previous_line_ignoring_comments(processed_source, send_line)
88
136
  processed_source[0..send_line - 2].reverse.find do |line|
89
137
  !comment_line?(line)
@@ -128,7 +176,20 @@ module RuboCop
128
176
  line == @class_or_module_def_last_line - 1
129
177
  end
130
178
 
179
+ def next_empty_line_range(node)
180
+ source_range(processed_source.buffer, node.last_line + 1, 0)
181
+ end
182
+
131
183
  def message(node)
184
+ case style
185
+ when :around
186
+ message_for_around_style(node)
187
+ when :only_before
188
+ message_for_only_before_style(node)
189
+ end
190
+ end
191
+
192
+ def message_for_around_style(node)
132
193
  send_line = node.first_line
133
194
 
134
195
  if block_start?(send_line) ||
@@ -138,6 +199,16 @@ module RuboCop
138
199
  format(MSG_BEFORE_AND_AFTER, modifier: node.loc.selector.source)
139
200
  end
140
201
  end
202
+
203
+ def message_for_only_before_style(node)
204
+ modifier = node.loc.selector.source
205
+
206
+ if next_line_empty?(node.last_line)
207
+ format(MSG_AFTER_FOR_ONLY_BEFORE, modifier: modifier)
208
+ else
209
+ format(MSG_BEFORE_FOR_ONLY_BEFORE, modifier: modifier)
210
+ end
211
+ end
141
212
  end
142
213
  end
143
214
  end
@@ -52,8 +52,6 @@ module RuboCop
52
52
  MSG = 'Use %<configured_indentation_width>d (not %<indentation>d) ' \
53
53
  'spaces for%<name>s indentation.'
54
54
 
55
- SPECIAL_MODIFIERS = %w[private protected].freeze
56
-
57
55
  def_node_matcher :access_modifier?, <<-PATTERN
58
56
  [(send ...) access_modifier?]
59
57
  PATTERN
@@ -188,7 +186,7 @@ module RuboCop
188
186
  def each_member(members)
189
187
  previous_modifier = nil
190
188
  members.first.children.each do |member|
191
- if member.send_type? && special_modifier?(member)
189
+ if member.send_type? && member.special_modifier?
192
190
  previous_modifier = member
193
191
  elsif previous_modifier
194
192
  yield member, previous_modifier.source_range
@@ -197,10 +195,6 @@ module RuboCop
197
195
  end
198
196
  end
199
197
 
200
- def special_modifier?(node)
201
- node.bare_access_modifier? && SPECIAL_MODIFIERS.include?(node.source)
202
- end
203
-
204
198
  def indentation_consistency_style
205
199
  config.for_cop('Layout/IndentationConsistency')['EnforcedStyle']
206
200
  end
@@ -24,11 +24,11 @@ module RuboCop
24
24
  include ParserDiagnostic
25
25
 
26
26
  AMBIGUITIES = {
27
- '+' => { actual: 'positive number', possible: 'addition' },
28
- '-' => { actual: 'negative number', possible: 'subtraction' },
29
- '*' => { actual: 'splat', possible: 'multiplication' },
30
- '&' => { actual: 'block', possible: 'binary AND' },
31
- '**' => { actual: 'keyword splat', possible: 'exponent' }
27
+ '+' => { actual: 'positive number', possible: 'addition' },
28
+ '-' => { actual: 'negative number', possible: 'subtraction' },
29
+ '*' => { actual: 'splat', possible: 'multiplication' },
30
+ '&' => { actual: 'block', possible: 'binary AND' },
31
+ '**' => { actual: 'keyword splat', possible: 'exponent' }
32
32
  }.each do |key, hash|
33
33
  hash[:operator] = key
34
34
  end
@@ -5,50 +5,89 @@ module RuboCop
5
5
  module Lint
6
6
  # This cop checks for *rescue* blocks with no body.
7
7
  #
8
- # @example
8
+ # @example AllowComments: false (default)
9
9
  #
10
10
  # # bad
11
+ # def some_method
12
+ # do_something
13
+ # rescue
14
+ # end
11
15
  #
16
+ # # bad
12
17
  # def some_method
13
18
  # do_something
14
19
  # rescue
15
20
  # # do nothing
16
21
  # end
17
22
  #
18
- # @example
19
- #
20
23
  # # bad
24
+ # begin
25
+ # do_something
26
+ # rescue
27
+ # end
21
28
  #
29
+ # # bad
22
30
  # begin
23
31
  # do_something
24
32
  # rescue
25
33
  # # do nothing
26
34
  # end
27
35
  #
28
- # @example
36
+ # # good
37
+ # def some_method
38
+ # do_something
39
+ # rescue
40
+ # handle_exception
41
+ # end
29
42
  #
30
43
  # # good
44
+ # begin
45
+ # do_something
46
+ # rescue
47
+ # handle_exception
48
+ # end
49
+ #
50
+ # @example AllowComments: true
31
51
  #
52
+ # # bad
32
53
  # def some_method
33
54
  # do_something
34
55
  # rescue
35
- # handle_exception
36
56
  # end
37
57
  #
38
- # @example
58
+ # # bad
59
+ # begin
60
+ # do_something
61
+ # rescue
62
+ # end
39
63
  #
40
64
  # # good
65
+ # def some_method
66
+ # do_something
67
+ # rescue
68
+ # # do nothing but comment
69
+ # end
41
70
  #
71
+ # # good
42
72
  # begin
43
73
  # do_something
44
74
  # rescue
45
- # handle_exception
75
+ # # do nothing but comment
46
76
  # end
47
77
  class HandleExceptions < Cop
48
78
  MSG = 'Do not suppress exceptions.'
49
79
 
50
80
  def on_resbody(node)
51
- add_offense(node) unless node.body
81
+ return if node.body
82
+ return if cop_config['AllowComments'] && comment_lines?(node)
83
+
84
+ add_offense(node)
85
+ end
86
+
87
+ private
88
+
89
+ def comment_lines?(node)
90
+ processed_source[line_range(node)].any? { |line| comment_line?(line) }
52
91
  end
53
92
  end
54
93
  end
@@ -53,6 +53,13 @@ module RuboCop
53
53
  end
54
54
  end
55
55
 
56
+ def autocorrect(node)
57
+ lambda do |corrector|
58
+ corrector.replace(node.loc.expression,
59
+ correct_method(node, node.receiver))
60
+ end
61
+ end
62
+
56
63
  private
57
64
 
58
65
  def date_time_object?(node)
@@ -5,6 +5,9 @@ module RuboCop
5
5
  module Lint
6
6
  # This cop checks for useless `else` in `begin..end` without `rescue`.
7
7
  #
8
+ # Note: This syntax is no longer valid on Ruby 2.6 or higher and
9
+ # this cop is going to be removed at some point the future.
10
+ #
8
11
  # @example
9
12
  #
10
13
  # # bad
@@ -9,7 +9,7 @@ module RuboCop
9
9
 
10
10
  FORMATS = {
11
11
  snake_case: /^@{0,2}[\da-z_]+[!?=]?$/,
12
- camelCase: /^@{0,2}_?[a-z][\da-zA-Z]+[!?=]?$/
12
+ camelCase: /^@{0,2}_?[a-z][\da-zA-Z]+[!?=]?$/
13
13
  }.freeze
14
14
  end
15
15
  end
@@ -8,8 +8,8 @@ module RuboCop
8
8
  include ConfigurableFormatting
9
9
 
10
10
  FORMATS = {
11
- snake_case: /(?:[a-z_]|_\d+)$/,
12
- normalcase: /(?:_\D*|[A-Za-z]\d*)$/,
11
+ snake_case: /(?:[a-z_]|_\d+)$/,
12
+ normalcase: /(?:_\D*|[A-Za-z]\d*)$/,
13
13
  non_integer: /[A-Za-z_]$/
14
14
  }.freeze
15
15
  end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ # This module encapsulates the ability to ignore certain methods when
6
+ # parsing using regex patterns.
7
+ module IgnoredMethodPatterns
8
+ private
9
+
10
+ def ignored_method_pattern?(name)
11
+ ignored_method_patterns.any? { |pattern| Regexp.new(pattern) =~ name }
12
+ end
13
+
14
+ def ignored_method_patterns
15
+ cop_config.fetch('IgnoredMethodPatterns', [])
16
+ end
17
+ end
18
+ end
19
+ end
@@ -21,20 +21,20 @@ module RuboCop
21
21
  MSG = 'Prefer `%<assert_method>s` over `%<refute_method>s`.'
22
22
 
23
23
  CORRECTIONS = {
24
- refute: 'assert_not',
25
- refute_empty: 'assert_not_empty',
26
- refute_equal: 'assert_not_equal',
27
- refute_in_delta: 'assert_not_in_delta',
28
- refute_in_epsilon: 'assert_not_in_epsilon',
29
- refute_includes: 'assert_not_includes',
24
+ refute: 'assert_not',
25
+ refute_empty: 'assert_not_empty',
26
+ refute_equal: 'assert_not_equal',
27
+ refute_in_delta: 'assert_not_in_delta',
28
+ refute_in_epsilon: 'assert_not_in_epsilon',
29
+ refute_includes: 'assert_not_includes',
30
30
  refute_instance_of: 'assert_not_instance_of',
31
- refute_kind_of: 'assert_not_kind_of',
32
- refute_nil: 'assert_not_nil',
33
- refute_operator: 'assert_not_operator',
34
- refute_predicate: 'assert_not_predicate',
35
- refute_respond_to: 'assert_not_respond_to',
36
- refute_same: 'assert_not_same',
37
- refute_match: 'assert_no_match'
31
+ refute_kind_of: 'assert_not_kind_of',
32
+ refute_nil: 'assert_not_nil',
33
+ refute_operator: 'assert_not_operator',
34
+ refute_predicate: 'assert_not_predicate',
35
+ refute_respond_to: 'assert_not_respond_to',
36
+ refute_same: 'assert_not_same',
37
+ refute_match: 'assert_no_match'
38
38
  }.freeze
39
39
 
40
40
  OFFENSIVE_METHODS = CORRECTIONS.keys.freeze
@@ -8,10 +8,19 @@ module RuboCop
8
8
  # method calls containing parameters.
9
9
  #
10
10
  # In the default style (require_parentheses), macro methods are ignored.
11
- # Additional methods can be added to the `IgnoredMethods` list. This
12
- # option is valid only in the default style. Macros can be included by
11
+ # Additional methods can be added to the `IgnoredMethods`
12
+ # or `IgnoredMethodPatterns` list. These options are
13
+ # valid only in the default style. Macros can be included by
13
14
  # either setting `IgnoreMacros` to false or adding specific macros to
14
- # the `IncludedMacros` list. If a method is listed in both
15
+ # the `IncludedMacros` list.
16
+ #
17
+ # Precedence of options is all follows:
18
+ #
19
+ # 1. `IgnoredMethods`
20
+ # 2. `IgnoredMethodPatterns`
21
+ # 3. `IncludedMacros`
22
+ #
23
+ # eg. If a method is listed in both
15
24
  # `IncludedMacros` and `IgnoredMethods`, then the latter takes
16
25
  # precedence (that is, the method is ignored).
17
26
  #
@@ -52,6 +61,9 @@ module RuboCop
52
61
  # # okay with `puts` listed in `IgnoredMethods`
53
62
  # puts 'test'
54
63
  #
64
+ # # okay with `^assert` listed in `IgnoredMethodPatterns`
65
+ # assert_equal 'test', x
66
+ #
55
67
  # # IgnoreMacros: true (default)
56
68
  #
57
69
  # # good
@@ -136,6 +148,7 @@ module RuboCop
136
148
  class MethodCallWithArgsParentheses < Cop
137
149
  include ConfigurableEnforcedStyle
138
150
  include IgnoredMethods
151
+ include IgnoredMethodPatterns
139
152
 
140
153
  TRAILING_WHITESPACE_REGEX = /\s+\Z/.freeze
141
154
 
@@ -173,6 +186,7 @@ module RuboCop
173
186
 
174
187
  def add_offense_for_require_parentheses(node)
175
188
  return if ignored_method?(node.method_name)
189
+ return if ignored_method_pattern?(node.method_name)
176
190
  return if eligible_for_parentheses_omission?(node)
177
191
  return unless node.arguments? && !node.parenthesized?
178
192