rubocop 1.78.0 → 1.79.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 (44) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -3
  3. data/config/default.yml +32 -19
  4. data/lib/rubocop/cop/internal_affairs/node_type_group.rb +3 -2
  5. data/lib/rubocop/cop/internal_affairs/useless_restrict_on_send.rb +1 -1
  6. data/lib/rubocop/cop/layout/empty_lines_after_module_inclusion.rb +99 -0
  7. data/lib/rubocop/cop/layout/space_around_keyword.rb +6 -1
  8. data/lib/rubocop/cop/layout/space_around_operators.rb +8 -0
  9. data/lib/rubocop/cop/lint/literal_as_condition.rb +12 -0
  10. data/lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +1 -0
  11. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +101 -2
  12. data/lib/rubocop/cop/lint/require_range_parentheses.rb +1 -1
  13. data/lib/rubocop/cop/lint/rescue_type.rb +1 -1
  14. data/lib/rubocop/cop/lint/useless_numeric_operation.rb +1 -0
  15. data/lib/rubocop/cop/lint/utils/nil_receiver_checker.rb +121 -0
  16. data/lib/rubocop/cop/naming/method_name.rb +40 -1
  17. data/lib/rubocop/cop/naming/predicate_method.rb +4 -1
  18. data/lib/rubocop/cop/style/access_modifier_declarations.rb +1 -1
  19. data/lib/rubocop/cop/style/accessor_grouping.rb +13 -1
  20. data/lib/rubocop/cop/style/arguments_forwarding.rb +11 -17
  21. data/lib/rubocop/cop/style/array_intersect.rb +53 -23
  22. data/lib/rubocop/cop/style/block_delimiters.rb +1 -1
  23. data/lib/rubocop/cop/style/conditional_assignment.rb +1 -1
  24. data/lib/rubocop/cop/style/dig_chain.rb +1 -1
  25. data/lib/rubocop/cop/style/exponential_notation.rb +1 -0
  26. data/lib/rubocop/cop/style/inverse_methods.rb +1 -1
  27. data/lib/rubocop/cop/style/it_assignment.rb +69 -12
  28. data/lib/rubocop/cop/style/it_block_parameter.rb +2 -0
  29. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +2 -4
  30. data/lib/rubocop/cop/style/parallel_assignment.rb +32 -20
  31. data/lib/rubocop/cop/style/redundant_freeze.rb +1 -1
  32. data/lib/rubocop/cop/style/redundant_line_continuation.rb +1 -1
  33. data/lib/rubocop/cop/style/redundant_parentheses.rb +9 -0
  34. data/lib/rubocop/cop/style/single_line_methods.rb +3 -3
  35. data/lib/rubocop/cop/style/sole_nested_conditional.rb +30 -1
  36. data/lib/rubocop/cop/style/stabby_lambda_parentheses.rb +1 -1
  37. data/lib/rubocop/cop/variable_force.rb +18 -7
  38. data/lib/rubocop/cops_documentation_generator.rb +1 -0
  39. data/lib/rubocop/formatter/markdown_formatter.rb +1 -0
  40. data/lib/rubocop/formatter/pacman_formatter.rb +1 -0
  41. data/lib/rubocop/lsp/routes.rb +4 -4
  42. data/lib/rubocop/version.rb +1 -1
  43. data/lib/rubocop.rb +2 -0
  44. metadata +12 -7
