rubocop 1.53.0 → 1.60.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.
- checksums.yaml +4 -4
- data/LICENSE.txt +1 -1
- data/README.md +5 -3
- data/config/default.yml +80 -11
- data/config/obsoletion.yml +5 -0
- data/lib/rubocop/cli/command/auto_generate_config.rb +10 -5
- data/lib/rubocop/cli.rb +1 -1
- data/lib/rubocop/config.rb +0 -2
- data/lib/rubocop/config_finder.rb +2 -2
- data/lib/rubocop/config_loader.rb +0 -1
- data/lib/rubocop/config_obsoletion/parameter_rule.rb +9 -1
- data/lib/rubocop/config_obsoletion.rb +11 -8
- data/lib/rubocop/config_validator.rb +0 -2
- data/lib/rubocop/cop/autocorrect_logic.rb +3 -1
- data/lib/rubocop/cop/base.rb +7 -1
- data/lib/rubocop/cop/bundler/duplicated_gem.rb +1 -0
- data/lib/rubocop/cop/bundler/duplicated_group.rb +127 -0
- data/lib/rubocop/cop/bundler/gem_comment.rb +2 -2
- data/lib/rubocop/cop/bundler/ordered_gems.rb +9 -1
- data/lib/rubocop/cop/correctors/lambda_literal_to_method_corrector.rb +7 -4
- data/lib/rubocop/cop/exclude_limit.rb +1 -1
- data/lib/rubocop/cop/gemspec/deprecated_attribute_assignment.rb +2 -2
- data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +9 -1
- data/lib/rubocop/cop/generator/require_file_injector.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/example_description.rb +42 -21
- data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +3 -1
- data/lib/rubocop/cop/internal_affairs/method_name_equal.rb +19 -20
- data/lib/rubocop/cop/internal_affairs/node_first_or_last_argument.rb +53 -0
- data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +2 -2
- data/lib/rubocop/cop/internal_affairs/redundant_method_dispatch_node.rb +11 -2
- data/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +2 -0
- data/lib/rubocop/cop/internal_affairs.rb +1 -0
- data/lib/rubocop/cop/layout/argument_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/dot_position.rb +1 -5
- data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +42 -9
- data/lib/rubocop/cop/layout/empty_line_between_defs.rb +26 -3
- data/lib/rubocop/cop/layout/end_alignment.rb +12 -2
- data/lib/rubocop/cop/layout/extra_spacing.rb +4 -10
- data/lib/rubocop/cop/layout/first_array_element_indentation.rb +22 -7
- data/lib/rubocop/cop/layout/first_parameter_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +2 -2
- data/lib/rubocop/cop/layout/heredoc_indentation.rb +4 -1
- data/lib/rubocop/cop/layout/indentation_width.rb +1 -1
- data/lib/rubocop/cop/layout/leading_comment_space.rb +1 -1
- data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +17 -9
- data/lib/rubocop/cop/layout/line_continuation_spacing.rb +1 -1
- data/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb +2 -0
- data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +18 -3
- data/lib/rubocop/cop/layout/redundant_line_break.rb +15 -4
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +4 -4
- data/lib/rubocop/cop/layout/single_line_block_chain.rb +5 -0
- data/lib/rubocop/cop/layout/space_after_comma.rb +9 -1
- data/lib/rubocop/cop/layout/space_after_not.rb +1 -1
- data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +2 -2
- data/lib/rubocop/cop/layout/space_around_operators.rb +53 -21
- data/lib/rubocop/cop/layout/space_inside_parens.rb +1 -1
- data/lib/rubocop/cop/layout/trailing_empty_lines.rb +5 -0
- data/lib/rubocop/cop/lint/assignment_in_condition.rb +4 -4
- data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +2 -2
- data/lib/rubocop/cop/lint/constant_overwritten_in_rescue.rb +1 -1
- data/lib/rubocop/cop/lint/debugger.rb +18 -4
- data/lib/rubocop/cop/lint/duplicate_methods.rb +1 -1
- data/lib/rubocop/cop/lint/empty_block.rb +1 -1
- data/lib/rubocop/cop/lint/erb_new_arguments.rb +3 -3
- data/lib/rubocop/cop/lint/float_comparison.rb +10 -0
- data/lib/rubocop/cop/lint/hash_compare_by_identity.rb +2 -1
- data/lib/rubocop/cop/lint/it_without_arguments_in_block.rb +56 -0
- data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +85 -0
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +1 -1
- data/lib/rubocop/cop/lint/mixed_case_range.rb +3 -1
- data/lib/rubocop/cop/lint/next_without_accumulator.rb +6 -21
- data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +10 -7
- data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +3 -5
- data/lib/rubocop/cop/lint/number_conversion.rb +9 -4
- data/lib/rubocop/cop/lint/redundant_regexp_quantifiers.rb +10 -0
- data/lib/rubocop/cop/lint/redundant_require_statement.rb +4 -0
- data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +63 -4
- data/lib/rubocop/cop/lint/redundant_with_index.rb +2 -2
- data/lib/rubocop/cop/lint/redundant_with_object.rb +2 -2
- data/lib/rubocop/cop/lint/safe_navigation_chain.rb +14 -8
- data/lib/rubocop/cop/lint/self_assignment.rb +38 -0
- data/lib/rubocop/cop/lint/shadowed_argument.rb +1 -0
- data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +7 -1
- data/lib/rubocop/cop/lint/struct_new_override.rb +12 -12
- data/lib/rubocop/cop/lint/suppressed_exception.rb +1 -1
- data/lib/rubocop/cop/lint/symbol_conversion.rb +8 -3
- data/lib/rubocop/cop/lint/syntax.rb +6 -3
- data/lib/rubocop/cop/lint/to_enum_arguments.rb +5 -3
- data/lib/rubocop/cop/lint/trailing_comma_in_attribute_declaration.rb +1 -1
- data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +2 -2
- data/lib/rubocop/cop/lint/useless_access_modifier.rb +2 -2
- data/lib/rubocop/cop/lint/useless_assignment.rb +38 -12
- data/lib/rubocop/cop/lint/useless_times.rb +1 -1
- data/lib/rubocop/cop/lint/void.rb +46 -21
- data/lib/rubocop/cop/metrics/abc_size.rb +3 -3
- data/lib/rubocop/cop/metrics/block_length.rb +1 -1
- data/lib/rubocop/cop/metrics/class_length.rb +8 -3
- data/lib/rubocop/cop/metrics/method_length.rb +1 -1
- data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +32 -4
- data/lib/rubocop/cop/mixin/check_line_breakable.rb +1 -1
- data/lib/rubocop/cop/mixin/comments_help.rb +16 -12
- data/lib/rubocop/cop/mixin/configurable_formatting.rb +1 -0
- data/lib/rubocop/cop/mixin/def_node.rb +1 -1
- data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +14 -11
- data/lib/rubocop/cop/mixin/heredoc.rb +6 -2
- data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +3 -2
- data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +6 -8
- data/lib/rubocop/cop/mixin/space_before_punctuation.rb +1 -1
- data/lib/rubocop/cop/mixin/string_help.rb +4 -2
- data/lib/rubocop/cop/mixin/trailing_comma.rb +1 -1
- data/lib/rubocop/cop/naming/block_forwarding.rb +12 -4
- data/lib/rubocop/cop/naming/constant_name.rb +1 -2
- data/lib/rubocop/cop/naming/file_name.rb +1 -1
- data/lib/rubocop/cop/naming/heredoc_delimiter_naming.rb +3 -1
- data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +1 -1
- data/lib/rubocop/cop/registry.rb +4 -4
- data/lib/rubocop/cop/security/open.rb +2 -2
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +2 -2
- data/lib/rubocop/cop/style/accessor_grouping.rb +1 -1
- data/lib/rubocop/cop/style/alias.rb +9 -8
- data/lib/rubocop/cop/style/arguments_forwarding.rb +355 -63
- data/lib/rubocop/cop/style/array_first_last.rb +64 -0
- data/lib/rubocop/cop/style/array_intersect.rb +13 -5
- data/lib/rubocop/cop/style/auto_resource_cleanup.rb +21 -14
- data/lib/rubocop/cop/style/bisected_attr_accessor.rb +2 -2
- data/lib/rubocop/cop/style/block_delimiters.rb +2 -1
- data/lib/rubocop/cop/style/case_like_if.rb +4 -4
- data/lib/rubocop/cop/style/class_check.rb +1 -0
- data/lib/rubocop/cop/style/class_equality_comparison.rb +7 -0
- data/lib/rubocop/cop/style/collection_compact.rb +7 -6
- data/lib/rubocop/cop/style/collection_methods.rb +2 -0
- data/lib/rubocop/cop/style/combinable_loops.rb +17 -9
- data/lib/rubocop/cop/style/concat_array_literals.rb +2 -1
- data/lib/rubocop/cop/style/conditional_assignment.rb +2 -2
- data/lib/rubocop/cop/style/date_time.rb +5 -4
- data/lib/rubocop/cop/style/each_for_simple_loop.rb +7 -7
- data/lib/rubocop/cop/style/each_with_object.rb +2 -2
- data/lib/rubocop/cop/style/empty_case_condition.rb +6 -1
- data/lib/rubocop/cop/style/empty_literal.rb +1 -1
- data/lib/rubocop/cop/style/eval_with_location.rb +3 -14
- data/lib/rubocop/cop/style/exact_regexp_match.rb +2 -1
- data/lib/rubocop/cop/style/explicit_block_argument.rb +2 -2
- data/lib/rubocop/cop/style/for.rb +1 -1
- data/lib/rubocop/cop/style/format_string.rb +24 -3
- data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +3 -1
- data/lib/rubocop/cop/style/guard_clause.rb +26 -0
- data/lib/rubocop/cop/style/hash_conversion.rb +10 -0
- data/lib/rubocop/cop/style/hash_each_methods.rb +83 -10
- data/lib/rubocop/cop/style/hash_except.rb +2 -1
- data/lib/rubocop/cop/style/identical_conditional_branches.rb +28 -3
- data/lib/rubocop/cop/style/if_with_semicolon.rb +2 -2
- data/lib/rubocop/cop/style/inverse_methods.rb +6 -5
- data/lib/rubocop/cop/style/invertible_unless_condition.rb +39 -2
- data/lib/rubocop/cop/style/lambda.rb +3 -3
- data/lib/rubocop/cop/style/lambda_call.rb +5 -0
- data/lib/rubocop/cop/style/map_compact_with_conditional_block.rb +3 -2
- data/lib/rubocop/cop/style/map_to_hash.rb +17 -7
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +22 -6
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +2 -4
- data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +20 -0
- data/lib/rubocop/cop/style/method_def_parentheses.rb +1 -1
- data/lib/rubocop/cop/style/missing_respond_to_missing.rb +2 -2
- data/lib/rubocop/cop/style/mixin_grouping.rb +1 -1
- data/lib/rubocop/cop/style/multiline_block_chain.rb +1 -1
- data/lib/rubocop/cop/style/multiline_ternary_operator.rb +2 -4
- data/lib/rubocop/cop/style/nested_ternary_operator.rb +3 -11
- data/lib/rubocop/cop/style/next.rb +1 -1
- data/lib/rubocop/cop/style/numeric_literal_prefix.rb +1 -1
- data/lib/rubocop/cop/style/open_struct_use.rb +1 -1
- data/lib/rubocop/cop/style/operator_method_call.rb +8 -2
- data/lib/rubocop/cop/style/parallel_assignment.rb +2 -2
- data/lib/rubocop/cop/style/parentheses_around_condition.rb +8 -0
- data/lib/rubocop/cop/style/redundant_argument.rb +9 -3
- data/lib/rubocop/cop/style/redundant_begin.rb +9 -1
- data/lib/rubocop/cop/style/redundant_conditional.rb +1 -9
- data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +1 -1
- data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +93 -5
- data/lib/rubocop/cop/style/redundant_each.rb +7 -4
- data/lib/rubocop/cop/style/redundant_exception.rb +32 -12
- data/lib/rubocop/cop/style/redundant_fetch_block.rb +3 -3
- data/lib/rubocop/cop/style/redundant_filter_chain.rb +22 -5
- data/lib/rubocop/cop/style/redundant_line_continuation.rb +10 -1
- data/lib/rubocop/cop/style/redundant_parentheses.rb +63 -21
- data/lib/rubocop/cop/style/redundant_regexp_argument.rb +18 -4
- data/lib/rubocop/cop/style/redundant_return.rb +8 -3
- data/lib/rubocop/cop/style/redundant_self.rb +17 -2
- data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +5 -0
- data/lib/rubocop/cop/style/redundant_sort.rb +9 -8
- data/lib/rubocop/cop/style/redundant_sort_by.rb +2 -2
- data/lib/rubocop/cop/style/redundant_string_escape.rb +1 -1
- data/lib/rubocop/cop/style/return_nil.rb +6 -2
- data/lib/rubocop/cop/style/return_nil_in_predicate_method_definition.rb +23 -9
- data/lib/rubocop/cop/style/sample.rb +2 -1
- data/lib/rubocop/cop/style/select_by_regexp.rb +7 -6
- data/lib/rubocop/cop/style/self_assignment.rb +1 -1
- data/lib/rubocop/cop/style/semicolon.rb +8 -3
- data/lib/rubocop/cop/style/single_argument_dig.rb +7 -3
- data/lib/rubocop/cop/style/single_line_do_end_block.rb +67 -0
- data/lib/rubocop/cop/style/slicing_with_range.rb +76 -10
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +3 -1
- data/lib/rubocop/cop/style/string_chars.rb +1 -0
- data/lib/rubocop/cop/style/string_literals_in_interpolation.rb +30 -5
- data/lib/rubocop/cop/style/strip.rb +7 -4
- data/lib/rubocop/cop/style/super_with_args_parentheses.rb +35 -0
- data/lib/rubocop/cop/style/symbol_array.rb +35 -15
- data/lib/rubocop/cop/style/symbol_proc.rb +36 -0
- data/lib/rubocop/cop/style/unpack_first.rb +11 -14
- data/lib/rubocop/cop/style/yoda_condition.rb +4 -2
- data/lib/rubocop/cop/style/yoda_expression.rb +8 -7
- data/lib/rubocop/cop/utils/regexp_ranges.rb +26 -13
- data/lib/rubocop/cop/variable_force/assignment.rb +14 -5
- data/lib/rubocop/cops_documentation_generator.rb +11 -1
- data/lib/rubocop/ext/regexp_node.rb +9 -4
- data/lib/rubocop/file_finder.rb +4 -7
- data/lib/rubocop/formatter/disabled_config_formatter.rb +17 -6
- data/lib/rubocop/formatter/html_formatter.rb +5 -4
- data/lib/rubocop/formatter/json_formatter.rb +0 -1
- data/lib/rubocop/formatter/junit_formatter.rb +1 -1
- data/lib/rubocop/formatter.rb +1 -1
- data/lib/rubocop/lsp/routes.rb +42 -19
- data/lib/rubocop/lsp/runtime.rb +22 -2
- data/lib/rubocop/lsp/server.rb +10 -4
- data/lib/rubocop/magic_comment.rb +12 -10
- data/lib/rubocop/options.rb +0 -8
- data/lib/rubocop/result_cache.rb +4 -1
- data/lib/rubocop/rspec/shared_contexts.rb +8 -3
- data/lib/rubocop/rspec/support.rb +1 -0
- data/lib/rubocop/runner.rb +6 -4
- data/lib/rubocop/server/client_command/exec.rb +1 -1
- data/lib/rubocop/string_interpreter.rb +3 -3
- data/lib/rubocop/target_finder.rb +7 -3
- data/lib/rubocop/target_ruby.rb +9 -5
- data/lib/rubocop/version.rb +1 -1
- data/lib/rubocop.rb +6 -0
- metadata +20 -13
- /data/lib/rubocop/formatter/{git_hub_actions_formatter.rb → github_actions_formatter.rb} +0 -0
|
@@ -125,7 +125,7 @@ module RuboCop
|
|
|
125
125
|
when :==, :eql?, :equal?
|
|
126
126
|
find_target_in_equality_node(node)
|
|
127
127
|
when :===
|
|
128
|
-
node.
|
|
128
|
+
node.first_argument
|
|
129
129
|
when :include?, :cover?
|
|
130
130
|
find_target_in_include_or_cover_node(node)
|
|
131
131
|
when :match, :match?, :=~
|
|
@@ -134,7 +134,7 @@ module RuboCop
|
|
|
134
134
|
end
|
|
135
135
|
|
|
136
136
|
def find_target_in_equality_node(node)
|
|
137
|
-
argument = node.
|
|
137
|
+
argument = node.first_argument
|
|
138
138
|
receiver = node.receiver
|
|
139
139
|
return unless argument && receiver
|
|
140
140
|
|
|
@@ -152,7 +152,7 @@ module RuboCop
|
|
|
152
152
|
end
|
|
153
153
|
|
|
154
154
|
def find_target_in_match_node(node)
|
|
155
|
-
argument = node.
|
|
155
|
+
argument = node.first_argument
|
|
156
156
|
receiver = node.receiver
|
|
157
157
|
return unless receiver
|
|
158
158
|
|
|
@@ -185,7 +185,7 @@ module RuboCop
|
|
|
185
185
|
def condition_from_send_node(node, target)
|
|
186
186
|
case node.method_name
|
|
187
187
|
when :is_a?
|
|
188
|
-
node.
|
|
188
|
+
node.first_argument if node.receiver == target
|
|
189
189
|
when :==, :eql?, :equal?
|
|
190
190
|
condition_from_equality_node(node, target)
|
|
191
191
|
when :=~, :match, :match?
|
|
@@ -8,6 +8,11 @@ module RuboCop
|
|
|
8
8
|
# `==`, `equal?`, and `eql?` custom method definitions are allowed by default.
|
|
9
9
|
# These are customizable with `AllowedMethods` option.
|
|
10
10
|
#
|
|
11
|
+
# @safety
|
|
12
|
+
# This cop's autocorrection is unsafe because there is no guarantee that
|
|
13
|
+
# the constant `Foo` exists when autocorrecting `var.class.name == 'Foo'` to
|
|
14
|
+
# `var.instance_of?(Foo)`.
|
|
15
|
+
#
|
|
11
16
|
# @example
|
|
12
17
|
# # bad
|
|
13
18
|
# var.class == Date
|
|
@@ -69,6 +74,8 @@ module RuboCop
|
|
|
69
74
|
matches_allowed_pattern?(def_node.method_name))
|
|
70
75
|
|
|
71
76
|
class_comparison_candidate?(node) do |receiver_node, class_node|
|
|
77
|
+
return if class_node.dstr_type?
|
|
78
|
+
|
|
72
79
|
range = offense_range(receiver_node, node)
|
|
73
80
|
class_argument = (class_name = class_name(class_node, node)) ? "(#{class_name})" : ''
|
|
74
81
|
|
|
@@ -53,7 +53,7 @@ module RuboCop
|
|
|
53
53
|
|
|
54
54
|
# @!method reject_method_with_block_pass?(node)
|
|
55
55
|
def_node_matcher :reject_method_with_block_pass?, <<~PATTERN
|
|
56
|
-
(
|
|
56
|
+
(call !nil? {:reject :delete_if :reject!}
|
|
57
57
|
(block_pass
|
|
58
58
|
(sym :nil?)))
|
|
59
59
|
PATTERN
|
|
@@ -61,21 +61,21 @@ module RuboCop
|
|
|
61
61
|
# @!method reject_method?(node)
|
|
62
62
|
def_node_matcher :reject_method?, <<~PATTERN
|
|
63
63
|
(block
|
|
64
|
-
(
|
|
64
|
+
(call
|
|
65
65
|
!nil? {:reject :delete_if :reject!})
|
|
66
66
|
$(args ...)
|
|
67
|
-
(
|
|
67
|
+
(call
|
|
68
68
|
$(lvar _) :nil?))
|
|
69
69
|
PATTERN
|
|
70
70
|
|
|
71
71
|
# @!method select_method?(node)
|
|
72
72
|
def_node_matcher :select_method?, <<~PATTERN
|
|
73
73
|
(block
|
|
74
|
-
(
|
|
74
|
+
(call
|
|
75
75
|
!nil? {:select :select!})
|
|
76
76
|
$(args ...)
|
|
77
|
-
(
|
|
78
|
-
(
|
|
77
|
+
(call
|
|
78
|
+
(call
|
|
79
79
|
$(lvar _) :nil?) :!))
|
|
80
80
|
PATTERN
|
|
81
81
|
|
|
@@ -91,6 +91,7 @@ module RuboCop
|
|
|
91
91
|
|
|
92
92
|
add_offense(range, message: message) { |corrector| corrector.replace(range, good) }
|
|
93
93
|
end
|
|
94
|
+
alias on_csend on_send
|
|
94
95
|
|
|
95
96
|
private
|
|
96
97
|
|
|
@@ -25,6 +25,7 @@ module RuboCop
|
|
|
25
25
|
# # bad
|
|
26
26
|
# items.collect
|
|
27
27
|
# items.collect!
|
|
28
|
+
# items.collect_concat
|
|
28
29
|
# items.inject
|
|
29
30
|
# items.detect
|
|
30
31
|
# items.find_all
|
|
@@ -33,6 +34,7 @@ module RuboCop
|
|
|
33
34
|
# # good
|
|
34
35
|
# items.map
|
|
35
36
|
# items.map!
|
|
37
|
+
# items.flat_map
|
|
36
38
|
# items.reduce
|
|
37
39
|
# items.find
|
|
38
40
|
# items.select
|
|
@@ -59,14 +59,13 @@ module RuboCop
|
|
|
59
59
|
class CombinableLoops < Base
|
|
60
60
|
extend AutoCorrector
|
|
61
61
|
|
|
62
|
-
include RangeHelp
|
|
63
|
-
|
|
64
62
|
MSG = 'Combine this loop with the previous loop.'
|
|
65
63
|
|
|
66
64
|
def on_block(node)
|
|
67
65
|
return unless node.parent&.begin_type?
|
|
68
66
|
return unless collection_looping_method?(node)
|
|
69
67
|
return unless same_collection_looping_block?(node, node.left_sibling)
|
|
68
|
+
return unless node.body && node.left_sibling.body
|
|
70
69
|
|
|
71
70
|
add_offense(node) do |corrector|
|
|
72
71
|
combine_with_left_sibling(corrector, node)
|
|
@@ -92,8 +91,9 @@ module RuboCop
|
|
|
92
91
|
end
|
|
93
92
|
|
|
94
93
|
def same_collection_looping_block?(node, sibling)
|
|
95
|
-
(sibling
|
|
96
|
-
|
|
94
|
+
return false if sibling.nil? || (!sibling.block_type? && !sibling.numblock_type?)
|
|
95
|
+
|
|
96
|
+
sibling.method?(node.method_name) &&
|
|
97
97
|
sibling.receiver == node.receiver &&
|
|
98
98
|
sibling.send_node.arguments == node.send_node.arguments
|
|
99
99
|
end
|
|
@@ -103,11 +103,19 @@ module RuboCop
|
|
|
103
103
|
end
|
|
104
104
|
|
|
105
105
|
def combine_with_left_sibling(corrector, node)
|
|
106
|
-
corrector.
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
)
|
|
110
|
-
|
|
106
|
+
corrector.remove(node.left_sibling.body.source_range.end.join(node.left_sibling.loc.end))
|
|
107
|
+
corrector.remove(node.source_range.begin.join(node.body.source_range.begin))
|
|
108
|
+
|
|
109
|
+
correct_end_of_block(corrector, node)
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def correct_end_of_block(corrector, node)
|
|
113
|
+
return unless node.left_sibling.respond_to?(:braces?)
|
|
114
|
+
return if node.right_sibling&.block_type? || node.right_sibling&.numblock_type?
|
|
115
|
+
|
|
116
|
+
end_of_block = node.left_sibling.braces? ? '}' : ' end'
|
|
117
|
+
corrector.remove(node.loc.end)
|
|
118
|
+
corrector.insert_before(node.source_range.end, end_of_block)
|
|
111
119
|
end
|
|
112
120
|
end
|
|
113
121
|
end
|
|
@@ -63,6 +63,7 @@ module RuboCop
|
|
|
63
63
|
end
|
|
64
64
|
end
|
|
65
65
|
# rubocop:enable Metrics
|
|
66
|
+
alias on_csend on_send
|
|
66
67
|
|
|
67
68
|
private
|
|
68
69
|
|
|
@@ -74,7 +75,7 @@ module RuboCop
|
|
|
74
75
|
new_arguments =
|
|
75
76
|
node.arguments.map do |arg|
|
|
76
77
|
if arg.percent_literal?
|
|
77
|
-
arg.children.map
|
|
78
|
+
arg.children.map { |child| child.value.inspect }
|
|
78
79
|
else
|
|
79
80
|
arg.children.map(&:source)
|
|
80
81
|
end
|
|
@@ -233,7 +233,7 @@ module RuboCop
|
|
|
233
233
|
PATTERN
|
|
234
234
|
|
|
235
235
|
ASSIGNMENT_TYPES.each do |type|
|
|
236
|
-
define_method "on_#{type}" do |node|
|
|
236
|
+
define_method :"on_#{type}" do |node|
|
|
237
237
|
return if part_of_ignored_node?(node)
|
|
238
238
|
return if node.parent&.shorthand_asgn?
|
|
239
239
|
|
|
@@ -534,7 +534,7 @@ module RuboCop
|
|
|
534
534
|
end
|
|
535
535
|
|
|
536
536
|
def element_assignment?(node)
|
|
537
|
-
node.send_type? && node.
|
|
537
|
+
node.send_type? && !node.method?(:[]=)
|
|
538
538
|
end
|
|
539
539
|
|
|
540
540
|
def extract_branches(node)
|
|
@@ -49,12 +49,12 @@ module RuboCop
|
|
|
49
49
|
class DateTime < Base
|
|
50
50
|
extend AutoCorrector
|
|
51
51
|
|
|
52
|
-
CLASS_MSG = 'Prefer Time over DateTime
|
|
53
|
-
COERCION_MSG = 'Do not use
|
|
52
|
+
CLASS_MSG = 'Prefer `Time` over `DateTime`.'
|
|
53
|
+
COERCION_MSG = 'Do not use `#to_datetime`.'
|
|
54
54
|
|
|
55
55
|
# @!method date_time?(node)
|
|
56
56
|
def_node_matcher :date_time?, <<~PATTERN
|
|
57
|
-
(
|
|
57
|
+
(call (const {nil? (cbase)} :DateTime) ...)
|
|
58
58
|
PATTERN
|
|
59
59
|
|
|
60
60
|
# @!method historic_date?(node)
|
|
@@ -64,7 +64,7 @@ module RuboCop
|
|
|
64
64
|
|
|
65
65
|
# @!method to_datetime?(node)
|
|
66
66
|
def_node_matcher :to_datetime?, <<~PATTERN
|
|
67
|
-
(
|
|
67
|
+
(call _ :to_datetime)
|
|
68
68
|
PATTERN
|
|
69
69
|
|
|
70
70
|
def on_send(node)
|
|
@@ -75,6 +75,7 @@ module RuboCop
|
|
|
75
75
|
|
|
76
76
|
add_offense(node, message: message) { |corrector| autocorrect(corrector, node) }
|
|
77
77
|
end
|
|
78
|
+
alias on_csend on_send
|
|
78
79
|
|
|
79
80
|
private
|
|
80
81
|
|
|
@@ -32,27 +32,27 @@ module RuboCop
|
|
|
32
32
|
|
|
33
33
|
send_node = node.send_node
|
|
34
34
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
add_offense(range) do |corrector|
|
|
35
|
+
add_offense(send_node) do |corrector|
|
|
38
36
|
range_type, min, max = each_range(node)
|
|
39
37
|
|
|
40
38
|
max += 1 if range_type == :irange
|
|
41
39
|
|
|
42
|
-
corrector.replace(
|
|
40
|
+
corrector.replace(send_node, "#{max - min}.times")
|
|
43
41
|
end
|
|
44
42
|
end
|
|
45
43
|
|
|
46
44
|
private
|
|
47
45
|
|
|
48
46
|
def offending?(node)
|
|
47
|
+
return false unless node.arguments.empty?
|
|
48
|
+
|
|
49
49
|
each_range_with_zero_origin?(node) || each_range_without_block_argument?(node)
|
|
50
50
|
end
|
|
51
51
|
|
|
52
52
|
# @!method each_range(node)
|
|
53
53
|
def_node_matcher :each_range, <<~PATTERN
|
|
54
54
|
(block
|
|
55
|
-
(
|
|
55
|
+
(call
|
|
56
56
|
(begin
|
|
57
57
|
(${irange erange}
|
|
58
58
|
(int $_) (int $_)))
|
|
@@ -64,7 +64,7 @@ module RuboCop
|
|
|
64
64
|
# @!method each_range_with_zero_origin?(node)
|
|
65
65
|
def_node_matcher :each_range_with_zero_origin?, <<~PATTERN
|
|
66
66
|
(block
|
|
67
|
-
(
|
|
67
|
+
(call
|
|
68
68
|
(begin
|
|
69
69
|
({irange erange}
|
|
70
70
|
(int 0) (int _)))
|
|
@@ -76,7 +76,7 @@ module RuboCop
|
|
|
76
76
|
# @!method each_range_without_block_argument?(node)
|
|
77
77
|
def_node_matcher :each_range_without_block_argument?, <<~PATTERN
|
|
78
78
|
(block
|
|
79
|
-
(
|
|
79
|
+
(call
|
|
80
80
|
(begin
|
|
81
81
|
({irange erange}
|
|
82
82
|
(int _) (int _)))
|
|
@@ -58,12 +58,12 @@ 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 $(
|
|
61
|
+
(block $(call _ {:inject :reduce} _) $_ $_)
|
|
62
62
|
PATTERN
|
|
63
63
|
|
|
64
64
|
# @!method each_with_object_numblock_candidate?(node)
|
|
65
65
|
def_node_matcher :each_with_object_numblock_candidate?, <<~PATTERN
|
|
66
|
-
(numblock $(
|
|
66
|
+
(numblock $(call _ {:inject :reduce} _) 2 $_)
|
|
67
67
|
PATTERN
|
|
68
68
|
|
|
69
69
|
def autocorrect_block(corrector, node, return_value)
|
|
@@ -40,9 +40,13 @@ module RuboCop
|
|
|
40
40
|
extend AutoCorrector
|
|
41
41
|
|
|
42
42
|
MSG = 'Do not use empty `case` condition, instead use an `if` expression.'
|
|
43
|
+
NOT_SUPPORTED_PARENT_TYPES = %i[return break next send csend].freeze
|
|
43
44
|
|
|
45
|
+
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
44
46
|
def on_case(case_node)
|
|
45
|
-
|
|
47
|
+
if case_node.condition || NOT_SUPPORTED_PARENT_TYPES.include?(case_node.parent&.type)
|
|
48
|
+
return
|
|
49
|
+
end
|
|
46
50
|
|
|
47
51
|
branch_bodies = [*case_node.when_branches.map(&:body), case_node.else_branch].compact
|
|
48
52
|
|
|
@@ -52,6 +56,7 @@ module RuboCop
|
|
|
52
56
|
|
|
53
57
|
add_offense(case_node.loc.keyword) { |corrector| autocorrect(corrector, case_node) }
|
|
54
58
|
end
|
|
59
|
+
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
55
60
|
|
|
56
61
|
private
|
|
57
62
|
|
|
@@ -83,7 +83,7 @@ module RuboCop
|
|
|
83
83
|
parent = node.parent
|
|
84
84
|
return false unless parent && %i[send super zsuper].include?(parent.type)
|
|
85
85
|
|
|
86
|
-
node.equal?(parent.
|
|
86
|
+
node.equal?(parent.first_argument) && !parentheses?(node.parent)
|
|
87
87
|
end
|
|
88
88
|
|
|
89
89
|
def replacement_range(node)
|
|
@@ -84,7 +84,7 @@ module RuboCop
|
|
|
84
84
|
# are considered.
|
|
85
85
|
return if node.method?(:eval) && !valid_eval_receiver?(node.receiver)
|
|
86
86
|
|
|
87
|
-
code = node.
|
|
87
|
+
code = node.first_argument
|
|
88
88
|
return unless code && (code.str_type? || code.dstr_type?)
|
|
89
89
|
|
|
90
90
|
check_location(node, code)
|
|
@@ -128,17 +128,6 @@ module RuboCop
|
|
|
128
128
|
node.method?(:eval) ? node.arguments.size >= 2 : true
|
|
129
129
|
end
|
|
130
130
|
|
|
131
|
-
# FIXME: It's a Style/ConditionalAssignment's false positive.
|
|
132
|
-
# rubocop:disable Style/ConditionalAssignment
|
|
133
|
-
def with_lineno?(node)
|
|
134
|
-
if node.method?(:eval)
|
|
135
|
-
node.arguments.size == 4
|
|
136
|
-
else
|
|
137
|
-
node.arguments.size == 3
|
|
138
|
-
end
|
|
139
|
-
end
|
|
140
|
-
# rubocop:enable Style/ConditionalAssignment
|
|
141
|
-
|
|
142
131
|
def add_offense_for_incorrect_line(method_name, line_node, sign, line_diff)
|
|
143
132
|
expected = expected_line(sign, line_diff)
|
|
144
133
|
message = format(MSG_INCORRECT_LINE,
|
|
@@ -165,7 +154,7 @@ module RuboCop
|
|
|
165
154
|
end
|
|
166
155
|
|
|
167
156
|
def check_line(node, code)
|
|
168
|
-
line_node = node.
|
|
157
|
+
line_node = node.last_argument
|
|
169
158
|
line_diff = line_difference(line_node, code)
|
|
170
159
|
if line_diff.zero?
|
|
171
160
|
add_offense_for_same_line(node, line_node)
|
|
@@ -227,7 +216,7 @@ module RuboCop
|
|
|
227
216
|
end
|
|
228
217
|
|
|
229
218
|
def missing_line(node, code)
|
|
230
|
-
line_diff = line_difference(node.
|
|
219
|
+
line_diff = line_difference(node.last_argument, code)
|
|
231
220
|
sign = line_diff.positive? ? :+ : :-
|
|
232
221
|
expected_line(sign, line_diff)
|
|
233
222
|
end
|
|
@@ -30,7 +30,7 @@ module RuboCop
|
|
|
30
30
|
|
|
31
31
|
# @!method exact_regexp_match(node)
|
|
32
32
|
def_node_matcher :exact_regexp_match, <<~PATTERN
|
|
33
|
-
(
|
|
33
|
+
(call
|
|
34
34
|
_ {:=~ :=== :!~ :match :match?}
|
|
35
35
|
(regexp
|
|
36
36
|
(str $_)
|
|
@@ -49,6 +49,7 @@ module RuboCop
|
|
|
49
49
|
corrector.replace(node, prefer)
|
|
50
50
|
end
|
|
51
51
|
end
|
|
52
|
+
alias on_csend on_send
|
|
52
53
|
|
|
53
54
|
private
|
|
54
55
|
|
|
@@ -86,7 +86,7 @@ module RuboCop
|
|
|
86
86
|
|
|
87
87
|
def extract_block_name(def_node)
|
|
88
88
|
if def_node.block_argument?
|
|
89
|
-
def_node.
|
|
89
|
+
def_node.last_argument.name
|
|
90
90
|
else
|
|
91
91
|
'block'
|
|
92
92
|
end
|
|
@@ -127,7 +127,7 @@ module RuboCop
|
|
|
127
127
|
end
|
|
128
128
|
|
|
129
129
|
def insert_argument(node, corrector, block_name)
|
|
130
|
-
last_arg = node.
|
|
130
|
+
last_arg = node.last_argument
|
|
131
131
|
arg_range = range_with_surrounding_comma(last_arg.source_range, :right)
|
|
132
132
|
replacement = " &#{block_name}"
|
|
133
133
|
replacement = ",#{replacement}" unless arg_range.source.end_with?(',')
|
|
@@ -4,13 +4,25 @@ module RuboCop
|
|
|
4
4
|
module Cop
|
|
5
5
|
module Style
|
|
6
6
|
# Enforces the use of a single string formatting utility.
|
|
7
|
-
# Valid options include Kernel#format
|
|
7
|
+
# Valid options include `Kernel#format`, `Kernel#sprintf`, and `String#%`.
|
|
8
8
|
#
|
|
9
|
-
# The detection of String
|
|
9
|
+
# The detection of `String#%` cannot be implemented in a reliable
|
|
10
10
|
# manner for all cases, so only two scenarios are considered -
|
|
11
11
|
# if the first argument is a string literal and if the second
|
|
12
12
|
# argument is an array literal.
|
|
13
13
|
#
|
|
14
|
+
# Autocorrection will be applied when using argument is a literal or known built-in conversion
|
|
15
|
+
# methods such as `to_d`, `to_f`, `to_h`, `to_i`, `to_r`, `to_s`, and `to_sym` on variables,
|
|
16
|
+
# provided that their return value is not an array. For example, when using `to_s`,
|
|
17
|
+
# `'%s' % [1, 2, 3].to_s` can be autocorrected without any incompatibility:
|
|
18
|
+
#
|
|
19
|
+
# [source,ruby]
|
|
20
|
+
# ----
|
|
21
|
+
# '%s' % [1, 2, 3] #=> '1'
|
|
22
|
+
# format('%s', [1, 2, 3]) #=> '[1, 2, 3]'
|
|
23
|
+
# '%s' % [1, 2, 3].to_s #=> '[1, 2, 3]'
|
|
24
|
+
# ----
|
|
25
|
+
#
|
|
14
26
|
# @example EnforcedStyle: format (default)
|
|
15
27
|
# # bad
|
|
16
28
|
# puts sprintf('%10s', 'hoge')
|
|
@@ -42,6 +54,9 @@ module RuboCop
|
|
|
42
54
|
MSG = 'Favor `%<prefer>s` over `%<current>s`.'
|
|
43
55
|
RESTRICT_ON_SEND = %i[format sprintf %].freeze
|
|
44
56
|
|
|
57
|
+
# Known conversion methods whose return value is not an array.
|
|
58
|
+
AUTOCORRECTABLE_METHODS = %i[to_d to_f to_h to_i to_r to_s to_sym].freeze
|
|
59
|
+
|
|
45
60
|
# @!method formatter(node)
|
|
46
61
|
def_node_matcher :formatter, <<~PATTERN
|
|
47
62
|
{
|
|
@@ -53,7 +68,7 @@ module RuboCop
|
|
|
53
68
|
|
|
54
69
|
# @!method variable_argument?(node)
|
|
55
70
|
def_node_matcher :variable_argument?, <<~PATTERN
|
|
56
|
-
(send {str dstr} :%
|
|
71
|
+
(send {str dstr} :% #autocorrectable?)
|
|
57
72
|
PATTERN
|
|
58
73
|
|
|
59
74
|
def on_send(node)
|
|
@@ -70,6 +85,12 @@ module RuboCop
|
|
|
70
85
|
|
|
71
86
|
private
|
|
72
87
|
|
|
88
|
+
def autocorrectable?(node)
|
|
89
|
+
return true if node.lvar_type?
|
|
90
|
+
|
|
91
|
+
node.send_type? && !AUTOCORRECTABLE_METHODS.include?(node.method_name)
|
|
92
|
+
end
|
|
93
|
+
|
|
73
94
|
def message(detected_style)
|
|
74
95
|
format(MSG, prefer: method_name(style), current: method_name(detected_style))
|
|
75
96
|
end
|
|
@@ -142,7 +142,9 @@ module RuboCop
|
|
|
142
142
|
end
|
|
143
143
|
|
|
144
144
|
next_token = processed_source.tokens[token_number]
|
|
145
|
-
|
|
145
|
+
if next_token&.text&.valid_encoding? && Encoding::ENCODING_PATTERN.match?(next_token.text)
|
|
146
|
+
token = next_token
|
|
147
|
+
end
|
|
146
148
|
|
|
147
149
|
token
|
|
148
150
|
end
|
|
@@ -55,6 +55,25 @@ module RuboCop
|
|
|
55
55
|
# foo || raise('exception') if something
|
|
56
56
|
# ok
|
|
57
57
|
#
|
|
58
|
+
# # bad
|
|
59
|
+
# define_method(:test) do
|
|
60
|
+
# if something
|
|
61
|
+
# work
|
|
62
|
+
# end
|
|
63
|
+
# end
|
|
64
|
+
#
|
|
65
|
+
# # good
|
|
66
|
+
# define_method(:test) do
|
|
67
|
+
# return unless something
|
|
68
|
+
#
|
|
69
|
+
# work
|
|
70
|
+
# end
|
|
71
|
+
#
|
|
72
|
+
# # also good
|
|
73
|
+
# define_method(:test) do
|
|
74
|
+
# work if something
|
|
75
|
+
# end
|
|
76
|
+
#
|
|
58
77
|
# @example AllowConsecutiveConditionals: false (default)
|
|
59
78
|
# # bad
|
|
60
79
|
# def test
|
|
@@ -110,6 +129,13 @@ module RuboCop
|
|
|
110
129
|
end
|
|
111
130
|
alias on_defs on_def
|
|
112
131
|
|
|
132
|
+
def on_block(node)
|
|
133
|
+
return unless node.method?(:define_method) || node.method?(:define_singleton_method)
|
|
134
|
+
|
|
135
|
+
on_def(node)
|
|
136
|
+
end
|
|
137
|
+
alias on_numblock on_block
|
|
138
|
+
|
|
113
139
|
def on_if(node)
|
|
114
140
|
return if accepted_form?(node)
|
|
115
141
|
|
|
@@ -10,6 +10,16 @@ module RuboCop
|
|
|
10
10
|
# `Hash[*ary]` can be replaced with `ary.each_slice(2).to_h` but it will be complicated.
|
|
11
11
|
# So, `AllowSplatArgument` option is true by default to allow splat argument for simple code.
|
|
12
12
|
#
|
|
13
|
+
# @safety
|
|
14
|
+
# This cop's autocorrection is unsafe because `ArgumentError` occurs
|
|
15
|
+
# if the number of elements is odd:
|
|
16
|
+
#
|
|
17
|
+
# [source,ruby]
|
|
18
|
+
# ----
|
|
19
|
+
# Hash[[[1, 2], [3]]] #=> {1=>2, 3=>nil}
|
|
20
|
+
# [[1, 2], [5]].to_h #=> wrong array length at 1 (expected 2, was 1) (ArgumentError)
|
|
21
|
+
# ----
|
|
22
|
+
#
|
|
13
23
|
# @example
|
|
14
24
|
# # bad
|
|
15
25
|
# Hash[ary]
|