rubocop 1.70.0 → 1.71.2
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.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/config/default.yml +17 -0
- data/lib/rubocop/cli/command/show_cops.rb +24 -2
- data/lib/rubocop/comment_config.rb +1 -1
- data/lib/rubocop/cop/autocorrect_logic.rb +1 -1
- data/lib/rubocop/cop/bundler/duplicated_gem.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/location_expression.rb +2 -1
- data/lib/rubocop/cop/internal_affairs/node_first_or_last_argument.rb +3 -2
- data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_processor.rb +63 -0
- data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_walker.rb +131 -0
- data/lib/rubocop/cop/internal_affairs/node_pattern_groups.rb +229 -0
- data/lib/rubocop/cop/internal_affairs/node_type_multiple_predicates.rb +126 -0
- data/lib/rubocop/cop/internal_affairs/on_send_without_on_csend.rb +90 -0
- data/lib/rubocop/cop/internal_affairs/redundant_source_range.rb +3 -1
- data/lib/rubocop/cop/internal_affairs/single_line_comparison.rb +5 -4
- data/lib/rubocop/cop/internal_affairs.rb +3 -0
- data/lib/rubocop/cop/layout/access_modifier_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/argument_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/block_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/class_structure.rb +9 -9
- data/lib/rubocop/cop/layout/dot_position.rb +1 -1
- data/lib/rubocop/cop/layout/else_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/empty_line_between_defs.rb +7 -11
- data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +1 -1
- data/lib/rubocop/cop/layout/end_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/first_argument_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +1 -1
- data/lib/rubocop/cop/layout/first_parameter_indentation.rb +2 -2
- data/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/multiline_hash_key_line_breaks.rb +1 -1
- data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +1 -0
- data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +1 -0
- data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +2 -2
- data/lib/rubocop/cop/layout/redundant_line_break.rb +6 -5
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/single_line_block_chain.rb +1 -1
- data/lib/rubocop/cop/layout/space_after_colon.rb +2 -2
- data/lib/rubocop/cop/layout/space_after_comma.rb +1 -1
- data/lib/rubocop/cop/layout/space_after_semicolon.rb +1 -1
- data/lib/rubocop/cop/layout/space_around_keyword.rb +1 -0
- data/lib/rubocop/cop/layout/space_before_comma.rb +1 -1
- data/lib/rubocop/cop/layout/space_before_semicolon.rb +1 -1
- data/lib/rubocop/cop/lint/ambiguous_block_association.rb +1 -1
- data/lib/rubocop/cop/lint/array_literal_in_regexp.rb +119 -0
- data/lib/rubocop/cop/lint/assignment_in_condition.rb +1 -3
- data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +1 -1
- data/lib/rubocop/cop/lint/constant_definition_in_block.rb +3 -3
- data/lib/rubocop/cop/lint/constant_reassignment.rb +2 -6
- data/lib/rubocop/cop/lint/debugger.rb +1 -1
- data/lib/rubocop/cop/lint/duplicate_match_pattern.rb +1 -1
- data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +1 -1
- data/lib/rubocop/cop/lint/duplicate_set_element.rb +1 -1
- data/lib/rubocop/cop/lint/empty_expression.rb +0 -2
- data/lib/rubocop/cop/lint/float_comparison.rb +5 -2
- data/lib/rubocop/cop/lint/float_out_of_range.rb +1 -1
- data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +1 -1
- data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +1 -1
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +13 -3
- data/lib/rubocop/cop/lint/missing_super.rb +2 -2
- data/lib/rubocop/cop/lint/mixed_case_range.rb +1 -1
- data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +1 -1
- data/lib/rubocop/cop/lint/nested_method_definition.rb +3 -3
- data/lib/rubocop/cop/lint/next_without_accumulator.rb +1 -1
- data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +1 -1
- data/lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +13 -18
- data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +2 -1
- data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +1 -5
- data/lib/rubocop/cop/lint/redundant_regexp_quantifiers.rb +1 -1
- data/lib/rubocop/cop/lint/redundant_string_coercion.rb +2 -2
- data/lib/rubocop/cop/lint/rescue_exception.rb +1 -1
- data/lib/rubocop/cop/lint/safe_navigation_chain.rb +8 -1
- data/lib/rubocop/cop/lint/shared_mutable_default.rb +3 -3
- data/lib/rubocop/cop/lint/suppressed_exception.rb +1 -1
- data/lib/rubocop/cop/lint/symbol_conversion.rb +1 -1
- data/lib/rubocop/cop/lint/unexpected_block_arity.rb +1 -1
- data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +1 -1
- data/lib/rubocop/cop/lint/unreachable_code.rb +1 -1
- data/lib/rubocop/cop/lint/unreachable_loop.rb +1 -1
- data/lib/rubocop/cop/lint/useless_access_modifier.rb +4 -4
- data/lib/rubocop/cop/lint/useless_assignment.rb +1 -1
- data/lib/rubocop/cop/lint/useless_method_definition.rb +1 -1
- data/lib/rubocop/cop/lint/useless_numeric_operation.rb +2 -1
- data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +2 -2
- data/lib/rubocop/cop/lint/void.rb +2 -7
- data/lib/rubocop/cop/metrics/block_nesting.rb +1 -1
- data/lib/rubocop/cop/metrics/collection_literal_length.rb +7 -0
- data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +1 -1
- data/lib/rubocop/cop/metrics/module_length.rb +1 -1
- data/lib/rubocop/cop/metrics/perceived_complexity.rb +1 -1
- data/lib/rubocop/cop/mixin/check_line_breakable.rb +5 -5
- data/lib/rubocop/cop/mixin/comments_help.rb +1 -1
- data/lib/rubocop/cop/mixin/frozen_string_literal.rb +1 -1
- data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +4 -4
- data/lib/rubocop/cop/mixin/hash_subset.rb +188 -0
- data/lib/rubocop/cop/mixin/method_complexity.rb +1 -1
- data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +22 -8
- data/lib/rubocop/cop/mixin/statement_modifier.rb +7 -2
- data/lib/rubocop/cop/mixin/string_help.rb +1 -1
- data/lib/rubocop/cop/mixin/trailing_comma.rb +3 -3
- data/lib/rubocop/cop/naming/block_forwarding.rb +18 -14
- data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +3 -3
- data/lib/rubocop/cop/security/compound_hash.rb +1 -0
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +2 -4
- data/lib/rubocop/cop/style/arguments_forwarding.rb +38 -19
- data/lib/rubocop/cop/style/array_first_last.rb +18 -2
- data/lib/rubocop/cop/style/block_delimiters.rb +7 -20
- data/lib/rubocop/cop/style/class_and_module_children.rb +1 -1
- data/lib/rubocop/cop/style/collection_methods.rb +1 -1
- data/lib/rubocop/cop/style/combinable_defined.rb +1 -1
- data/lib/rubocop/cop/style/combinable_loops.rb +2 -2
- data/lib/rubocop/cop/style/concat_array_literals.rb +1 -1
- data/lib/rubocop/cop/style/conditional_assignment.rb +6 -4
- data/lib/rubocop/cop/style/documentation.rb +1 -1
- data/lib/rubocop/cop/style/double_negation.rb +3 -3
- data/lib/rubocop/cop/style/each_for_simple_loop.rb +1 -1
- data/lib/rubocop/cop/style/each_with_object.rb +2 -3
- data/lib/rubocop/cop/style/eval_with_location.rb +1 -1
- data/lib/rubocop/cop/style/exact_regexp_match.rb +1 -1
- data/lib/rubocop/cop/style/explicit_block_argument.rb +15 -2
- data/lib/rubocop/cop/style/fetch_env_var.rb +1 -1
- data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +1 -1
- data/lib/rubocop/cop/style/hash_each_methods.rb +3 -6
- data/lib/rubocop/cop/style/hash_except.rb +20 -131
- data/lib/rubocop/cop/style/hash_slice.rb +80 -0
- data/lib/rubocop/cop/style/hash_syntax.rb +1 -1
- data/lib/rubocop/cop/style/identical_conditional_branches.rb +22 -3
- data/lib/rubocop/cop/style/if_unless_modifier.rb +3 -3
- data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +1 -1
- data/lib/rubocop/cop/style/if_with_semicolon.rb +2 -2
- data/lib/rubocop/cop/style/infinite_loop.rb +1 -1
- data/lib/rubocop/cop/style/inverse_methods.rb +6 -6
- data/lib/rubocop/cop/style/it_assignment.rb +1 -1
- data/lib/rubocop/cop/style/keyword_parameters_order.rb +1 -1
- data/lib/rubocop/cop/style/map_into_array.rb +1 -1
- data/lib/rubocop/cop/style/map_to_hash.rb +1 -1
- data/lib/rubocop/cop/style/map_to_set.rb +3 -2
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +10 -13
- data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +2 -1
- data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +2 -4
- data/lib/rubocop/cop/style/method_def_parentheses.rb +1 -1
- data/lib/rubocop/cop/style/multiline_block_chain.rb +1 -1
- data/lib/rubocop/cop/style/mutable_constant.rb +2 -2
- data/lib/rubocop/cop/style/negated_if_else_condition.rb +1 -1
- data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +1 -1
- data/lib/rubocop/cop/style/open_struct_use.rb +5 -5
- data/lib/rubocop/cop/style/parallel_assignment.rb +1 -5
- data/lib/rubocop/cop/style/parentheses_around_condition.rb +2 -2
- data/lib/rubocop/cop/style/percent_literal_delimiters.rb +1 -1
- data/lib/rubocop/cop/style/proc.rb +1 -2
- data/lib/rubocop/cop/style/raise_args.rb +1 -1
- data/lib/rubocop/cop/style/redundant_begin.rb +1 -1
- data/lib/rubocop/cop/style/redundant_condition.rb +2 -2
- data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +6 -10
- data/lib/rubocop/cop/style/redundant_each.rb +1 -1
- data/lib/rubocop/cop/style/redundant_exception.rb +2 -2
- data/lib/rubocop/cop/style/redundant_freeze.rb +2 -2
- data/lib/rubocop/cop/style/redundant_line_continuation.rb +27 -10
- data/lib/rubocop/cop/style/redundant_parentheses.rb +9 -6
- data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +1 -1
- data/lib/rubocop/cop/style/redundant_regexp_escape.rb +1 -1
- data/lib/rubocop/cop/style/redundant_self_assignment.rb +12 -27
- data/lib/rubocop/cop/style/redundant_sort.rb +2 -2
- data/lib/rubocop/cop/style/redundant_string_escape.rb +2 -2
- data/lib/rubocop/cop/style/return_nil.rb +1 -1
- data/lib/rubocop/cop/style/safe_navigation.rb +1 -1
- data/lib/rubocop/cop/style/semicolon.rb +1 -1
- data/lib/rubocop/cop/style/single_line_block_params.rb +1 -1
- data/lib/rubocop/cop/style/single_line_methods.rb +1 -1
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +2 -2
- data/lib/rubocop/cop/style/string_concatenation.rb +1 -1
- data/lib/rubocop/cop/style/string_literals.rb +1 -1
- data/lib/rubocop/cop/style/string_methods.rb +1 -1
- data/lib/rubocop/cop/style/super_arguments.rb +4 -4
- data/lib/rubocop/cop/style/ternary_parentheses.rb +1 -1
- data/lib/rubocop/cop/style/top_level_method_definition.rb +1 -1
- data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +4 -1
- data/lib/rubocop/cop/style/while_until_modifier.rb +0 -1
- data/lib/rubocop/cop/style/yoda_expression.rb +1 -1
- data/lib/rubocop/cop/util.rb +2 -2
- data/lib/rubocop/cop/variable_force/variable.rb +14 -2
- data/lib/rubocop/cop/variable_force/variable_table.rb +3 -3
- data/lib/rubocop/cops_documentation_generator.rb +13 -13
- data/lib/rubocop/directive_comment.rb +9 -8
- data/lib/rubocop/options.rb +2 -1
- data/lib/rubocop/result_cache.rb +13 -13
- data/lib/rubocop/rspec/expect_offense.rb +6 -2
- data/lib/rubocop/rspec/support.rb +1 -2
- data/lib/rubocop/target_finder.rb +1 -0
- data/lib/rubocop/version.rb +1 -1
- data/lib/rubocop.rb +3 -0
- metadata +15 -11
- data/lib/rubocop/rspec/host_environment_simulation_helper.rb +0 -28
@@ -13,6 +13,20 @@ module RuboCop
|
|
13
13
|
# The default variable name is `block`. If the name is already in use, it will not be
|
14
14
|
# autocorrected.
|
15
15
|
#
|
16
|
+
# [NOTE]
|
17
|
+
# --
|
18
|
+
# Because of a bug in Ruby 3.3.0, when a block is referenced inside of another block,
|
19
|
+
# no offense will be registered until Ruby 3.4:
|
20
|
+
|
21
|
+
# [source,ruby]
|
22
|
+
# ----
|
23
|
+
# def foo(&block)
|
24
|
+
# # Using an anonymous block would be a syntax error on Ruby 3.3.0
|
25
|
+
# block_method { bar(&block) }
|
26
|
+
# end
|
27
|
+
# ----
|
28
|
+
# --
|
29
|
+
#
|
16
30
|
# @example EnforcedStyle: anonymous (default)
|
17
31
|
#
|
18
32
|
# # bad
|
@@ -90,21 +104,11 @@ module RuboCop
|
|
90
104
|
last_argument.source == block_pass_node.source
|
91
105
|
end
|
92
106
|
|
93
|
-
#
|
94
|
-
#
|
95
|
-
#
|
96
|
-
# def foo(&)
|
97
|
-
# block_method do
|
98
|
-
# bar(&)
|
99
|
-
# end
|
100
|
-
# end
|
101
|
-
#
|
102
|
-
# $ ruby -vc foo.rb
|
103
|
-
# ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [x86_64-darwin22]
|
104
|
-
# foo.rb: foo.rb:4: anonymous block parameter is also used within block (SyntaxError)
|
105
|
-
#
|
107
|
+
# Ruby 3.3.0 had a bug where accessing an anonymous block argument inside of a block
|
108
|
+
# was a syntax error in unambiguous cases: https://bugs.ruby-lang.org/issues/20090
|
109
|
+
# We disallow this also for earlier Ruby versions so that code is forwards compatible.
|
106
110
|
def invalidates_syntax?(block_pass_node)
|
107
|
-
block_pass_node.each_ancestor(:
|
111
|
+
target_ruby_version <= 3.3 && block_pass_node.each_ancestor(:any_block).any?
|
108
112
|
end
|
109
113
|
|
110
114
|
def use_kwarg_in_method_definition?(node)
|
@@ -113,7 +113,7 @@ module RuboCop
|
|
113
113
|
end
|
114
114
|
end
|
115
115
|
|
116
|
-
# rubocop:disable Metrics/
|
116
|
+
# rubocop:disable Metrics/MethodLength
|
117
117
|
def correct_node(corrector, node, offending_name, preferred_name)
|
118
118
|
return unless node
|
119
119
|
|
@@ -129,13 +129,13 @@ module RuboCop
|
|
129
129
|
end
|
130
130
|
end
|
131
131
|
|
132
|
-
if child_node.
|
132
|
+
if child_node.type?(:masgn, :lvasgn)
|
133
133
|
correct_reassignment(corrector, child_node, offending_name, preferred_name)
|
134
134
|
break
|
135
135
|
end
|
136
136
|
end
|
137
137
|
end
|
138
|
-
# rubocop:enable Metrics/
|
138
|
+
# rubocop:enable Metrics/MethodLength
|
139
139
|
|
140
140
|
# If the exception variable is reassigned, that assignment needs to be corrected.
|
141
141
|
# Further `lvar` nodes will not be corrected though since they now refer to a
|
@@ -150,8 +150,6 @@ module RuboCop
|
|
150
150
|
|
151
151
|
RESTRICT_ON_SEND = %i[private protected public module_function].freeze
|
152
152
|
|
153
|
-
ALLOWED_NODE_TYPES = %i[pair block].freeze
|
154
|
-
|
155
153
|
# @!method access_modifier_with_symbol?(node)
|
156
154
|
def_node_matcher :access_modifier_with_symbol?, <<~PATTERN
|
157
155
|
(send nil? {:private :protected :public :module_function}
|
@@ -188,7 +186,7 @@ module RuboCop
|
|
188
186
|
|
189
187
|
def allowed?(node)
|
190
188
|
!node.access_modifier? ||
|
191
|
-
|
189
|
+
node.parent&.type?(:pair, :any_block) ||
|
192
190
|
allow_modifiers_on_symbols?(node) ||
|
193
191
|
allow_modifiers_on_attrs?(node) ||
|
194
192
|
allow_modifiers_on_alias_method?(node)
|
@@ -312,7 +310,7 @@ module RuboCop
|
|
312
310
|
argument_less_modifier_node = find_argument_less_modifier_node(node)
|
313
311
|
if argument_less_modifier_node
|
314
312
|
corrector.insert_after(argument_less_modifier_node, "\n\n#{source}")
|
315
|
-
elsif (ancestor = node.each_ancestor(:
|
313
|
+
elsif (ancestor = node.each_ancestor(:class, :module).first)
|
316
314
|
|
317
315
|
corrector.insert_before(ancestor.loc.end, "#{node.method_name}\n\n#{source}\n")
|
318
316
|
else
|
@@ -31,6 +31,20 @@ module RuboCop
|
|
31
31
|
#
|
32
32
|
# This cop handles not only method forwarding but also forwarding to `super`.
|
33
33
|
#
|
34
|
+
# [NOTE]
|
35
|
+
# --
|
36
|
+
# Because of a bug in Ruby 3.3.0, when a block is referenced inside of another block,
|
37
|
+
# no offense will be registered until Ruby 3.4:
|
38
|
+
|
39
|
+
# [source,ruby]
|
40
|
+
# ----
|
41
|
+
# def foo(&block)
|
42
|
+
# # Using an anonymous block would be a syntax error on Ruby 3.3.0
|
43
|
+
# block_method { bar(&block) }
|
44
|
+
# end
|
45
|
+
# ----
|
46
|
+
# --
|
47
|
+
#
|
34
48
|
# @example
|
35
49
|
# # bad
|
36
50
|
# def foo(*args, &block)
|
@@ -148,7 +162,7 @@ module RuboCop
|
|
148
162
|
|
149
163
|
restarg, kwrestarg, blockarg = extract_forwardable_args(node.arguments)
|
150
164
|
forwardable_args = redundant_forwardable_named_args(restarg, kwrestarg, blockarg)
|
151
|
-
send_nodes = node.each_descendant(:
|
165
|
+
send_nodes = node.each_descendant(:call, :super, :yield).to_a
|
152
166
|
|
153
167
|
send_classifications = classify_send_nodes(
|
154
168
|
node, send_nodes, non_splat_or_block_pass_lvar_references(node.body), forwardable_args
|
@@ -191,9 +205,7 @@ module RuboCop
|
|
191
205
|
|
192
206
|
send_classifications.each do |send_node, c, forward_rest, forward_kwrest, forward_block_arg| # rubocop:disable Layout/LineLength
|
193
207
|
if !forward_rest && !forward_kwrest && c != :all_anonymous
|
194
|
-
|
195
|
-
# in Ruby 3.3.0.
|
196
|
-
if outside_block?(forward_block_arg)
|
208
|
+
if allow_anonymous_forwarding_in_block?(forward_block_arg)
|
197
209
|
register_forward_block_arg_offense(!forward_rest, node.arguments, block_arg)
|
198
210
|
register_forward_block_arg_offense(!forward_rest, send_node, forward_block_arg)
|
199
211
|
end
|
@@ -214,24 +226,22 @@ module RuboCop
|
|
214
226
|
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
215
227
|
def add_post_ruby_32_offenses(def_node, send_classifications, forwardable_args)
|
216
228
|
return unless use_anonymous_forwarding?
|
217
|
-
return
|
229
|
+
return unless all_forwarding_offenses_correctable?(send_classifications)
|
218
230
|
|
219
231
|
rest_arg, kwrest_arg, block_arg = *forwardable_args
|
220
232
|
|
221
233
|
send_classifications.each do |send_node, _c, forward_rest, forward_kwrest, forward_block_arg| # rubocop:disable Layout/LineLength
|
222
|
-
if
|
234
|
+
if allow_anonymous_forwarding_in_block?(forward_rest)
|
223
235
|
register_forward_args_offense(def_node.arguments, rest_arg)
|
224
236
|
register_forward_args_offense(send_node, forward_rest)
|
225
237
|
end
|
226
238
|
|
227
|
-
if
|
239
|
+
if allow_anonymous_forwarding_in_block?(forward_kwrest)
|
228
240
|
register_forward_kwargs_offense(!forward_rest, def_node.arguments, kwrest_arg)
|
229
241
|
register_forward_kwargs_offense(!forward_rest, send_node, forward_kwrest)
|
230
242
|
end
|
231
243
|
|
232
|
-
|
233
|
-
# in Ruby 3.3.0.
|
234
|
-
if outside_block?(forward_block_arg)
|
244
|
+
if allow_anonymous_forwarding_in_block?(forward_block_arg)
|
235
245
|
register_forward_block_arg_offense(!forward_rest, def_node.arguments, block_arg)
|
236
246
|
register_forward_block_arg_offense(!forward_rest, send_node, forward_block_arg)
|
237
247
|
end
|
@@ -293,10 +303,25 @@ module RuboCop
|
|
293
303
|
redundant_arg_names.include?(arg.source) ? arg : nil
|
294
304
|
end
|
295
305
|
|
296
|
-
|
306
|
+
# Checks if forwarding is uses both in blocks and outside of blocks.
|
307
|
+
# On Ruby 3.3.0, anonymous block forwarding in blocks can be is a syntax
|
308
|
+
# error, so we only want to register an offense if we can change all occurrences.
|
309
|
+
def all_forwarding_offenses_correctable?(send_classifications)
|
310
|
+
return true if target_ruby_version >= 3.4
|
311
|
+
|
312
|
+
send_classifications.none? do |send_node, *|
|
313
|
+
send_node.each_ancestor(:any_block).any?
|
314
|
+
end
|
315
|
+
end
|
316
|
+
|
317
|
+
# Ruby 3.3.0 had a bug where accessing an anonymous block argument inside of a block
|
318
|
+
# was a syntax error in unambiguous cases: https://bugs.ruby-lang.org/issues/20090
|
319
|
+
# We disallow this also for earlier Ruby versions so that code is forwards compatible.
|
320
|
+
def allow_anonymous_forwarding_in_block?(node)
|
297
321
|
return false unless node
|
322
|
+
return true if target_ruby_version >= 3.4
|
298
323
|
|
299
|
-
node.each_ancestor(:
|
324
|
+
node.each_ancestor(:any_block).none?
|
300
325
|
end
|
301
326
|
|
302
327
|
def register_forward_args_offense(def_arguments_or_send, rest_arg_or_splat)
|
@@ -357,12 +382,6 @@ module RuboCop
|
|
357
382
|
cop_config.fetch('UseAnonymousForwarding', false)
|
358
383
|
end
|
359
384
|
|
360
|
-
def send_inside_block?(send_classifications)
|
361
|
-
send_classifications.any? do |send_node, *|
|
362
|
-
send_node.each_ancestor(:block, :numblock).any?
|
363
|
-
end
|
364
|
-
end
|
365
|
-
|
366
385
|
def add_parens_if_missing(node, corrector)
|
367
386
|
return if parentheses?(node)
|
368
387
|
return if node.send_type? && node.method?(:[])
|
@@ -511,7 +530,7 @@ module RuboCop
|
|
511
530
|
end
|
512
531
|
|
513
532
|
def additional_kwargs?
|
514
|
-
@def_node.arguments.any? { |a| a.
|
533
|
+
@def_node.arguments.any? { |a| a.type?(:kwarg, :kwoptarg) }
|
515
534
|
end
|
516
535
|
|
517
536
|
def forward_additional_kwargs?
|
@@ -42,14 +42,30 @@ module RuboCop
|
|
42
42
|
return if node.parent && brace_method?(node.parent)
|
43
43
|
|
44
44
|
preferred = (value.zero? ? 'first' : 'last')
|
45
|
-
|
46
|
-
|
45
|
+
offense_range = find_offense_range(node)
|
46
|
+
|
47
|
+
add_offense(offense_range, message: format(MSG, preferred: preferred)) do |corrector|
|
48
|
+
corrector.replace(offense_range, preferred_value(node, preferred))
|
47
49
|
end
|
48
50
|
end
|
49
51
|
# rubocop:enable Metrics/AbcSize
|
52
|
+
alias on_csend on_send
|
50
53
|
|
51
54
|
private
|
52
55
|
|
56
|
+
def preferred_value(node, value)
|
57
|
+
value = ".#{value}" unless node.loc.dot
|
58
|
+
value
|
59
|
+
end
|
60
|
+
|
61
|
+
def find_offense_range(node)
|
62
|
+
if node.loc.dot
|
63
|
+
node.loc.selector.join(node.source_range.end)
|
64
|
+
else
|
65
|
+
node.loc.selector
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
53
69
|
def innermost_braces_node(node)
|
54
70
|
node = node.receiver while node.receiver.send_type? && node.receiver.method?(:[])
|
55
71
|
node
|
@@ -195,6 +195,7 @@ module RuboCop
|
|
195
195
|
end
|
196
196
|
end
|
197
197
|
end
|
198
|
+
alias on_csend on_send
|
198
199
|
|
199
200
|
def on_block(node)
|
200
201
|
return if ignored_node?(node)
|
@@ -348,7 +349,7 @@ module RuboCop
|
|
348
349
|
case node.type
|
349
350
|
when :block, :numblock
|
350
351
|
yield node
|
351
|
-
when :send
|
352
|
+
when :send, :csend
|
352
353
|
# When a method has an argument which is another method with a block,
|
353
354
|
# that block needs braces, otherwise a syntax error will be introduced
|
354
355
|
# for subsequent arguments.
|
@@ -369,9 +370,8 @@ module RuboCop
|
|
369
370
|
end
|
370
371
|
# rubocop:enable Metrics/CyclomaticComplexity
|
371
372
|
|
372
|
-
# rubocop:disable Metrics/CyclomaticComplexity
|
373
373
|
def proper_block_style?(node)
|
374
|
-
return true if
|
374
|
+
return true if require_do_end?(node)
|
375
375
|
return special_method_proper_block_style?(node) if special_method?(node.method_name)
|
376
376
|
|
377
377
|
case style
|
@@ -381,15 +381,6 @@ module RuboCop
|
|
381
381
|
when :always_braces then braces_style?(node)
|
382
382
|
end
|
383
383
|
end
|
384
|
-
# rubocop:enable Metrics/CyclomaticComplexity
|
385
|
-
|
386
|
-
def require_braces?(node)
|
387
|
-
return false unless node.braces?
|
388
|
-
|
389
|
-
node.each_ancestor(:send).any? do |send|
|
390
|
-
send.arithmetic_operation? && node.source_range.end_pos < send.loc.selector.begin_pos
|
391
|
-
end
|
392
|
-
end
|
393
384
|
|
394
385
|
def require_do_end?(node)
|
395
386
|
return false if node.braces? || node.multiline?
|
@@ -483,18 +474,14 @@ module RuboCop
|
|
483
474
|
end
|
484
475
|
|
485
476
|
def return_value_of_scope?(node)
|
486
|
-
return false unless node.parent
|
487
|
-
|
488
|
-
conditional?(node.parent) || array_or_range?(node.parent) ||
|
489
|
-
node.parent.children.last == node
|
490
|
-
end
|
477
|
+
return false unless (parent = node.parent)
|
491
478
|
|
492
|
-
|
493
|
-
|
479
|
+
parent.conditional? || parent.operator_keyword? || array_or_range?(parent) ||
|
480
|
+
parent.children.last == node
|
494
481
|
end
|
495
482
|
|
496
483
|
def array_or_range?(node)
|
497
|
-
node.
|
484
|
+
node.type?(:array, :range)
|
498
485
|
end
|
499
486
|
|
500
487
|
def begin_required?(block_node)
|
@@ -49,7 +49,6 @@ module RuboCop
|
|
49
49
|
def on_block(node)
|
50
50
|
check_method_node(node.send_node)
|
51
51
|
end
|
52
|
-
|
53
52
|
alias on_numblock on_block
|
54
53
|
|
55
54
|
def on_send(node)
|
@@ -57,6 +56,7 @@ module RuboCop
|
|
57
56
|
|
58
57
|
check_method_node(node)
|
59
58
|
end
|
59
|
+
alias on_csend on_send
|
60
60
|
|
61
61
|
private
|
62
62
|
|
@@ -98,7 +98,7 @@ module RuboCop
|
|
98
98
|
end
|
99
99
|
|
100
100
|
def same_collection_looping_block?(node, sibling)
|
101
|
-
return false if sibling.nil? ||
|
101
|
+
return false if sibling.nil? || !sibling.any_block_type?
|
102
102
|
|
103
103
|
sibling.method?(node.method_name) &&
|
104
104
|
sibling.receiver == node.receiver &&
|
@@ -118,7 +118,7 @@ module RuboCop
|
|
118
118
|
|
119
119
|
def correct_end_of_block(corrector, node)
|
120
120
|
return unless node.left_sibling.respond_to?(:braces?)
|
121
|
-
return if node.right_sibling&.
|
121
|
+
return if node.right_sibling&.any_block_type?
|
122
122
|
|
123
123
|
end_of_block = node.left_sibling.braces? ? '}' : ' end'
|
124
124
|
corrector.remove(node.loc.end)
|
@@ -86,7 +86,7 @@ module RuboCop
|
|
86
86
|
|
87
87
|
def percent_literals_includes_only_basic_literals?(node)
|
88
88
|
node.arguments.select(&:percent_literal?).all? do |arg|
|
89
|
-
arg.children.all? { |child| child.
|
89
|
+
arg.children.all? { |child| child.type?(:str, :sym) }
|
90
90
|
end
|
91
91
|
end
|
92
92
|
end
|
@@ -107,7 +107,7 @@ module RuboCop
|
|
107
107
|
parent = node.parent
|
108
108
|
return true unless parent
|
109
109
|
|
110
|
-
!
|
110
|
+
!parent.type?(:mlhs, :resbody)
|
111
111
|
end
|
112
112
|
end
|
113
113
|
|
@@ -309,7 +309,7 @@ module RuboCop
|
|
309
309
|
end
|
310
310
|
|
311
311
|
def allowed_single_line?(branches)
|
312
|
-
single_line_conditions_only? && branches.any?(&:begin_type?)
|
312
|
+
single_line_conditions_only? && branches.compact.any?(&:begin_type?)
|
313
313
|
end
|
314
314
|
|
315
315
|
def assignment_node(node)
|
@@ -326,7 +326,7 @@ module RuboCop
|
|
326
326
|
end
|
327
327
|
|
328
328
|
def move_assignment_outside_condition(corrector, node)
|
329
|
-
if node.
|
329
|
+
if node.type?(:case, :case_match)
|
330
330
|
CaseCorrector.correct(corrector, self, node)
|
331
331
|
elsif node.ternary?
|
332
332
|
TernaryCorrector.correct(corrector, node)
|
@@ -340,7 +340,7 @@ module RuboCop
|
|
340
340
|
|
341
341
|
if ternary_condition?(condition)
|
342
342
|
TernaryCorrector.move_assignment_inside_condition(corrector, node)
|
343
|
-
elsif condition.
|
343
|
+
elsif condition.type?(:case, :case_match)
|
344
344
|
CaseCorrector.move_assignment_inside_condition(corrector, node)
|
345
345
|
elsif condition.if_type?
|
346
346
|
IfCorrector.move_assignment_inside_condition(corrector, node)
|
@@ -445,6 +445,8 @@ module RuboCop
|
|
445
445
|
end
|
446
446
|
|
447
447
|
[condition.loc.else, condition.loc.end].each do |loc|
|
448
|
+
next unless loc
|
449
|
+
|
448
450
|
corrector.remove_preceding(loc, loc.column - column)
|
449
451
|
end
|
450
452
|
end
|
@@ -186,7 +186,7 @@ module RuboCop
|
|
186
186
|
def qualify_const(node)
|
187
187
|
return if node.nil?
|
188
188
|
|
189
|
-
if node.
|
189
|
+
if node.type?(:cbase, :self, :call) || node.variable?
|
190
190
|
node.source
|
191
191
|
else
|
192
192
|
[qualify_const(node.namespace), node.short_name].compact
|
@@ -93,7 +93,7 @@ module RuboCop
|
|
93
93
|
|
94
94
|
if conditional_node
|
95
95
|
double_negative_condition_return_value?(node, last_child, conditional_node)
|
96
|
-
elsif last_child.
|
96
|
+
elsif last_child.type?(:pair, :hash) || last_child.parent.array_type?
|
97
97
|
false
|
98
98
|
else
|
99
99
|
last_child.last_line <= node.last_line
|
@@ -102,7 +102,7 @@ module RuboCop
|
|
102
102
|
|
103
103
|
def find_def_node_from_ascendant(node)
|
104
104
|
return unless (parent = node.parent)
|
105
|
-
return parent if parent.
|
105
|
+
return parent if parent.type?(:def, :defs)
|
106
106
|
return node.parent.child_nodes.first if define_method?(parent)
|
107
107
|
|
108
108
|
find_def_node_from_ascendant(node.parent)
|
@@ -147,7 +147,7 @@ module RuboCop
|
|
147
147
|
def find_parent_not_enumerable(node)
|
148
148
|
return unless (parent = node.parent)
|
149
149
|
|
150
|
-
if parent.
|
150
|
+
if parent.type?(:pair, :hash, :array)
|
151
151
|
find_parent_not_enumerable(parent)
|
152
152
|
else
|
153
153
|
parent
|
@@ -4,7 +4,7 @@ module RuboCop
|
|
4
4
|
module Cop
|
5
5
|
module Style
|
6
6
|
# Checks for loops which iterate a constant number of times,
|
7
|
-
# using a Range literal and `#each`. This can be done more readably using
|
7
|
+
# using a `Range` literal and `#each`. This can be done more readably using
|
8
8
|
# `Integer#times`.
|
9
9
|
#
|
10
10
|
# This check only applies if the block takes no parameters.
|
@@ -58,7 +58,7 @@ module RuboCop
|
|
58
58
|
|
59
59
|
# @!method each_with_object_block_candidate?(node)
|
60
60
|
def_node_matcher :each_with_object_block_candidate?, <<~PATTERN
|
61
|
-
(block $(call _ {:inject :reduce} _) $_ $_)
|
61
|
+
(block $(call _ {:inject :reduce} _) $(args _ _) $_)
|
62
62
|
PATTERN
|
63
63
|
|
64
64
|
# @!method each_with_object_numblock_candidate?(node)
|
@@ -71,8 +71,7 @@ module RuboCop
|
|
71
71
|
|
72
72
|
first_arg, second_arg = *node.arguments
|
73
73
|
|
74
|
-
corrector.
|
75
|
-
corrector.replace(second_arg, first_arg.source)
|
74
|
+
corrector.swap(first_arg, second_arg)
|
76
75
|
|
77
76
|
if return_value_occupies_whole_line?(return_value)
|
78
77
|
corrector.remove(whole_line_expression(return_value))
|
@@ -86,7 +86,7 @@ module RuboCop
|
|
86
86
|
return if node.method?(:eval) && !valid_eval_receiver?(node.receiver)
|
87
87
|
|
88
88
|
code = node.first_argument
|
89
|
-
return unless code
|
89
|
+
return unless code&.type?(:str, :dstr)
|
90
90
|
|
91
91
|
check_location(node, code)
|
92
92
|
end
|
@@ -123,7 +123,7 @@ module RuboCop
|
|
123
123
|
end
|
124
124
|
|
125
125
|
def call_like?(node)
|
126
|
-
node.
|
126
|
+
node.type?(:call, :zsuper, :super)
|
127
127
|
end
|
128
128
|
|
129
129
|
def insert_argument(node, corrector, block_name)
|
@@ -135,7 +135,13 @@ module RuboCop
|
|
135
135
|
end
|
136
136
|
|
137
137
|
def correct_call_node(node, corrector, block_name)
|
138
|
-
|
138
|
+
new_arguments = if node.zsuper_type?
|
139
|
+
args = build_new_arguments_for_zsuper(node) << "&#{block_name}"
|
140
|
+
args.join(', ')
|
141
|
+
else
|
142
|
+
"&#{block_name}"
|
143
|
+
end
|
144
|
+
corrector.insert_after(node, "(#{new_arguments})")
|
139
145
|
return unless node.parenthesized?
|
140
146
|
|
141
147
|
args_begin = Util.args_begin(node)
|
@@ -144,6 +150,13 @@ module RuboCop
|
|
144
150
|
corrector.remove(range)
|
145
151
|
end
|
146
152
|
|
153
|
+
def build_new_arguments_for_zsuper(node)
|
154
|
+
def_node = node.each_ancestor(:def, :defs).first
|
155
|
+
def_node.arguments.map do |arg|
|
156
|
+
arg.optarg_type? ? arg.node_parts[0] : arg.source
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
147
160
|
def block_body_range(block_node, send_node)
|
148
161
|
range_between(send_node.source_range.end_pos, block_node.loc.end.end_pos)
|
149
162
|
end
|
@@ -6,7 +6,7 @@ module RuboCop
|
|
6
6
|
# Suggests `ENV.fetch` for the replacement of `ENV[]`.
|
7
7
|
# `ENV[]` silently fails and returns `nil` when the environment variable is unset,
|
8
8
|
# which may cause unexpected behaviors when the developer forgets to set it.
|
9
|
-
# On the other hand, `ENV.fetch` raises KeyError or returns the explicitly
|
9
|
+
# On the other hand, `ENV.fetch` raises `KeyError` or returns the explicitly
|
10
10
|
# specified default value.
|
11
11
|
#
|
12
12
|
# @example
|
@@ -3,7 +3,7 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module Style
|
6
|
-
# Checks for uses of `each_key` and `each_value` Hash methods.
|
6
|
+
# Checks for uses of `each_key` and `each_value` `Hash` methods.
|
7
7
|
#
|
8
8
|
# NOTE: If you have an array of two-element arrays, you can put
|
9
9
|
# parentheses around the block arguments to indicate that you're not
|
@@ -44,7 +44,7 @@ module RuboCop
|
|
44
44
|
|
45
45
|
# @!method kv_each(node)
|
46
46
|
def_node_matcher :kv_each, <<~PATTERN
|
47
|
-
(
|
47
|
+
(any_block $(call (call _ ${:keys :values}) :each) ...)
|
48
48
|
PATTERN
|
49
49
|
|
50
50
|
# @!method each_arguments(node)
|
@@ -162,10 +162,7 @@ module RuboCop
|
|
162
162
|
|
163
163
|
def use_array_converter_method_as_preceding?(node)
|
164
164
|
return false unless (preceding_method = node.children.first.children.first)
|
165
|
-
unless preceding_method.
|
166
|
-
preceding_method.block_type? || preceding_method.numblock_type?
|
167
|
-
return false
|
168
|
-
end
|
165
|
+
return false unless preceding_method.type?(:call, :any_block)
|
169
166
|
|
170
167
|
ARRAY_CONVERTER_METHODS.include?(preceding_method.method_name)
|
171
168
|
end
|