@@ -0,0 +1,121 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Lint
6
+ module Utils
7
+ # Utility class that checks if the receiver can't be nil.
8
+ class NilReceiverChecker
9
+ NIL_METHODS = (nil.methods + %i[!]).to_set.freeze
10
+
11
+ def initialize(receiver, additional_nil_methods)
12
+ @receiver = receiver
13
+ @additional_nil_methods = additional_nil_methods
14
+ @checked_nodes = {}.compare_by_identity
15
+ end
16
+
17
+ def cant_be_nil?
18
+ sole_condition_of_parent_if?(@receiver) || _cant_be_nil?(@receiver.parent, @receiver)
19
+ end
20
+
21
+ private
22
+
23
+ # rubocop:disable Metrics
24
+ def _cant_be_nil?(node, receiver)
25
+ return false unless node
26
+
27
+ # For some nodes, we check their parent and then some children for these parents.
28
+ # This is added to avoid infinite loops.
29
+ return false if @checked_nodes.key?(node)
30
+
31
+ @checked_nodes[node] = true
32
+
33
+ case node.type
34
+ when :def, :class, :module, :sclass
35
+ return false
36
+ when :send
37
+ return non_nil_method?(node.method_name) if node.receiver == receiver
38
+
39
+ node.arguments.each do |argument|
40
+ return true if _cant_be_nil?(argument, receiver)
41
+ end
42
+
43
+ return true if _cant_be_nil?(node.receiver, receiver)
44
+ when :begin
45
+ return true if _cant_be_nil?(node.children.first, receiver)
46
+ when :if, :case
47
+ return true if _cant_be_nil?(node.condition, receiver)
48
+ when :and, :or
49
+ return true if _cant_be_nil?(node.lhs, receiver)
50
+ when :pair
51
+ if _cant_be_nil?(node.key, receiver) ||
52
+ _cant_be_nil?(node.value, receiver)
53
+ return true
54
+ end
55
+ when :when
56
+ node.each_condition do |condition|
57
+ return true if _cant_be_nil?(condition, receiver)
58
+ end
59
+ when :lvasgn, :ivasgn, :cvasgn, :gvasgn, :casgn
60
+ return true if _cant_be_nil?(node.expression, receiver)
61
+ end
62
+
63
+ # Due to how `if/else` are implemented (`elsif` is a child of `if` or another `elsif`),
64
+ # using left_siblings will not work correctly for them.
65
+ if !else_branch?(node) || (node.if_type? && !node.elsif?)
66
+ node.left_siblings.reverse_each do |sibling|
67
+ next unless sibling.is_a?(AST::Node)
68
+
69
+ return true if _cant_be_nil?(sibling, receiver)
70
+ end
71
+ end
72
+
73
+ if node.parent
74
+ _cant_be_nil?(node.parent, receiver)
75
+ else
76
+ false
77
+ end
78
+ end
79
+ # rubocop:enable Metrics
80
+
81
+ def non_nil_method?(method_name)
82
+ !NIL_METHODS.include?(method_name) && !@additional_nil_methods.include?(method_name)
83
+ end
84
+
85
+ # rubocop:disable Metrics/PerceivedComplexity
86
+ def sole_condition_of_parent_if?(node)
87
+ parent = node.parent
88
+
89
+ while parent
90
+ if parent.if_type?
91
+ if parent.condition == node
92
+ return true
93
+ elsif parent.elsif?
94
+ parent = find_top_if(parent)
95
+ end
96
+ elsif else_branch?(parent)
97
+ # Find the top `if` for `else`.
98
+ parent = parent.parent
99
+ end
100
+
101
+ parent = parent&.parent
102
+ end
103
+
104
+ false
105
+ end
106
+ # rubocop:enable Metrics/PerceivedComplexity
107
+
108
+ def else_branch?(node)
109
+ node.parent&.if_type? && node.parent.else_branch == node
110
+ end
111
+
112
+ def find_top_if(node)
113
+ node = node.parent while node.elsif?
114
+
115
+ node
116
+ end
117
+ end
118
+ end
119
+ end
120
+ end
121
+ end
@@ -53,6 +53,12 @@ module RuboCop
53
53
  # # good
54
54
  # Struct.new(:foo_bar)
55
55
  #
56
+ # # bad
57
+ # alias_method :fooBar, :some_method
58
+ #
59
+ # # good
60
+ # alias_method :foo_bar, :some_method
61
+ #
56
62
  # @example EnforcedStyle: camelCase
