rubocop 1.57.1 → 1.65.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 +4 -5
- data/assets/output.css.erb +159 -0
- data/assets/output.html.erb +1 -160
- data/config/default.yml +136 -19
- data/lib/rubocop/cached_data.rb +11 -3
- data/lib/rubocop/cli/command/auto_generate_config.rb +22 -8
- data/lib/rubocop/cli/command/lsp.rb +2 -2
- data/lib/rubocop/cli/command/show_docs_url.rb +2 -2
- data/lib/rubocop/cli.rb +10 -1
- data/lib/rubocop/config.rb +36 -12
- data/lib/rubocop/config_finder.rb +12 -2
- data/lib/rubocop/config_loader.rb +1 -2
- data/lib/rubocop/config_loader_resolver.rb +9 -3
- data/lib/rubocop/config_obsoletion.rb +11 -8
- data/lib/rubocop/config_validator.rb +14 -7
- data/lib/rubocop/cop/autocorrect_logic.rb +6 -1
- data/lib/rubocop/cop/base.rb +63 -16
- data/lib/rubocop/cop/bundler/gem_comment.rb +2 -2
- data/lib/rubocop/cop/bundler/gem_version.rb +3 -5
- data/lib/rubocop/cop/cop.rb +20 -2
- data/lib/rubocop/cop/correctors/each_to_for_corrector.rb +4 -8
- data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +5 -13
- data/lib/rubocop/cop/documentation.rb +16 -6
- data/lib/rubocop/cop/exclude_limit.rb +1 -1
- data/lib/rubocop/cop/force.rb +12 -0
- data/lib/rubocop/cop/gemspec/add_runtime_dependency.rb +38 -0
- data/lib/rubocop/cop/gemspec/dependency_version.rb +3 -5
- data/lib/rubocop/cop/gemspec/deprecated_attribute_assignment.rb +2 -2
- data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +2 -2
- data/lib/rubocop/cop/gemspec/required_ruby_version.rb +5 -1
- data/lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb +3 -3
- data/lib/rubocop/cop/internal_affairs/example_description.rb +6 -5
- data/lib/rubocop/cop/internal_affairs/method_name_end_with.rb +8 -6
- 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 +123 -29
- data/lib/rubocop/cop/internal_affairs/redundant_expect_offense_arguments.rb +34 -0
- data/lib/rubocop/cop/internal_affairs.rb +2 -0
- data/lib/rubocop/cop/layout/argument_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/case_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/comment_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/empty_comment.rb +3 -1
- data/lib/rubocop/cop/layout/empty_line_after_magic_comment.rb +14 -7
- data/lib/rubocop/cop/layout/empty_line_after_multiline_condition.rb +1 -1
- data/lib/rubocop/cop/layout/end_alignment.rb +15 -3
- data/lib/rubocop/cop/layout/extra_spacing.rb +4 -10
- data/lib/rubocop/cop/layout/first_argument_indentation.rb +2 -2
- data/lib/rubocop/cop/layout/first_array_element_indentation.rb +24 -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 +2 -2
- data/lib/rubocop/cop/layout/indentation_width.rb +1 -1
- data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +1 -1
- data/lib/rubocop/cop/layout/line_length.rb +20 -20
- data/lib/rubocop/cop/layout/redundant_line_break.rb +16 -3
- 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_around_operators.rb +53 -20
- data/lib/rubocop/cop/layout/space_before_block_braces.rb +19 -10
- data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +1 -1
- data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +3 -4
- data/lib/rubocop/cop/legacy/corrector.rb +12 -2
- data/lib/rubocop/cop/lint/assignment_in_condition.rb +6 -6
- 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 +29 -3
- data/lib/rubocop/cop/lint/deprecated_class_methods.rb +1 -1
- data/lib/rubocop/cop/lint/duplicate_case_condition.rb +1 -1
- data/lib/rubocop/cop/lint/duplicate_methods.rb +1 -1
- data/lib/rubocop/cop/lint/empty_conditional_body.rb +2 -2
- data/lib/rubocop/cop/lint/empty_when.rb +1 -1
- data/lib/rubocop/cop/lint/erb_new_arguments.rb +24 -17
- 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/implicit_string_concatenation.rb +14 -7
- data/lib/rubocop/cop/lint/it_without_arguments_in_block.rb +56 -0
- data/lib/rubocop/cop/lint/literal_as_condition.rb +1 -1
- data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +85 -0
- data/lib/rubocop/cop/lint/mixed_case_range.rb +9 -4
- data/lib/rubocop/cop/lint/nested_method_definition.rb +1 -1
- data/lib/rubocop/cop/lint/next_without_accumulator.rb +6 -21
- 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_safe_navigation.rb +54 -6
- data/lib/rubocop/cop/lint/redundant_with_index.rb +6 -2
- data/lib/rubocop/cop/lint/redundant_with_object.rb +2 -2
- data/lib/rubocop/cop/lint/rescue_type.rb +1 -3
- data/lib/rubocop/cop/lint/safe_navigation_chain.rb +3 -4
- data/lib/rubocop/cop/lint/script_permission.rb +3 -3
- 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/symbol_conversion.rb +7 -2
- data/lib/rubocop/cop/lint/syntax.rb +6 -3
- data/lib/rubocop/cop/lint/to_enum_arguments.rb +1 -3
- data/lib/rubocop/cop/lint/trailing_comma_in_attribute_declaration.rb +1 -1
- data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +3 -2
- data/lib/rubocop/cop/lint/unreachable_code.rb +4 -2
- data/lib/rubocop/cop/lint/unreachable_loop.rb +8 -2
- data/lib/rubocop/cop/lint/useless_access_modifier.rb +2 -2
- data/lib/rubocop/cop/lint/useless_times.rb +2 -2
- data/lib/rubocop/cop/lint/void.rb +53 -12
- data/lib/rubocop/cop/metrics/abc_size.rb +3 -3
- data/lib/rubocop/cop/metrics/block_nesting.rb +19 -7
- data/lib/rubocop/cop/metrics/class_length.rb +6 -1
- data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +5 -5
- data/lib/rubocop/cop/mixin/alignment.rb +5 -1
- data/lib/rubocop/cop/mixin/allowed_methods.rb +7 -1
- data/lib/rubocop/cop/mixin/allowed_pattern.rb +15 -3
- data/lib/rubocop/cop/mixin/check_line_breakable.rb +1 -1
- data/lib/rubocop/cop/mixin/code_length.rb +12 -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/configurable_max.rb +5 -1
- data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +23 -13
- data/lib/rubocop/cop/mixin/method_complexity.rb +15 -6
- data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +1 -1
- data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +1 -1
- data/lib/rubocop/cop/mixin/rescue_node.rb +4 -0
- data/lib/rubocop/cop/mixin/safe_assignment.rb +1 -1
- data/lib/rubocop/cop/mixin/space_before_punctuation.rb +1 -1
- data/lib/rubocop/cop/naming/block_forwarding.rb +34 -7
- data/lib/rubocop/cop/naming/constant_name.rb +1 -2
- data/lib/rubocop/cop/naming/file_name.rb +2 -2
- data/lib/rubocop/cop/naming/inclusive_language.rb +1 -2
- data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +1 -1
- data/lib/rubocop/cop/naming/predicate_name.rb +2 -2
- data/lib/rubocop/cop/registry.rb +1 -1
- data/lib/rubocop/cop/security/compound_hash.rb +2 -2
- data/lib/rubocop/cop/security/open.rb +2 -2
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +52 -2
- data/lib/rubocop/cop/style/accessor_grouping.rb +1 -1
- data/lib/rubocop/cop/style/alias.rb +1 -0
- data/lib/rubocop/cop/style/arguments_forwarding.rb +155 -21
- data/lib/rubocop/cop/style/array_first_last.rb +64 -0
- 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/case_like_if.rb +5 -5
- data/lib/rubocop/cop/style/class_check.rb +1 -0
- data/lib/rubocop/cop/style/class_vars.rb +3 -3
- data/lib/rubocop/cop/style/collection_compact.rb +21 -11
- data/lib/rubocop/cop/style/combinable_loops.rb +13 -7
- data/lib/rubocop/cop/style/commented_keyword.rb +5 -2
- data/lib/rubocop/cop/style/concat_array_literals.rb +1 -0
- data/lib/rubocop/cop/style/conditional_assignment.rb +7 -8
- data/lib/rubocop/cop/style/copyright.rb +31 -21
- data/lib/rubocop/cop/style/date_time.rb +5 -4
- data/lib/rubocop/cop/style/documentation.rb +24 -24
- data/lib/rubocop/cop/style/documentation_method.rb +20 -0
- 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_literal.rb +1 -1
- data/lib/rubocop/cop/style/eval_with_location.rb +6 -15
- data/lib/rubocop/cop/style/exact_regexp_match.rb +4 -2
- data/lib/rubocop/cop/style/explicit_block_argument.rb +2 -2
- data/lib/rubocop/cop/style/for.rb +2 -0
- data/lib/rubocop/cop/style/format_string.rb +9 -9
- data/lib/rubocop/cop/style/hash_each_methods.rb +105 -11
- data/lib/rubocop/cop/style/hash_except.rb +10 -6
- data/lib/rubocop/cop/style/hash_syntax.rb +24 -2
- data/lib/rubocop/cop/style/identical_conditional_branches.rb +12 -1
- data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +5 -3
- data/lib/rubocop/cop/style/inverse_methods.rb +14 -13
- data/lib/rubocop/cop/style/invertible_unless_condition.rb +44 -2
- data/lib/rubocop/cop/style/map_compact_with_conditional_block.rb +82 -50
- data/lib/rubocop/cop/style/map_into_array.rb +175 -0
- data/lib/rubocop/cop/style/map_to_hash.rb +18 -8
- data/lib/rubocop/cop/style/map_to_set.rb +1 -1
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +19 -5
- 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/multiline_method_signature.rb +10 -1
- data/lib/rubocop/cop/style/multiline_ternary_operator.rb +5 -3
- data/lib/rubocop/cop/style/next.rb +1 -1
- data/lib/rubocop/cop/style/nil_comparison.rb +2 -0
- data/lib/rubocop/cop/style/numeric_literal_prefix.rb +1 -1
- data/lib/rubocop/cop/style/numeric_predicate.rb +10 -2
- data/lib/rubocop/cop/style/object_then.rb +5 -3
- data/lib/rubocop/cop/style/one_line_conditional.rb +1 -1
- data/lib/rubocop/cop/style/operator_method_call.rb +2 -2
- data/lib/rubocop/cop/style/parallel_assignment.rb +3 -5
- data/lib/rubocop/cop/style/parentheses_around_condition.rb +8 -0
- data/lib/rubocop/cop/style/quoted_symbols.rb +1 -1
- data/lib/rubocop/cop/style/raise_args.rb +4 -1
- data/lib/rubocop/cop/style/redundant_argument.rb +27 -3
- data/lib/rubocop/cop/style/redundant_assignment.rb +10 -2
- data/lib/rubocop/cop/style/redundant_begin.rb +1 -1
- data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +5 -4
- data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +17 -10
- data/lib/rubocop/cop/style/redundant_each.rb +7 -4
- data/lib/rubocop/cop/style/redundant_fetch_block.rb +3 -3
- data/lib/rubocop/cop/style/redundant_file_extension_in_require.rb +1 -1
- data/lib/rubocop/cop/style/redundant_filter_chain.rb +5 -4
- data/lib/rubocop/cop/style/redundant_line_continuation.rb +19 -2
- data/lib/rubocop/cop/style/redundant_parentheses.rb +50 -19
- data/lib/rubocop/cop/style/redundant_percent_q.rb +1 -1
- data/lib/rubocop/cop/style/redundant_return.rb +7 -1
- data/lib/rubocop/cop/style/redundant_self.rb +17 -2
- 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/require_order.rb +1 -1
- data/lib/rubocop/cop/style/sample.rb +3 -4
- 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 -0
- data/lib/rubocop/cop/style/send.rb +4 -4
- data/lib/rubocop/cop/style/send_with_literal_method_name.rb +104 -0
- data/lib/rubocop/cop/style/single_argument_dig.rb +7 -3
- data/lib/rubocop/cop/style/single_line_do_end_block.rb +3 -1
- data/lib/rubocop/cop/style/slicing_with_range.rb +76 -10
- data/lib/rubocop/cop/style/special_global_vars.rb +1 -2
- data/lib/rubocop/cop/style/string_chars.rb +1 -0
- data/lib/rubocop/cop/style/strip.rb +7 -4
- data/lib/rubocop/cop/style/super_arguments.rb +174 -0
- data/lib/rubocop/cop/style/super_with_args_parentheses.rb +35 -0
- data/lib/rubocop/cop/style/symbol_proc.rb +75 -5
- data/lib/rubocop/cop/style/top_level_method_definition.rb +1 -1
- data/lib/rubocop/cop/style/unpack_first.rb +11 -14
- data/lib/rubocop/cop/style/zero_length_predicate.rb +28 -24
- data/lib/rubocop/cop/team.rb +13 -0
- data/lib/rubocop/cop/util.rb +7 -1
- data/lib/rubocop/cop/utils/regexp_ranges.rb +1 -1
- data/lib/rubocop/cops_documentation_generator.rb +16 -4
- data/lib/rubocop/directive_comment.rb +10 -8
- data/lib/rubocop/ext/regexp_node.rb +9 -4
- data/lib/rubocop/ext/regexp_parser.rb +4 -21
- data/lib/rubocop/formatter/clang_style_formatter.rb +3 -7
- data/lib/rubocop/formatter/disabled_config_formatter.rb +23 -8
- data/lib/rubocop/formatter/formatter_set.rb +7 -1
- data/lib/rubocop/formatter/html_formatter.rb +37 -14
- data/lib/rubocop/formatter/json_formatter.rb +0 -1
- data/lib/rubocop/formatter/offense_count_formatter.rb +12 -2
- data/lib/rubocop/formatter/tap_formatter.rb +3 -7
- data/lib/rubocop/formatter.rb +1 -1
- data/lib/rubocop/lockfile.rb +56 -7
- data/lib/rubocop/lsp/logger.rb +1 -1
- data/lib/rubocop/lsp/routes.rb +12 -15
- data/lib/rubocop/lsp/runtime.rb +1 -1
- data/lib/rubocop/lsp/server.rb +7 -2
- data/lib/rubocop/lsp/severity.rb +1 -1
- data/lib/rubocop/lsp.rb +36 -0
- data/lib/rubocop/magic_comment.rb +1 -1
- data/lib/rubocop/options.rb +14 -11
- data/lib/rubocop/path_util.rb +6 -2
- data/lib/rubocop/rake_task.rb +1 -1
- data/lib/rubocop/result_cache.rb +0 -1
- data/lib/rubocop/rspec/cop_helper.rb +8 -2
- data/lib/rubocop/rspec/expect_offense.rb +16 -8
- data/lib/rubocop/rspec/shared_contexts.rb +73 -16
- data/lib/rubocop/rspec/support.rb +3 -0
- data/lib/rubocop/runner.rb +14 -3
- data/lib/rubocop/server/cache.rb +11 -2
- data/lib/rubocop/server/client_command/exec.rb +2 -3
- data/lib/rubocop/server/client_command/start.rb +1 -1
- data/lib/rubocop/server/core.rb +4 -0
- data/lib/rubocop/server/server_command/exec.rb +0 -1
- data/lib/rubocop/target_finder.rb +84 -78
- data/lib/rubocop/target_ruby.rb +82 -80
- data/lib/rubocop/version.rb +19 -4
- data/lib/rubocop.rb +8 -0
- metadata +27 -29
- /data/lib/rubocop/formatter/{git_hub_actions_formatter.rb → github_actions_formatter.rb} +0 -0
|
@@ -8,11 +8,28 @@ module RuboCop
|
|
|
8
8
|
# This cop identifies places where `do_something(*args, &block)`
|
|
9
9
|
# can be replaced by `do_something(...)`.
|
|
10
10
|
#
|
|
11
|
+
# In Ruby 3.1, anonymous block forwarding has been added.
|
|
12
|
+
#
|
|
13
|
+
# This cop identifies places where `do_something(&block)` can be replaced
|
|
14
|
+
# by `do_something(&)`; if desired, this functionality can be disabled
|
|
15
|
+
# by setting `UseAnonymousForwarding: false`.
|
|
16
|
+
#
|
|
11
17
|
# In Ruby 3.2, anonymous args/kwargs forwarding has been added.
|
|
12
18
|
#
|
|
13
19
|
# This cop also identifies places where `use_args(*args)`/`use_kwargs(**kwargs)` can be
|
|
14
20
|
# replaced by `use_args(*)`/`use_kwargs(**)`; if desired, this functionality can be disabled
|
|
15
|
-
# by setting UseAnonymousForwarding: false
|
|
21
|
+
# by setting `UseAnonymousForwarding: false`.
|
|
22
|
+
#
|
|
23
|
+
# And this cop has `RedundantRestArgumentNames`, `RedundantKeywordRestArgumentNames`,
|
|
24
|
+
# and `RedundantBlockArgumentNames` options. This configuration is a list of redundant names
|
|
25
|
+
# that are sufficient for anonymizing meaningless naming.
|
|
26
|
+
#
|
|
27
|
+
# Meaningless names that are commonly used can be anonymized by default:
|
|
28
|
+
# e.g., `*args`, `**options`, `&block`, and so on.
|
|
29
|
+
#
|
|
30
|
+
# Names not on this list are likely to be meaningful and are allowed by default.
|
|
31
|
+
#
|
|
32
|
+
# This cop handles not only method forwarding but also forwarding to `super`.
|
|
16
33
|
#
|
|
17
34
|
# @example
|
|
18
35
|
# # bad
|
|
@@ -32,22 +49,25 @@ module RuboCop
|
|
|
32
49
|
#
|
|
33
50
|
# @example UseAnonymousForwarding: true (default, only relevant for Ruby >= 3.2)
|
|
34
51
|
# # bad
|
|
35
|
-
# def foo(*args, **kwargs)
|
|
52
|
+
# def foo(*args, **kwargs, &block)
|
|
36
53
|
# args_only(*args)
|
|
37
54
|
# kwargs_only(**kwargs)
|
|
55
|
+
# block_only(&block)
|
|
38
56
|
# end
|
|
39
57
|
#
|
|
40
58
|
# # good
|
|
41
|
-
# def foo(*,
|
|
59
|
+
# def foo(*, **, &)
|
|
42
60
|
# args_only(*)
|
|
43
61
|
# kwargs_only(**)
|
|
62
|
+
# block_only(&)
|
|
44
63
|
# end
|
|
45
64
|
#
|
|
46
65
|
# @example UseAnonymousForwarding: false (only relevant for Ruby >= 3.2)
|
|
47
66
|
# # good
|
|
48
|
-
# def foo(*args, **kwargs)
|
|
67
|
+
# def foo(*args, **kwargs, &block)
|
|
49
68
|
# args_only(*args)
|
|
50
69
|
# kwargs_only(**kwargs)
|
|
70
|
+
# block_only(&block)
|
|
51
71
|
# end
|
|
52
72
|
#
|
|
53
73
|
# @example AllowOnlyRestArgument: true (default, only relevant for Ruby < 3.2)
|
|
@@ -72,6 +92,38 @@ module RuboCop
|
|
|
72
92
|
# bar(**kwargs)
|
|
73
93
|
# end
|
|
74
94
|
#
|
|
95
|
+
# @example RedundantRestArgumentNames: ['args', 'arguments'] (default)
|
|
96
|
+
# # bad
|
|
97
|
+
# def foo(*args)
|
|
98
|
+
# bar(*args)
|
|
99
|
+
# end
|
|
100
|
+
#
|
|
101
|
+
# # good
|
|
102
|
+
# def foo(*)
|
|
103
|
+
# bar(*)
|
|
104
|
+
# end
|
|
105
|
+
#
|
|
106
|
+
# @example RedundantKeywordRestArgumentNames: ['kwargs', 'options', 'opts'] (default)
|
|
107
|
+
# # bad
|
|
108
|
+
# def foo(**kwargs)
|
|
109
|
+
# bar(**kwargs)
|
|
110
|
+
# end
|
|
111
|
+
#
|
|
112
|
+
# # good
|
|
113
|
+
# def foo(**)
|
|
114
|
+
# bar(**)
|
|
115
|
+
# end
|
|
116
|
+
#
|
|
117
|
+
# @example RedundantBlockArgumentNames: ['blk', 'block', 'proc'] (default)
|
|
118
|
+
# # bad - But it is good with `EnforcedStyle: explicit` set for `Naming/BlockForwarding`.
|
|
119
|
+
# def foo(&block)
|
|
120
|
+
# bar(&block)
|
|
121
|
+
# end
|
|
122
|
+
#
|
|
123
|
+
# # good
|
|
124
|
+
# def foo(&)
|
|
125
|
+
# bar(&)
|
|
126
|
+
# end
|
|
75
127
|
class ArgumentsForwarding < Base
|
|
76
128
|
include RangeHelp
|
|
77
129
|
extend AutoCorrector
|
|
@@ -85,17 +137,21 @@ module RuboCop
|
|
|
85
137
|
FORWARDING_MSG = 'Use shorthand syntax `...` for arguments forwarding.'
|
|
86
138
|
ARGS_MSG = 'Use anonymous positional arguments forwarding (`*`).'
|
|
87
139
|
KWARGS_MSG = 'Use anonymous keyword arguments forwarding (`**`).'
|
|
140
|
+
BLOCK_MSG = 'Use anonymous block arguments forwarding (`&`).'
|
|
141
|
+
|
|
142
|
+
def self.autocorrect_incompatible_with
|
|
143
|
+
[Naming::BlockForwarding]
|
|
144
|
+
end
|
|
88
145
|
|
|
89
146
|
def on_def(node)
|
|
90
147
|
return unless node.body
|
|
91
148
|
|
|
92
|
-
|
|
149
|
+
restarg, kwrestarg, blockarg = extract_forwardable_args(node.arguments)
|
|
150
|
+
forwardable_args = redundant_forwardable_named_args(restarg, kwrestarg, blockarg)
|
|
151
|
+
send_nodes = node.each_descendant(:send, :csend, :super, :yield).to_a
|
|
93
152
|
|
|
94
153
|
send_classifications = classify_send_nodes(
|
|
95
|
-
node,
|
|
96
|
-
node.each_descendant(:send).to_a,
|
|
97
|
-
non_splat_or_block_pass_lvar_references(node.body),
|
|
98
|
-
forwardable_args
|
|
154
|
+
node, send_nodes, non_splat_or_block_pass_lvar_references(node.body), forwardable_args
|
|
99
155
|
)
|
|
100
156
|
|
|
101
157
|
return if send_classifications.empty?
|
|
@@ -115,36 +171,71 @@ module RuboCop
|
|
|
115
171
|
[args.find(&:restarg_type?), args.find(&:kwrestarg_type?), args.find(&:blockarg_type?)]
|
|
116
172
|
end
|
|
117
173
|
|
|
174
|
+
def redundant_forwardable_named_args(restarg, kwrestarg, blockarg)
|
|
175
|
+
restarg_node = redundant_named_arg(restarg, 'RedundantRestArgumentNames', '*')
|
|
176
|
+
kwrestarg_node = redundant_named_arg(kwrestarg, 'RedundantKeywordRestArgumentNames', '**')
|
|
177
|
+
blockarg_node = redundant_named_arg(blockarg, 'RedundantBlockArgumentNames', '&')
|
|
178
|
+
|
|
179
|
+
[restarg_node, kwrestarg_node, blockarg_node]
|
|
180
|
+
end
|
|
181
|
+
|
|
118
182
|
def only_forwards_all?(send_classifications)
|
|
119
183
|
send_classifications.all? { |_, c, _, _| c == :all }
|
|
120
184
|
end
|
|
121
185
|
|
|
186
|
+
# rubocop:disable Metrics/MethodLength
|
|
122
187
|
def add_forward_all_offenses(node, send_classifications, forwardable_args)
|
|
123
|
-
|
|
124
|
-
|
|
188
|
+
_rest_arg, _kwrest_arg, block_arg = *forwardable_args
|
|
189
|
+
registered_block_arg_offense = false
|
|
190
|
+
|
|
191
|
+
send_classifications.each do |send_node, _c, forward_rest, forward_kwrest, forward_block_arg| # rubocop:disable Layout/LineLength
|
|
192
|
+
if !forward_rest && !forward_kwrest
|
|
193
|
+
# Prevents `anonymous block parameter is also used within block (SyntaxError)` occurs
|
|
194
|
+
# in Ruby 3.3.0.
|
|
195
|
+
if outside_block?(forward_block_arg)
|
|
196
|
+
register_forward_block_arg_offense(!forward_rest, node.arguments, block_arg)
|
|
197
|
+
register_forward_block_arg_offense(!forward_rest, send_node, forward_block_arg)
|
|
198
|
+
end
|
|
199
|
+
registered_block_arg_offense = true
|
|
200
|
+
break
|
|
201
|
+
else
|
|
202
|
+
register_forward_all_offense(send_node, send_node, forward_rest)
|
|
203
|
+
end
|
|
125
204
|
end
|
|
126
205
|
|
|
206
|
+
return if registered_block_arg_offense
|
|
207
|
+
|
|
127
208
|
rest_arg, _kwrest_arg, _block_arg = *forwardable_args
|
|
128
209
|
register_forward_all_offense(node, node.arguments, rest_arg)
|
|
129
210
|
end
|
|
211
|
+
# rubocop:enable Metrics/MethodLength
|
|
130
212
|
|
|
213
|
+
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
|
131
214
|
def add_post_ruby_32_offenses(def_node, send_classifications, forwardable_args)
|
|
132
215
|
return unless use_anonymous_forwarding?
|
|
133
216
|
|
|
134
|
-
rest_arg, kwrest_arg,
|
|
217
|
+
rest_arg, kwrest_arg, block_arg = *forwardable_args
|
|
135
218
|
|
|
136
|
-
send_classifications.each do |send_node, _c, forward_rest, forward_kwrest|
|
|
137
|
-
if forward_rest
|
|
219
|
+
send_classifications.each do |send_node, _c, forward_rest, forward_kwrest, forward_block_arg| # rubocop:disable Layout/LineLength
|
|
220
|
+
if outside_block?(forward_rest)
|
|
138
221
|
register_forward_args_offense(def_node.arguments, rest_arg)
|
|
139
222
|
register_forward_args_offense(send_node, forward_rest)
|
|
140
223
|
end
|
|
141
224
|
|
|
142
|
-
if forward_kwrest
|
|
225
|
+
if outside_block?(forward_kwrest)
|
|
143
226
|
register_forward_kwargs_offense(!forward_rest, def_node.arguments, kwrest_arg)
|
|
144
227
|
register_forward_kwargs_offense(!forward_rest, send_node, forward_kwrest)
|
|
145
228
|
end
|
|
229
|
+
|
|
230
|
+
# Prevents `anonymous block parameter is also used within block (SyntaxError)` occurs
|
|
231
|
+
# in Ruby 3.3.0.
|
|
232
|
+
if outside_block?(forward_block_arg)
|
|
233
|
+
register_forward_block_arg_offense(!forward_rest, def_node.arguments, block_arg)
|
|
234
|
+
register_forward_block_arg_offense(!forward_rest, send_node, forward_block_arg)
|
|
235
|
+
end
|
|
146
236
|
end
|
|
147
237
|
end
|
|
238
|
+
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength
|
|
148
239
|
|
|
149
240
|
def non_splat_or_block_pass_lvar_references(body)
|
|
150
241
|
body.each_descendant(:lvar, :lvasgn).filter_map do |lvar|
|
|
@@ -173,10 +264,7 @@ module RuboCop
|
|
|
173
264
|
|
|
174
265
|
def classification_and_forwards(def_node, send_node, referenced_lvars, forwardable_args)
|
|
175
266
|
classifier = SendNodeClassifier.new(
|
|
176
|
-
def_node,
|
|
177
|
-
send_node,
|
|
178
|
-
referenced_lvars,
|
|
179
|
-
forwardable_args,
|
|
267
|
+
def_node, send_node, referenced_lvars, forwardable_args,
|
|
180
268
|
target_ruby_version: target_ruby_version,
|
|
181
269
|
allow_only_rest_arguments: allow_only_rest_arguments?
|
|
182
270
|
)
|
|
@@ -185,7 +273,28 @@ module RuboCop
|
|
|
185
273
|
|
|
186
274
|
return unless classification
|
|
187
275
|
|
|
188
|
-
[
|
|
276
|
+
[
|
|
277
|
+
classification,
|
|
278
|
+
classifier.forwarded_rest_arg,
|
|
279
|
+
classifier.forwarded_kwrest_arg,
|
|
280
|
+
classifier.forwarded_block_arg
|
|
281
|
+
]
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
def redundant_named_arg(arg, config_name, keyword)
|
|
285
|
+
return nil unless arg
|
|
286
|
+
|
|
287
|
+
redundant_arg_names = cop_config.fetch(config_name, []).map do |redundant_arg_name|
|
|
288
|
+
"#{keyword}#{redundant_arg_name}"
|
|
289
|
+
end << keyword
|
|
290
|
+
|
|
291
|
+
redundant_arg_names.include?(arg.source) ? arg : nil
|
|
292
|
+
end
|
|
293
|
+
|
|
294
|
+
def outside_block?(node)
|
|
295
|
+
return false unless node
|
|
296
|
+
|
|
297
|
+
node.each_ancestor(:block, :numblock).none?
|
|
189
298
|
end
|
|
190
299
|
|
|
191
300
|
def register_forward_args_offense(def_arguments_or_send, rest_arg_or_splat)
|
|
@@ -204,6 +313,17 @@ module RuboCop
|
|
|
204
313
|
end
|
|
205
314
|
end
|
|
206
315
|
|
|
316
|
+
def register_forward_block_arg_offense(add_parens, def_arguments_or_send, block_arg)
|
|
317
|
+
return if target_ruby_version <= 3.0 ||
|
|
318
|
+
block_arg.nil? || block_arg.source == '&' || explicit_block_name?
|
|
319
|
+
|
|
320
|
+
add_offense(block_arg, message: BLOCK_MSG) do |corrector|
|
|
321
|
+
add_parens_if_missing(def_arguments_or_send, corrector) if add_parens
|
|
322
|
+
|
|
323
|
+
corrector.replace(block_arg, '&')
|
|
324
|
+
end
|
|
325
|
+
end
|
|
326
|
+
|
|
207
327
|
def register_forward_all_offense(def_or_send, send_or_arguments, rest_or_splat)
|
|
208
328
|
arg_range = arguments_range(def_or_send, rest_or_splat)
|
|
209
329
|
|
|
@@ -278,7 +398,7 @@ module RuboCop
|
|
|
278
398
|
end
|
|
279
399
|
|
|
280
400
|
def classification
|
|
281
|
-
return nil unless forwarded_rest_arg || forwarded_kwrest_arg
|
|
401
|
+
return nil unless forwarded_rest_arg || forwarded_kwrest_arg || forwarded_block_arg
|
|
282
402
|
|
|
283
403
|
if can_forward_all?
|
|
284
404
|
:all
|
|
@@ -362,9 +482,23 @@ module RuboCop
|
|
|
362
482
|
def no_additional_args?
|
|
363
483
|
forwardable_count = [@rest_arg, @kwrest_arg, @block_arg].compact.size
|
|
364
484
|
|
|
485
|
+
return false if missing_rest_arg_or_kwrest_arg?
|
|
486
|
+
|
|
365
487
|
@def_node.arguments.size == forwardable_count &&
|
|
366
488
|
@send_node.arguments.size == forwardable_count
|
|
367
489
|
end
|
|
490
|
+
|
|
491
|
+
def missing_rest_arg_or_kwrest_arg?
|
|
492
|
+
(@rest_arg_name && !forwarded_rest_arg) ||
|
|
493
|
+
(@kwrest_arg_name && !forwarded_kwrest_arg)
|
|
494
|
+
end
|
|
495
|
+
end
|
|
496
|
+
|
|
497
|
+
def explicit_block_name?
|
|
498
|
+
block_forwarding_config = config.for_cop('Naming/BlockForwarding')
|
|
499
|
+
return false unless block_forwarding_config['Enabled']
|
|
500
|
+
|
|
501
|
+
block_forwarding_config['EnforcedStyle'] == 'explicit'
|
|
368
502
|
end
|
|
369
503
|
end
|
|
370
504
|
end
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module Cop
|
|
5
|
+
module Style
|
|
6
|
+
# Identifies usages of `arr[0]` and `arr[-1]` and suggests to change
|
|
7
|
+
# them to use `arr.first` and `arr.last` instead.
|
|
8
|
+
#
|
|
9
|
+
# The cop is disabled by default due to safety concerns.
|
|
10
|
+
#
|
|
11
|
+
# @safety
|
|
12
|
+
# This cop is unsafe because `[0]` or `[-1]` can be called on a Hash,
|
|
13
|
+
# which returns a value for `0` or `-1` key, but changing these to use
|
|
14
|
+
# `.first` or `.last` will return first/last tuple instead. Also, String
|
|
15
|
+
# does not implement `first`/`last` methods.
|
|
16
|
+
#
|
|
17
|
+
# @example
|
|
18
|
+
# # bad
|
|
19
|
+
# arr[0]
|
|
20
|
+
# arr[-1]
|
|
21
|
+
#
|
|
22
|
+
# # good
|
|
23
|
+
# arr.first
|
|
24
|
+
# arr.last
|
|
25
|
+
# arr[0] = 2
|
|
26
|
+
# arr[0][-2]
|
|
27
|
+
#
|
|
28
|
+
class ArrayFirstLast < Base
|
|
29
|
+
extend AutoCorrector
|
|
30
|
+
|
|
31
|
+
MSG = 'Use `%<preferred>s`.'
|
|
32
|
+
RESTRICT_ON_SEND = %i[[]].freeze
|
|
33
|
+
|
|
34
|
+
# rubocop:disable Metrics/AbcSize
|
|
35
|
+
def on_send(node)
|
|
36
|
+
return unless node.arguments.size == 1 && node.first_argument.int_type?
|
|
37
|
+
|
|
38
|
+
value = node.first_argument.value
|
|
39
|
+
return unless [0, -1].include?(value)
|
|
40
|
+
|
|
41
|
+
node = innermost_braces_node(node)
|
|
42
|
+
return if node.parent && brace_method?(node.parent)
|
|
43
|
+
|
|
44
|
+
preferred = (value.zero? ? 'first' : 'last')
|
|
45
|
+
add_offense(node.loc.selector, message: format(MSG, preferred: preferred)) do |corrector|
|
|
46
|
+
corrector.replace(node.loc.selector, ".#{preferred}")
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
# rubocop:enable Metrics/AbcSize
|
|
50
|
+
|
|
51
|
+
private
|
|
52
|
+
|
|
53
|
+
def innermost_braces_node(node)
|
|
54
|
+
node = node.receiver while node.receiver.send_type? && node.receiver.method?(:[])
|
|
55
|
+
node
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def brace_method?(node)
|
|
59
|
+
node.send_type? && (node.method?(:[]) || node.method?(:[]=))
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
@@ -16,31 +16,38 @@ module RuboCop
|
|
|
16
16
|
# File.open('file') do |f|
|
|
17
17
|
# # ...
|
|
18
18
|
# end
|
|
19
|
+
#
|
|
20
|
+
# # bad
|
|
21
|
+
# f = Tempfile.open('temp')
|
|
22
|
+
#
|
|
23
|
+
# # good
|
|
24
|
+
# Tempfile.open('temp') do |f|
|
|
25
|
+
# # ...
|
|
26
|
+
# end
|
|
19
27
|
class AutoResourceCleanup < Base
|
|
20
|
-
MSG = 'Use the block version of `%<
|
|
21
|
-
|
|
22
|
-
TARGET_METHODS = { File: :open }.freeze
|
|
28
|
+
MSG = 'Use the block version of `%<current>s`.'
|
|
29
|
+
RESTRICT_ON_SEND = %i[open].freeze
|
|
23
30
|
|
|
24
|
-
|
|
31
|
+
# @!method file_open_method?(node)
|
|
32
|
+
def_node_matcher :file_open_method?, <<~PATTERN
|
|
33
|
+
(send (const {nil? cbase} {:File :Tempfile}) :open ...)
|
|
34
|
+
PATTERN
|
|
25
35
|
|
|
26
36
|
def on_send(node)
|
|
27
|
-
|
|
28
|
-
next if node.method_name != target_method
|
|
37
|
+
return if !file_open_method?(node) || cleanup?(node)
|
|
29
38
|
|
|
30
|
-
|
|
31
|
-
next if node.receiver != target_receiver
|
|
39
|
+
current = node.receiver.source_range.begin.join(node.selector.end).source
|
|
32
40
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
add_offense(node, message: format(MSG, class: target_class, method: target_method))
|
|
36
|
-
end
|
|
41
|
+
add_offense(node, message: format(MSG, current: current))
|
|
37
42
|
end
|
|
38
43
|
|
|
39
44
|
private
|
|
40
45
|
|
|
41
46
|
def cleanup?(node)
|
|
42
|
-
|
|
43
|
-
|
|
47
|
+
return true if node.block_argument?
|
|
48
|
+
return false unless (parent = node.parent)
|
|
49
|
+
|
|
50
|
+
parent.block_type? || !parent.lvasgn_type?
|
|
44
51
|
end
|
|
45
52
|
end
|
|
46
53
|
end
|
|
@@ -33,7 +33,7 @@ module RuboCop
|
|
|
33
33
|
def on_class(class_node)
|
|
34
34
|
@macros_to_rewrite[class_node] = Set.new
|
|
35
35
|
|
|
36
|
-
find_macros(class_node.body).
|
|
36
|
+
find_macros(class_node.body).each_value do |macros|
|
|
37
37
|
bisected = find_bisection(macros)
|
|
38
38
|
next unless bisected.any?
|
|
39
39
|
|
|
@@ -74,7 +74,7 @@ module RuboCop
|
|
|
74
74
|
def find_macros(class_def)
|
|
75
75
|
# Find all the macros (`attr_reader`, `attr_writer`, etc.) in the class body
|
|
76
76
|
# and turn them into `Macro` objects so that they can be processed.
|
|
77
|
-
return
|
|
77
|
+
return {} if !class_def || class_def.def_type?
|
|
78
78
|
|
|
79
79
|
send_nodes =
|
|
80
80
|
if class_def.send_type?
|
|
@@ -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?
|
|
@@ -230,7 +230,7 @@ module RuboCop
|
|
|
230
230
|
|
|
231
231
|
def branch_conditions(node)
|
|
232
232
|
conditions = []
|
|
233
|
-
while node&.if_type?
|
|
233
|
+
while node&.if_type? && !node.ternary?
|
|
234
234
|
conditions << node.condition
|
|
235
235
|
node = node.else_branch
|
|
236
236
|
end
|
|
@@ -54,9 +54,9 @@ module RuboCop
|
|
|
54
54
|
end
|
|
55
55
|
|
|
56
56
|
def on_send(node)
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
)
|
|
57
|
+
return unless (first_argument = node.first_argument)
|
|
58
|
+
|
|
59
|
+
add_offense(first_argument, message: format(MSG, class_var: first_argument.source))
|
|
60
60
|
end
|
|
61
61
|
end
|
|
62
62
|
end
|
|
@@ -19,17 +19,19 @@ module RuboCop
|
|
|
19
19
|
# @example
|
|
20
20
|
# # bad
|
|
21
21
|
# array.reject(&:nil?)
|
|
22
|
-
# array.delete_if(&:nil?)
|
|
23
22
|
# array.reject { |e| e.nil? }
|
|
24
|
-
# array.delete_if { |e| e.nil? }
|
|
25
23
|
# array.select { |e| !e.nil? }
|
|
24
|
+
# array.grep_v(nil)
|
|
25
|
+
# array.grep_v(NilClass)
|
|
26
26
|
#
|
|
27
27
|
# # good
|
|
28
28
|
# array.compact
|
|
29
29
|
#
|
|
30
30
|
# # bad
|
|
31
31
|
# hash.reject!(&:nil?)
|
|
32
|
+
# array.delete_if(&:nil?)
|
|
32
33
|
# hash.reject! { |k, v| v.nil? }
|
|
34
|
+
# array.delete_if { |e| e.nil? }
|
|
33
35
|
# hash.select! { |k, v| !v.nil? }
|
|
34
36
|
#
|
|
35
37
|
# # good
|
|
@@ -46,14 +48,14 @@ module RuboCop
|
|
|
46
48
|
extend TargetRubyVersion
|
|
47
49
|
|
|
48
50
|
MSG = 'Use `%<good>s` instead of `%<bad>s`.'
|
|
49
|
-
RESTRICT_ON_SEND = %i[reject delete_if reject! select select!].freeze
|
|
51
|
+
RESTRICT_ON_SEND = %i[reject delete_if reject! select select! grep_v].freeze
|
|
50
52
|
TO_ENUM_METHODS = %i[to_enum lazy].freeze
|
|
51
53
|
|
|
52
54
|
minimum_target_ruby_version 2.4
|
|
53
55
|
|
|
54
56
|
# @!method reject_method_with_block_pass?(node)
|
|
55
57
|
def_node_matcher :reject_method_with_block_pass?, <<~PATTERN
|
|
56
|
-
(
|
|
58
|
+
(call !nil? {:reject :delete_if :reject!}
|
|
57
59
|
(block_pass
|
|
58
60
|
(sym :nil?)))
|
|
59
61
|
PATTERN
|
|
@@ -61,24 +63,29 @@ module RuboCop
|
|
|
61
63
|
# @!method reject_method?(node)
|
|
62
64
|
def_node_matcher :reject_method?, <<~PATTERN
|
|
63
65
|
(block
|
|
64
|
-
(
|
|
66
|
+
(call
|
|
65
67
|
!nil? {:reject :delete_if :reject!})
|
|
66
68
|
$(args ...)
|
|
67
|
-
(
|
|
69
|
+
(call
|
|
68
70
|
$(lvar _) :nil?))
|
|
69
71
|
PATTERN
|
|
70
72
|
|
|
71
73
|
# @!method select_method?(node)
|
|
72
74
|
def_node_matcher :select_method?, <<~PATTERN
|
|
73
75
|
(block
|
|
74
|
-
(
|
|
76
|
+
(call
|
|
75
77
|
!nil? {:select :select!})
|
|
76
78
|
$(args ...)
|
|
77
|
-
(
|
|
78
|
-
(
|
|
79
|
+
(call
|
|
80
|
+
(call
|
|
79
81
|
$(lvar _) :nil?) :!))
|
|
80
82
|
PATTERN
|
|
81
83
|
|
|
84
|
+
# @!method grep_v_with_nil?(node)
|
|
85
|
+
def_node_matcher :grep_v_with_nil?, <<~PATTERN
|
|
86
|
+
(send _ :grep_v {(nil) (const {nil? cbase} :NilClass)})
|
|
87
|
+
PATTERN
|
|
88
|
+
|
|
82
89
|
def on_send(node)
|
|
83
90
|
return unless (range = offense_range(node))
|
|
84
91
|
return if allowed_receiver?(node.receiver)
|
|
@@ -91,11 +98,13 @@ module RuboCop
|
|
|
91
98
|
|
|
92
99
|
add_offense(range, message: message) { |corrector| corrector.replace(range, good) }
|
|
93
100
|
end
|
|
101
|
+
alias on_csend on_send
|
|
94
102
|
|
|
95
103
|
private
|
|
96
104
|
|
|
105
|
+
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
97
106
|
def offense_range(node)
|
|
98
|
-
if reject_method_with_block_pass?(node)
|
|
107
|
+
if reject_method_with_block_pass?(node) || grep_v_with_nil?(node)
|
|
99
108
|
range(node, node)
|
|
100
109
|
else
|
|
101
110
|
block_node = node.parent
|
|
@@ -109,6 +118,7 @@ module RuboCop
|
|
|
109
118
|
range(node, block_node)
|
|
110
119
|
end
|
|
111
120
|
end
|
|
121
|
+
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
112
122
|
|
|
113
123
|
def to_enum_method?(node)
|
|
114
124
|
return false unless node.receiver.send_type?
|
|
@@ -117,7 +127,7 @@ module RuboCop
|
|
|
117
127
|
end
|
|
118
128
|
|
|
119
129
|
def good_method_name(node)
|
|
120
|
-
if node.bang_method?
|
|
130
|
+
if node.bang_method? || node.method?(:delete_if)
|
|
121
131
|
'compact!'
|
|
122
132
|
else
|
|
123
133
|
'compact'
|
|
@@ -59,8 +59,6 @@ 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)
|
|
@@ -105,11 +103,19 @@ module RuboCop
|
|
|
105
103
|
end
|
|
106
104
|
|
|
107
105
|
def combine_with_left_sibling(corrector, node)
|
|
108
|
-
corrector.
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
)
|
|
112
|
-
|
|
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)
|
|
113
119
|
end
|
|
114
120
|
end
|
|
115
121
|
end
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require_relative '../../directive_comment'
|
|
4
|
+
|
|
3
5
|
module RuboCop
|
|
4
6
|
module Cop
|
|
5
7
|
module Style
|
|
@@ -49,8 +51,9 @@ module RuboCop
|
|
|
49
51
|
KEYWORDS = %w[begin class def end module].freeze
|
|
50
52
|
KEYWORD_REGEXES = KEYWORDS.map { |w| /^\s*#{w}\s/ }.freeze
|
|
51
53
|
|
|
52
|
-
ALLOWED_COMMENTS = %w[:nodoc: :yields:
|
|
53
|
-
ALLOWED_COMMENT_REGEXES = ALLOWED_COMMENTS.map { |c| /#\s*#{c}/ }
|
|
54
|
+
ALLOWED_COMMENTS = %w[:nodoc: :yields:].freeze
|
|
55
|
+
ALLOWED_COMMENT_REGEXES = (ALLOWED_COMMENTS.map { |c| /#\s*#{c}/ } +
|
|
56
|
+
[DirectiveComment::DIRECTIVE_COMMENT_REGEXP]).freeze
|
|
54
57
|
|
|
55
58
|
REGEXP = /(?<keyword>\S+).*#/.freeze
|
|
56
59
|
|