rubocop 0.69.0 → 0.70.0

Sign up to get free protection for your applications and to get access to all the features.
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