57
63
  # # bad
58
64
  # def foo_bar; end
@@ -74,6 +80,12 @@ module RuboCop
74
80
  # # good
75
81
  # Struct.new(:fooBar)
76
82
  #
83
+ # # bad
84
+ # alias_method :foo_bar, :some_method
85
+ #
86
+ # # good
87
+ # alias_method :fooBar, :some_method
88
+ #
77
89
  # @example ForbiddenIdentifiers: ['def', 'super']
78
90
  # # bad
79
91
  # def def; end
@@ -94,6 +106,9 @@ module RuboCop
94
106
  MSG = 'Use %<style>s for method names.'
95
107
  MSG_FORBIDDEN = '`%<identifier>s` is forbidden, use another method name instead.'
96
108
 
109
+ OPERATOR_METHODS = %i[| ^ & <=> == === =~ > >= < <= << >> + - * /
110
+ % ** ~ +@ -@ !@ ~@ [] []= ! != !~ `].to_set.freeze
111
+
97
112
  # @!method sym_name(node)
98
113
  def_node_matcher :sym_name, '(sym $_name)'
99
114
 
@@ -103,11 +118,18 @@ module RuboCop
103
118
  # @!method new_struct?(node)
104
119
  def_node_matcher :new_struct?, '(send (const {nil? cbase} :Struct) :new ...)'
105
120
 
121
+ # @!method define_data?(node)
122
+ def_node_matcher :define_data?, '(send (const {nil? cbase} :Data) :define ...)'
123
+
106
124
  def on_send(node)
107
125
  if node.method?(:define_method) || node.method?(:define_singleton_method)
108
126
  handle_define_method(node)
109
127
  elsif new_struct?(node)
110
128
  handle_new_struct(node)
129
+ elsif define_data?(node)
130
+ handle_define_data(node)
131
+ elsif node.method?(:alias_method)
132
+ handle_alias_method(node)
111
133
  else
112
134
  handle_attr_accessor(node)
113
135
  end
@@ -124,6 +146,10 @@ module RuboCop
124
146
  end
125
147
  alias on_defs on_def
126
148
 
149
+ def on_alias(node)
150
+ handle_method_name(node.new_identifier, node.new_identifier.value)
151
+ end
152
+
127
153
  private
128
154
 
129
155
  def handle_define_method(node)
@@ -139,6 +165,19 @@ module RuboCop
139
165
  end
140
166
  end
141
167
 
168
+ def handle_define_data(node)
169
+ node.arguments.select { |argument| argument.type?(:sym, :str) }.each do |name|
170
+ handle_method_name(name, name.value)
171
+ end
172
+ end
173
+
174
+ def handle_alias_method(node)
175
+ return unless node.arguments.size == 2
176
+ return unless node.first_argument.type?(:str, :sym)
177
+
178
+ handle_method_name(node.first_argument, node.first_argument.value)
179
+ end
180
+
142
181
  def handle_attr_accessor(node)
143
182
  return unless (attrs = node.attribute_accessor?)
144
183
 
@@ -159,7 +198,7 @@ module RuboCop
159
198
 
160
199
  if forbidden_name?(name.to_s)
161
200
  register_forbidden_name(node)
162
- else
201
+ elsif !OPERATOR_METHODS.include?(name)
163
202
  check_name(node, name, range_position(node))
164
203
  end
165
204
  end
@@ -269,7 +269,10 @@ module RuboCop
269
269
  node.body ? [last_value(node.body)] : [s(:nil)]
270
270
  else
271
271
  # Branches with no value act as an implicit `nil`.
272
- node.branches.filter_map { |branch| branch ? last_value(branch) : s(:nil) }
272
+ branches = node.branches.map { |branch| branch ? last_value(branch) : s(:nil) }
273
+ # Missing else branches also act as an implicit `nil`.
274
+ branches.push(s(:nil)) unless node.else_branch
275
+ branches
273
276
  end
274
277
  end
275
278
 
@@ -348,7 +348,7 @@ module RuboCop
348
348
  end
349
349
 
350
350
  def remove_modifier_node_within_begin(corrector, modifier_node, begin_node)
351
- def_node = begin_node.children[1]
351
+ def_node = begin_node.children[begin_node.children.index(modifier_node) + 1]
352
352
  range = modifier_node.source_range.begin.join(def_node.source_range.begin)
353
353
  corrector.remove(range)
354
354
  end
@@ -84,7 +84,10 @@ module RuboCop
84
84
 
85
85
  def autocorrect(corrector, node)
86
86
  if (preferred_accessors = preferred_accessors(node))
87
- corrector.replace(node, preferred_accessors)
87
+ corrector.replace(
88
+ grouped_style? ? node : range_with_trailing_argument_comment(node),
89
+ preferred_accessors
90
+ )
88
91
  else
89
92
  range = range_with_surrounding_space(node.source_range, side: :left)
90
93
  corrector.remove(range)
@@ -196,6 +199,15 @@ module RuboCop
196
199
  end
197
200
  end.join("\n")
198
201
  end
202
+
203
+ def range_with_trailing_argument_comment(node)
204
+ comment = processed_source.ast_with_comments[node.last_argument].last
205
+ if comment
206
+ add_range(node.source_range, comment.source_range)
207
+ else
208
+ node
209
+ end
210
+ end
199
211
  end
200
212
  end
201
213
  end
@@ -146,7 +146,6 @@ module RuboCop
146
146
  minimum_target_ruby_version 2.7
147
147
 
148
148
  FORWARDING_LVAR_TYPES = %i[splat kwsplat block_pass].freeze
149
- ADDITIONAL_ARG_TYPES = %i[lvar arg optarg].freeze
150
149
 
151
150
  FORWARDING_MSG = 'Use shorthand syntax `...` for arguments forwarding.'
152
151
  ARGS_MSG = 'Use anonymous positional arguments forwarding (`*`).'
@@ -198,9 +197,9 @@ module RuboCop
198
197
  send_classifications.all? { |_, c, _, _| all_classifications.include?(c) }
199
198
  end
200
199
 
201
- # rubocop:disable Metrics/MethodLength
200
+ # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
202
201
  def add_forward_all_offenses(node, send_classifications, forwardable_args)
203
- _rest_arg, _kwrest_arg, block_arg = *forwardable_args
202
+ rest_arg, kwrest_arg, block_arg = *forwardable_args
204
203
  registered_block_arg_offense = false
205
204
 
206
205
  send_classifications.each do |send_node, c, forward_rest, forward_kwrest, forward_block_arg| # rubocop:disable Layout/LineLength
@@ -212,16 +211,20 @@ module RuboCop
212
211
  registered_block_arg_offense = true
213
212
  break
214
213
  else
215
- register_forward_all_offense(send_node, send_node, forward_rest)
214
+ first_arg = forward_rest || forward_kwrest || forward_all_first_argument(send_node)
215
+ register_forward_all_offense(send_node, send_node, first_arg)
216
216
  end
217
217
  end
218
218
 
219
219
  return if registered_block_arg_offense
220
220
 
221
- rest_arg, _kwrest_arg, _block_arg = *forwardable_args
222
- register_forward_all_offense(node, node.arguments, rest_arg)
221
+ register_forward_all_offense(node, node.arguments, rest_arg || kwrest_arg)
222
+ end
223
+ # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
224
+
225
+ def forward_all_first_argument(node)
226
+ node.arguments.reverse_each.find(&:forwarded_restarg_type?)
223
227
  end
224
- # rubocop:enable Metrics/MethodLength
225
228
 
226
229
  # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
227
230
  def add_post_ruby_32_offenses(def_node, send_classifications, forwardable_args)
@@ -361,18 +364,9 @@ module RuboCop
361
364
  end
362
365
  end
363
366
 
364
- # rubocop:disable Metrics/AbcSize
365
367
  def arguments_range(node, first_node)
366
- arguments = node.arguments.reject do |arg|
367
- next true if ADDITIONAL_ARG_TYPES.include?(arg.type) || arg.variable? || arg.call_type?
368
-
369
- arg.literal? && arg.each_descendant(:kwsplat).none?
370
- end
371
-
372
- start_node = first_node || arguments.first
373
- start_node.source_range.begin.join(arguments.last.source_range.end)
368
+ first_node.source_range.begin.join(node.last_argument.source_range.end)
374
369
  end
375
- # rubocop:enable Metrics/AbcSize
376
370
 
377
371
  def allow_only_rest_arguments?
378
372
  cop_config.fetch('AllowOnlyRestArgument', true)
@@ -5,12 +5,15 @@ module RuboCop
5
5
  module Style
6
6
  # In Ruby 3.1, `Array#intersect?` has been added.
7
7
  #
8
- # This cop identifies places where `(array1 & array2).any?`
9
- # or `(array1.intersection(array2)).any?` can be replaced by
10
- # `array1.intersect?(array2)`.
8
+ # This cop identifies places where:
11
9
  #
12
- # The `array1.intersect?(array2)` method is faster than
13
- # `(array1 & array2).any?` and is more readable.
10
+ # * `(array1 & array2).any?`
11
+ # * `(array1.intersection(array2)).any?`
12
+ # * `array1.any? { |elem| array2.member?(elem) }`
13
+ #
14
+ # can be replaced with `array1.intersect?(array2)`.
15
+ #
16
+ # `array1.intersect?(array2)` is faster and more readable.
14
17
  #
15
18
  # In cases like the following, compatibility is not ensured,
16
19
  # so it will not be detected when using block argument.
@@ -40,6 +43,10 @@ module RuboCop
40
43
  # array1.intersection(array2).empty?
41
44
  # array1.intersection(array2).none?
42
45
  #
46
+ # # bad
47
+ # array1.any? { |elem| array2.member?(elem) }
48
+ # array1.none? { |elem| array2.member?(elem) }
49
+ #
43
50
  # # good
44
51
  # array1.intersect?(array2)
45
52
  # !array1.intersect?(array2)
@@ -77,8 +84,26 @@ module RuboCop
77
84
  )
78
85
  PATTERN
79
86
 
80
- MSG = 'Use `%<negated>s%<receiver>s%<dot>sintersect?(%<argument>s)` ' \
81
- 'instead of `%<existing>s`.'
87
+ # @!method any_none_block_intersection(node)
88
+ def_node_matcher :any_none_block_intersection, <<~PATTERN
89
+ {
90
+ (block
91
+ (call $_receiver ${:any? :none?})
92
+ (args (arg _key))
93
+ (send $_argument :member? (lvar _key))
94
+ )
95
+ (numblock
96
+ (call $_receiver ${:any? :none?}) 1
97
+ (send $_argument :member? (lvar :_1))
98
+ )
99
+ (itblock
100
+ (call $_receiver ${:any? :none?}) :it
101
+ (send $_argument :member? (lvar :it))
102
+ )
103
+ }
104
+ PATTERN
105
+
106
+ MSG = 'Use `%<replacement>s` instead of `%<existing>s`.'
82
107
  STRAIGHT_METHODS = %i[present? any?].freeze
83
108
  NEGATED_METHODS = %i[blank? empty? none?].freeze
84
109
  RESTRICT_ON_SEND = (STRAIGHT_METHODS + NEGATED_METHODS).freeze
@@ -88,16 +113,25 @@ module RuboCop
88
113
  return unless (receiver, argument, method_name = bad_intersection?(node))
89
114
 
90
115
  dot = node.loc.dot.source
91
- message = message(receiver.source, argument.source, method_name, dot, node.source)
92
-
93
- add_offense(node, message: message) do |corrector|
94
- bang = straight?(method_name) ? '' : '!'
116
+ bang = straight?(method_name) ? '' : '!'
117
+ replacement = "#{bang}#{receiver.source}#{dot}intersect?(#{argument.source})"
95
118
 
96
- corrector.replace(node, "#{bang}#{receiver.source}#{dot}intersect?(#{argument.source})")
97
- end
119
+ register_offense(node, replacement)
98
120
  end
99
121
  alias on_csend on_send
100
122
 
123
+ def on_block(node)
124
+ return unless (receiver, method_name, argument = any_none_block_intersection(node))
125
+
126
+ dot = node.send_node.loc.dot.source
127
+ bang = method_name == :any? ? '' : '!'
128
+ replacement = "#{bang}#{receiver.source}#{dot}intersect?(#{argument.source})"
129
+
130
+ register_offense(node, replacement)
131
+ end
132
+ alias on_numblock on_block
133
+ alias on_itblock on_block
134
+
101
135
  private
102
136
 
103
137
  def bad_intersection?(node)
@@ -114,16 +148,12 @@ module RuboCop
114
148
  STRAIGHT_METHODS.include?(method_name.to_sym)
115
149
  end
116
150
 
117
- def message(receiver, argument, method_name, dot, existing)
118
- negated = straight?(method_name) ? '' : '!'
119
- format(
120
- MSG,
121
- negated: negated,
122
- receiver: receiver,
123
- argument: argument,
124
- dot: dot,
125
- existing: existing
126
- )
151
+ def register_offense(node, replacement)
152
+ message = format(MSG, replacement: replacement, existing: node.source)
153
+
154
+ add_offense(node, message: message) do |corrector|
155
+ corrector.replace(node, replacement)
156
+ end
127
157
  end
128
158
  end
129
159
  end
@@ -4,7 +4,7 @@
4
4
  module RuboCop
5
5
  module Cop
6
6
  module Style
7
- # Check for uses of braces or do/end around single line or
7
+ # Checks for uses of braces or do/end around single line or
8
8
  # multi-line blocks.
9
9
  #
10
10
  # Methods that can be either procedural or functional and cannot be
@@ -111,7 +111,7 @@ module RuboCop
111
111
  end
112
112
  end
113
113
 
114
- # Check for `if` and `case` statements where each branch is used for
114
+ # Checks for `if` and `case` statements where each branch is used for
115
115
  # both the assignment and comparison of the same variable
116
116
  # when using the return of the condition can be used instead.
117
117
  #
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Style
6
- # Check for chained `dig` calls that can be collapsed into a single `dig`.
6
+ # Checks for chained `dig` calls that can be collapsed into a single `dig`.
7
7
  #
8
8
  # @safety
9
9
  # This cop is unsafe because it cannot be guaranteed that the receiver
@@ -59,6 +59,7 @@ module RuboCop
59
59
  #
60
60
  class ExponentialNotation < Base
61
61
  include ConfigurableEnforcedStyle
62
+
62
63
  MESSAGES = {
63
64
  scientific: 'Use a mantissa >= 1 and < 10.',
64
65
  engineering: 'Use an exponent divisible by 3 and a mantissa >= 0.1 and < 1000.',
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Style
6
- # Check for usages of not (`not` or `!`) called on a method
6
+ # Checks for usages of not (`not` or `!`) called on a method
7
7
  # when an inverse of that method can be used instead.
8
8
  #
9
9
  # Methods that can be inverted by a not (`not` or `!`) should be defined
@@ -3,33 +3,90 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Style
6
- # Checks for assignments to a local `it` variable inside a block
6
+ # Checks for local variables and method parameters named `it`,
7
7
  # where `it` can refer to the first anonymous parameter as of Ruby 3.4.
8
+ # Use a meaningful variable name instead.
8
9
  #
9
- # Although Ruby allows reassigning `it` in these cases, it could
10
+ # NOTE: Although Ruby allows reassigning `it` in these cases, it could
10
11
  # cause confusion if `it` is used as a block parameter elsewhere.
11
- # For consistency, this also applies to numblocks and blocks with
12
- # parameters, even though `it` cannot be used in those cases.
13
12
  #
14
13
  # @example
15
14
  # # bad
16
- # foo { it = 5 }
17
- # foo { |bar| it = bar }
18
- # foo { it = _2 }
15
+ # it = 5
19
16
  #
20
- # # good - use a different variable name
21
- # foo { var = 5 }
22
- # foo { |bar| var = bar }
23
- # foo { bar = _2 }
17
+ # # good
18
+ # var = 5
19
+ #
20
+ # # bad
21
+ # def foo(it)
22
+ # end
23
+ #
24
+ # # good
25
+ # def foo(arg)
26
+ # end
27
+ #
28
+ # # bad
29
+ # def foo(it = 5)
30
+ # end
31
+ #
32
+ # # good
33
+ # def foo(arg = 5)
34
+ # end
35
+ #
36
+ # # bad
37
+ # def foo(*it)
38
+ # end
39
+ #
40
+ # # good
41
+ # def foo(*args)
42
+ # end
43
+ #
44
+ # # bad
45
+ # def foo(it:)
46
+ # end
47
+ #
48
+ # # good
49
+ # def foo(arg:)
50
+ # end
51
+ #
52
+ # # bad
53
+ # def foo(it: 5)
54
+ # end
55
+ #
56
+ # # good
57
+ # def foo(arg: 5)
58
+ # end
59
+ #
60
+ # # bad
61
+ # def foo(**it)
62
+ # end
63
+ #
64
+ # # good
65
+ # def foo(**kwargs)
66
+ # end
67
+ #
68
+ # # bad
69
+ # def foo(&it)
70
+ # end
71
+ #
72
+ # # good
73
+ # def foo(&block)
74
+ # end
24
75
  class ItAssignment < Base
25
76
  MSG = '`it` is the default block parameter; consider another name.'
26
77
 
27
78
  def on_lvasgn(node)
28
79
  return unless node.name == :it
29
- return unless node.each_ancestor(:any_block).any?
30
80
 
31
81
  add_offense(node.loc.name)
32
82
  end
83
+ alias on_arg on_lvasgn
84
+ alias on_optarg on_lvasgn
85
+ alias on_restarg on_lvasgn
86
+ alias on_blockarg on_lvasgn
87
+ alias on_kwarg on_lvasgn
88
+ alias on_kwoptarg on_lvasgn
89
+ alias on_kwrestarg on_lvasgn
33
90
  end
34
91
  end
35
92
  end
@@ -109,6 +109,8 @@ module RuboCop
109
109
  private
110
110
 
111
111
  def find_block_variables(node, block_argument_name)
112
+ return [] unless node.body
113
+
112
114
  node.body.each_descendant(:lvar).select do |descendant|
113
115
  descendant.source == block_argument_name
114
116
  end
@@ -222,11 +222,9 @@ module RuboCop
222
222
  end
223
223
 
224
224
  def unary_literal?(node)
225
- # NOTE: should be removed after releasing https://github.com/rubocop/rubocop-ast/pull/379
226
- return node.source.match?(/\A[+-]/) if node.complex_type?
225
+ return true if node.numeric_type? && node.sign?
227
226
 
228
- (node.numeric_type? && node.sign?) ||
229
- (node.parent&.send_type? && node.parent.unary_operation?)
227
+ node.parent&.send_type? && node.parent.unary_operation?
230
228
  end
231
229
 
232
230
  def assigned_before?(node, target)