rubocop 1.42.0 → 1.64.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/LICENSE.txt +1 -1
- data/README.md +7 -6
- data/assets/output.css.erb +159 -0
- data/assets/output.html.erb +1 -160
- data/config/default.yml +342 -64
- data/config/obsoletion.yml +5 -0
- data/lib/rubocop/cached_data.rb +11 -3
- data/lib/rubocop/cli/command/auto_generate_config.rb +27 -6
- data/lib/rubocop/cli/command/execute_runner.rb +7 -2
- data/lib/rubocop/cli/command/lsp.rb +19 -0
- data/lib/rubocop/cli/command/show_docs_url.rb +2 -2
- data/lib/rubocop/cli.rb +68 -10
- data/lib/rubocop/comment_config.rb +19 -0
- data/lib/rubocop/config.rb +43 -15
- data/lib/rubocop/config_finder.rb +14 -4
- data/lib/rubocop/config_loader.rb +20 -24
- data/lib/rubocop/config_obsoletion/parameter_rule.rb +9 -1
- data/lib/rubocop/config_obsoletion.rb +13 -10
- data/lib/rubocop/config_validator.rb +14 -7
- data/lib/rubocop/cop/autocorrect_logic.rb +37 -14
- data/lib/rubocop/cop/base.rb +97 -28
- 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 +4 -4
- data/lib/rubocop/cop/bundler/gem_version.rb +5 -7
- data/lib/rubocop/cop/bundler/ordered_gems.rb +9 -1
- data/lib/rubocop/cop/commissioner.rb +8 -2
- data/lib/rubocop/cop/cop.rb +25 -5
- data/lib/rubocop/cop/corrector.rb +11 -3
- data/lib/rubocop/cop/correctors/alignment_corrector.rb +3 -3
- data/lib/rubocop/cop/correctors/each_to_for_corrector.rb +4 -8
- data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +6 -14
- data/lib/rubocop/cop/correctors/lambda_literal_to_method_corrector.rb +7 -4
- data/lib/rubocop/cop/correctors/line_break_corrector.rb +1 -1
- data/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +2 -2
- data/lib/rubocop/cop/correctors/ordered_gem_corrector.rb +2 -7
- data/lib/rubocop/cop/correctors/parentheses_corrector.rb +1 -1
- data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +2 -2
- 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/dependency_version.rb +6 -8
- data/lib/rubocop/cop/gemspec/deprecated_attribute_assignment.rb +3 -3
- data/lib/rubocop/cop/gemspec/development_dependencies.rb +107 -0
- data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +9 -1
- data/lib/rubocop/cop/gemspec/required_ruby_version.rb +5 -1
- data/lib/rubocop/cop/generator/require_file_injector.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/cop_description.rb +37 -13
- data/lib/rubocop/cop/internal_affairs/example_description.rb +46 -24
- data/lib/rubocop/cop/internal_affairs/example_heredoc_delimiter.rb +3 -3
- data/lib/rubocop/cop/internal_affairs/inherit_deprecated_cop_class.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/location_expression.rb +37 -0
- data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +3 -1
- 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 +128 -34
- data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/processed_source_buffer_name.rb +42 -0
- data/lib/rubocop/cop/internal_affairs/redundant_expect_offense_arguments.rb +34 -0
- data/lib/rubocop/cop/internal_affairs/redundant_let_rubocop_config_new.rb +11 -3
- data/lib/rubocop/cop/internal_affairs/redundant_location_argument.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/redundant_message_argument.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/redundant_method_dispatch_node.rb +11 -2
- data/lib/rubocop/cop/internal_affairs/redundant_source_range.rb +66 -0
- data/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +2 -0
- data/lib/rubocop/cop/internal_affairs.rb +5 -0
- data/lib/rubocop/cop/layout/argument_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/array_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/block_end_newline.rb +7 -15
- data/lib/rubocop/cop/layout/class_structure.rb +15 -19
- data/lib/rubocop/cop/layout/closing_heredoc_indentation.rb +2 -3
- data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +2 -6
- data/lib/rubocop/cop/layout/comment_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/dot_position.rb +1 -5
- data/lib/rubocop/cop/layout/empty_comment.rb +6 -4
- data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +42 -9
- data/lib/rubocop/cop/layout/empty_line_after_magic_comment.rb +14 -7
- data/lib/rubocop/cop/layout/empty_line_between_defs.rb +28 -5
- data/lib/rubocop/cop/layout/empty_lines.rb +1 -1
- data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +2 -0
- data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +2 -0
- data/lib/rubocop/cop/layout/end_alignment.rb +23 -3
- data/lib/rubocop/cop/layout/extra_spacing.rb +3 -4
- data/lib/rubocop/cop/layout/first_argument_indentation.rb +8 -3
- data/lib/rubocop/cop/layout/first_array_element_indentation.rb +24 -7
- data/lib/rubocop/cop/layout/first_array_element_line_break.rb +25 -34
- data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +7 -19
- data/lib/rubocop/cop/layout/first_method_argument_line_break.rb +42 -52
- data/lib/rubocop/cop/layout/first_method_parameter_line_break.rb +38 -55
- data/lib/rubocop/cop/layout/first_parameter_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +12 -6
- data/lib/rubocop/cop/layout/heredoc_indentation.rb +12 -12
- data/lib/rubocop/cop/layout/indentation_style.rb +1 -1
- data/lib/rubocop/cop/layout/indentation_width.rb +3 -3
- data/lib/rubocop/cop/layout/initial_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/leading_comment_space.rb +2 -2
- data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +18 -12
- data/lib/rubocop/cop/layout/line_continuation_spacing.rb +12 -8
- data/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb +2 -0
- data/lib/rubocop/cop/layout/multiline_array_line_breaks.rb +8 -27
- data/lib/rubocop/cop/layout/multiline_hash_key_line_breaks.rb +7 -26
- data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +4 -21
- data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +18 -3
- data/lib/rubocop/cop/layout/multiline_method_parameter_line_breaks.rb +6 -30
- data/lib/rubocop/cop/layout/redundant_line_break.rb +33 -11
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +6 -6
- 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_keyword.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_before_block_braces.rb +19 -10
- data/lib/rubocop/cop/layout/space_before_first_arg.rb +1 -1
- data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +2 -2
- data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +11 -13
- data/lib/rubocop/cop/layout/space_inside_block_braces.rb +3 -1
- data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +1 -1
- data/lib/rubocop/cop/layout/space_inside_parens.rb +3 -3
- data/lib/rubocop/cop/layout/space_inside_percent_literal_delimiters.rb +1 -1
- data/lib/rubocop/cop/layout/space_inside_range_literal.rb +1 -1
- data/lib/rubocop/cop/layout/space_inside_reference_brackets.rb +4 -4
- data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +6 -6
- data/lib/rubocop/cop/layout/trailing_empty_lines.rb +5 -0
- data/lib/rubocop/cop/layout/trailing_whitespace.rb +1 -1
- data/lib/rubocop/cop/lint/ambiguous_block_association.rb +13 -1
- data/lib/rubocop/cop/lint/ambiguous_operator.rb +4 -0
- 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/constant_resolution.rb +1 -1
- data/lib/rubocop/cop/lint/debugger.rb +49 -26
- data/lib/rubocop/cop/lint/deprecated_class_methods.rb +62 -112
- data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +1 -1
- data/lib/rubocop/cop/lint/duplicate_hash_key.rb +2 -1
- data/lib/rubocop/cop/lint/duplicate_match_pattern.rb +122 -0
- data/lib/rubocop/cop/lint/duplicate_methods.rb +3 -3
- data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +47 -22
- data/lib/rubocop/cop/lint/else_layout.rb +3 -7
- data/lib/rubocop/cop/lint/empty_block.rb +2 -2
- data/lib/rubocop/cop/lint/empty_conditional_body.rb +6 -4
- data/lib/rubocop/cop/lint/empty_interpolation.rb +1 -1
- data/lib/rubocop/cop/lint/erb_new_arguments.rb +27 -21
- data/lib/rubocop/cop/lint/float_comparison.rb +10 -0
- data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +14 -7
- data/lib/rubocop/cop/lint/hash_compare_by_identity.rb +2 -1
- data/lib/rubocop/cop/lint/heredoc_method_call_position.rb +16 -18
- data/lib/rubocop/cop/lint/identity_comparison.rb +0 -1
- data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +1 -1
- data/lib/rubocop/cop/lint/incompatible_io_select_with_fiber_scheduler.rb +5 -3
- data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +1 -1
- data/lib/rubocop/cop/lint/inherit_exception.rb +9 -0
- data/lib/rubocop/cop/lint/it_without_arguments_in_block.rb +56 -0
- data/lib/rubocop/cop/lint/lambda_without_literal_block.rb +1 -1
- data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +85 -0
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +47 -5
- data/lib/rubocop/cop/lint/missing_super.rb +63 -5
- data/lib/rubocop/cop/lint/mixed_case_range.rb +116 -0
- data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +1 -0
- data/lib/rubocop/cop/lint/nested_method_definition.rb +4 -9
- 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 +14 -4
- data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +2 -2
- data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +2 -0
- data/lib/rubocop/cop/lint/ordered_magic_comments.rb +0 -1
- data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +8 -12
- data/lib/rubocop/cop/lint/percent_string_array.rb +1 -1
- data/lib/rubocop/cop/lint/percent_symbol_array.rb +1 -1
- data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +11 -5
- data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +5 -5
- data/lib/rubocop/cop/lint/redundant_regexp_quantifiers.rb +130 -0
- data/lib/rubocop/cop/lint/redundant_require_statement.rb +21 -2
- data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +72 -8
- data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +1 -1
- data/lib/rubocop/cop/lint/redundant_string_coercion.rb +35 -15
- data/lib/rubocop/cop/lint/redundant_with_index.rb +7 -3
- data/lib/rubocop/cop/lint/redundant_with_object.rb +3 -3
- data/lib/rubocop/cop/lint/refinement_import_methods.rb +2 -1
- data/lib/rubocop/cop/lint/rescue_type.rb +2 -4
- data/lib/rubocop/cop/lint/safe_navigation_chain.rb +14 -8
- data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +1 -1
- 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/send_with_mixin_argument.rb +1 -2
- data/lib/rubocop/cop/lint/shadowed_argument.rb +1 -0
- data/lib/rubocop/cop/lint/shadowed_exception.rb +6 -12
- 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 +2 -2
- data/lib/rubocop/cop/lint/symbol_conversion.rb +8 -3
- data/lib/rubocop/cop/lint/syntax.rb +10 -3
- data/lib/rubocop/cop/lint/to_enum_arguments.rb +23 -6
- data/lib/rubocop/cop/lint/top_level_return_with_argument.rb +23 -9
- 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/unreachable_code.rb +4 -2
- data/lib/rubocop/cop/lint/unreachable_loop.rb +11 -5
- data/lib/rubocop/cop/lint/useless_access_modifier.rb +12 -9
- data/lib/rubocop/cop/lint/useless_assignment.rb +94 -10
- data/lib/rubocop/cop/lint/useless_method_definition.rb +12 -4
- data/lib/rubocop/cop/lint/useless_rescue.rb +89 -0
- data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +9 -1
- data/lib/rubocop/cop/lint/useless_times.rb +3 -3
- data/lib/rubocop/cop/lint/void.rb +119 -20
- data/lib/rubocop/cop/metrics/abc_size.rb +3 -3
- data/lib/rubocop/cop/metrics/block_length.rb +2 -2
- data/lib/rubocop/cop/metrics/block_nesting.rb +2 -2
- data/lib/rubocop/cop/metrics/class_length.rb +8 -2
- data/lib/rubocop/cop/metrics/collection_literal_length.rb +76 -0
- data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +1 -1
- data/lib/rubocop/cop/metrics/method_length.rb +1 -1
- data/lib/rubocop/cop/metrics/parameter_lists.rb +27 -0
- data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +3 -7
- data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +38 -10
- data/lib/rubocop/cop/migration/department_name.rb +3 -3
- data/lib/rubocop/cop/mixin/alignment.rb +1 -1
- data/lib/rubocop/cop/mixin/allowed_methods.rb +3 -1
- data/lib/rubocop/cop/mixin/allowed_receivers.rb +34 -0
- data/lib/rubocop/cop/mixin/annotation_comment.rb +1 -1
- 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 +21 -11
- 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/documentation_comment.rb +1 -1
- data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +1 -1
- data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +1 -1
- data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +78 -29
- data/lib/rubocop/cop/mixin/hash_transform_method.rb +3 -3
- data/lib/rubocop/cop/mixin/heredoc.rb +6 -2
- data/lib/rubocop/cop/mixin/line_length_help.rb +3 -1
- data/lib/rubocop/cop/mixin/method_complexity.rb +15 -6
- data/lib/rubocop/cop/mixin/min_branches_count.rb +40 -0
- data/lib/rubocop/cop/mixin/multiline_element_line_breaks.rb +0 -3
- data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +4 -3
- data/lib/rubocop/cop/mixin/ordered_gem_node.rb +1 -1
- data/lib/rubocop/cop/mixin/percent_literal.rb +1 -1
- data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +6 -8
- data/lib/rubocop/cop/mixin/range_help.rb +1 -6
- data/lib/rubocop/cop/mixin/safe_assignment.rb +1 -1
- data/lib/rubocop/cop/mixin/space_after_punctuation.rb +1 -1
- data/lib/rubocop/cop/mixin/space_before_punctuation.rb +1 -1
- data/lib/rubocop/cop/mixin/statement_modifier.rb +4 -3
- data/lib/rubocop/cop/mixin/string_help.rb +4 -2
- data/lib/rubocop/cop/mixin/surrounding_space.rb +3 -3
- data/lib/rubocop/cop/mixin/trailing_comma.rb +3 -3
- data/lib/rubocop/cop/naming/ascii_identifiers.rb +1 -1
- data/lib/rubocop/cop/naming/block_forwarding.rb +38 -7
- data/lib/rubocop/cop/naming/class_and_module_camel_case.rb +1 -1
- data/lib/rubocop/cop/naming/constant_name.rb +2 -3
- data/lib/rubocop/cop/naming/file_name.rb +3 -3
- data/lib/rubocop/cop/naming/heredoc_delimiter_case.rb +1 -1
- data/lib/rubocop/cop/naming/heredoc_delimiter_naming.rb +3 -1
- data/lib/rubocop/cop/naming/inclusive_language.rb +24 -6
- data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +26 -11
- data/lib/rubocop/cop/naming/method_name.rb +3 -3
- data/lib/rubocop/cop/naming/predicate_name.rb +3 -3
- data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +12 -4
- data/lib/rubocop/cop/naming/variable_name.rb +6 -1
- data/lib/rubocop/cop/registry.rb +16 -9
- 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 +78 -13
- data/lib/rubocop/cop/style/accessor_grouping.rb +44 -18
- data/lib/rubocop/cop/style/alias.rb +10 -8
- data/lib/rubocop/cop/style/arguments_forwarding.rb +414 -62
- data/lib/rubocop/cop/style/array_first_last.rb +64 -0
- data/lib/rubocop/cop/style/array_intersect.rb +14 -6
- data/lib/rubocop/cop/style/ascii_comments.rb +1 -1
- data/lib/rubocop/cop/style/attr.rb +11 -1
- data/lib/rubocop/cop/style/auto_resource_cleanup.rb +21 -14
- data/lib/rubocop/cop/style/begin_block.rb +1 -2
- data/lib/rubocop/cop/style/bisected_attr_accessor.rb +3 -3
- data/lib/rubocop/cop/style/block_comments.rb +2 -2
- data/lib/rubocop/cop/style/block_delimiters.rb +22 -6
- data/lib/rubocop/cop/style/case_like_if.rb +25 -8
- data/lib/rubocop/cop/style/class_and_module_children.rb +5 -12
- data/lib/rubocop/cop/style/class_check.rb +1 -0
- data/lib/rubocop/cop/style/class_equality_comparison.rb +58 -40
- data/lib/rubocop/cop/style/class_vars.rb +3 -3
- data/lib/rubocop/cop/style/collection_compact.rb +37 -14
- data/lib/rubocop/cop/style/collection_methods.rb +2 -0
- data/lib/rubocop/cop/style/colon_method_call.rb +2 -2
- data/lib/rubocop/cop/style/combinable_loops.rb +36 -8
- data/lib/rubocop/cop/style/command_literal.rb +1 -1
- data/lib/rubocop/cop/style/comment_annotation.rb +1 -1
- data/lib/rubocop/cop/style/commented_keyword.rb +7 -4
- data/lib/rubocop/cop/style/comparable_clamp.rb +125 -0
- data/lib/rubocop/cop/style/concat_array_literals.rb +12 -3
- data/lib/rubocop/cop/style/conditional_assignment.rb +15 -20
- data/lib/rubocop/cop/style/copyright.rb +37 -24
- data/lib/rubocop/cop/style/data_inheritance.rb +75 -0
- data/lib/rubocop/cop/style/date_time.rb +5 -4
- data/lib/rubocop/cop/style/dir.rb +1 -1
- data/lib/rubocop/cop/style/dir_empty.rb +54 -0
- data/lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb +2 -2
- data/lib/rubocop/cop/style/document_dynamic_eval_definition.rb +3 -3
- data/lib/rubocop/cop/style/documentation.rb +36 -30
- data/lib/rubocop/cop/style/documentation_method.rb +30 -4
- data/lib/rubocop/cop/style/double_negation.rb +2 -2
- data/lib/rubocop/cop/style/each_for_simple_loop.rb +7 -7
- data/lib/rubocop/cop/style/each_with_object.rb +3 -3
- data/lib/rubocop/cop/style/empty_block_parameter.rb +1 -1
- data/lib/rubocop/cop/style/empty_case_condition.rb +6 -1
- data/lib/rubocop/cop/style/empty_lambda_parameter.rb +1 -1
- data/lib/rubocop/cop/style/empty_literal.rb +1 -1
- data/lib/rubocop/cop/style/eval_with_location.rb +14 -23
- data/lib/rubocop/cop/style/exact_regexp_match.rb +70 -0
- data/lib/rubocop/cop/style/explicit_block_argument.rb +3 -3
- data/lib/rubocop/cop/style/file_empty.rb +71 -0
- data/lib/rubocop/cop/style/file_read.rb +3 -3
- data/lib/rubocop/cop/style/file_write.rb +1 -1
- data/lib/rubocop/cop/style/for.rb +3 -1
- data/lib/rubocop/cop/style/format_string.rb +33 -12
- data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +4 -2
- data/lib/rubocop/cop/style/guard_clause.rb +29 -1
- data/lib/rubocop/cop/style/hash_conversion.rb +10 -0
- data/lib/rubocop/cop/style/hash_each_methods.rb +106 -21
- data/lib/rubocop/cop/style/hash_except.rb +25 -13
- data/lib/rubocop/cop/style/hash_like_case.rb +3 -9
- data/lib/rubocop/cop/style/hash_syntax.rb +29 -3
- data/lib/rubocop/cop/style/hash_transform_keys.rb +2 -2
- data/lib/rubocop/cop/style/hash_transform_values.rb +2 -2
- data/lib/rubocop/cop/style/identical_conditional_branches.rb +34 -5
- data/lib/rubocop/cop/style/if_inside_else.rb +6 -0
- data/lib/rubocop/cop/style/if_unless_modifier.rb +111 -15
- data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +7 -3
- data/lib/rubocop/cop/style/if_with_semicolon.rb +2 -2
- data/lib/rubocop/cop/style/infinite_loop.rb +2 -5
- data/lib/rubocop/cop/style/inverse_methods.rb +14 -13
- data/lib/rubocop/cop/style/invertible_unless_condition.rb +160 -0
- 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 +8 -10
- data/lib/rubocop/cop/style/map_into_array.rb +175 -0
- data/lib/rubocop/cop/style/map_to_hash.rb +20 -7
- data/lib/rubocop/cop/style/map_to_set.rb +5 -2
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +48 -28
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +46 -41
- data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +22 -0
- data/lib/rubocop/cop/style/method_def_parentheses.rb +1 -1
- data/lib/rubocop/cop/style/min_max.rb +3 -3
- data/lib/rubocop/cop/style/min_max_comparison.rb +11 -1
- data/lib/rubocop/cop/style/missing_else.rb +13 -1
- data/lib/rubocop/cop/style/missing_respond_to_missing.rb +2 -2
- data/lib/rubocop/cop/style/mixin_grouping.rb +5 -5
- data/lib/rubocop/cop/style/multiline_block_chain.rb +1 -1
- data/lib/rubocop/cop/style/multiline_if_modifier.rb +0 -4
- data/lib/rubocop/cop/style/multiline_memoization.rb +2 -2
- data/lib/rubocop/cop/style/multiline_method_signature.rb +17 -5
- data/lib/rubocop/cop/style/multiline_ternary_operator.rb +21 -4
- data/lib/rubocop/cop/style/multiple_comparison.rb +14 -0
- data/lib/rubocop/cop/style/negated_if_else_condition.rb +13 -12
- 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/nil_comparison.rb +2 -0
- data/lib/rubocop/cop/style/nil_lambda.rb +2 -2
- data/lib/rubocop/cop/style/numbered_parameters_limit.rb +11 -3
- data/lib/rubocop/cop/style/numeric_literal_prefix.rb +1 -1
- data/lib/rubocop/cop/style/numeric_literals.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 +4 -7
- data/lib/rubocop/cop/style/open_struct_use.rb +1 -1
- data/lib/rubocop/cop/style/operator_method_call.rb +24 -4
- data/lib/rubocop/cop/style/parallel_assignment.rb +32 -24
- data/lib/rubocop/cop/style/parentheses_around_condition.rb +8 -0
- data/lib/rubocop/cop/style/percent_literal_delimiters.rb +2 -3
- data/lib/rubocop/cop/style/percent_q_literals.rb +1 -1
- data/lib/rubocop/cop/style/preferred_hash_methods.rb +1 -1
- data/lib/rubocop/cop/style/raise_args.rb +4 -1
- data/lib/rubocop/cop/style/redundant_argument.rb +33 -4
- data/lib/rubocop/cop/style/redundant_array_constructor.rb +77 -0
- data/lib/rubocop/cop/style/redundant_assignment.rb +10 -2
- data/lib/rubocop/cop/style/redundant_begin.rb +10 -2
- data/lib/rubocop/cop/style/redundant_condition.rb +18 -3
- data/lib/rubocop/cop/style/redundant_conditional.rb +2 -14
- data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +39 -0
- data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +103 -9
- 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 +9 -7
- data/lib/rubocop/cop/style/redundant_filter_chain.rb +118 -0
- data/lib/rubocop/cop/style/redundant_heredoc_delimiter_quotes.rb +58 -0
- data/lib/rubocop/cop/style/redundant_interpolation.rb +2 -2
- data/lib/rubocop/cop/style/redundant_line_continuation.rb +200 -0
- data/lib/rubocop/cop/style/redundant_parentheses.rb +73 -24
- data/lib/rubocop/cop/style/redundant_percent_q.rb +2 -2
- data/lib/rubocop/cop/style/redundant_regexp_argument.rb +100 -0
- data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +7 -8
- data/lib/rubocop/cop/style/redundant_regexp_constructor.rb +46 -0
- data/lib/rubocop/cop/style/redundant_regexp_escape.rb +13 -4
- data/lib/rubocop/cop/style/redundant_return.rb +14 -3
- data/lib/rubocop/cop/style/redundant_self.rb +17 -2
- data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +8 -1
- data/lib/rubocop/cop/style/redundant_sort.rb +13 -12
- data/lib/rubocop/cop/style/redundant_sort_by.rb +2 -2
- data/lib/rubocop/cop/style/redundant_string_escape.rb +6 -5
- data/lib/rubocop/cop/style/regexp_literal.rb +11 -2
- data/lib/rubocop/cop/style/require_order.rb +12 -15
- data/lib/rubocop/cop/style/rescue_modifier.rb +1 -3
- data/lib/rubocop/cop/style/rescue_standard_error.rb +2 -2
- data/lib/rubocop/cop/style/return_nil.rb +6 -2
- data/lib/rubocop/cop/style/return_nil_in_predicate_method_definition.rb +95 -0
- data/lib/rubocop/cop/style/safe_navigation.rb +2 -2
- data/lib/rubocop/cop/style/sample.rb +3 -4
- data/lib/rubocop/cop/style/select_by_regexp.rb +22 -11
- data/lib/rubocop/cop/style/self_assignment.rb +3 -3
- data/lib/rubocop/cop/style/semicolon.rb +43 -5
- data/lib/rubocop/cop/style/send.rb +4 -4
- data/lib/rubocop/cop/style/send_with_literal_method_name.rb +90 -0
- data/lib/rubocop/cop/style/signal_exception.rb +1 -1
- 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/single_line_methods.rb +1 -1
- data/lib/rubocop/cop/style/slicing_with_range.rb +77 -11
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +9 -5
- data/lib/rubocop/cop/style/special_global_vars.rb +4 -6
- data/lib/rubocop/cop/style/stderr_puts.rb +1 -1
- data/lib/rubocop/cop/style/string_chars.rb +1 -0
- data/lib/rubocop/cop/style/string_hash_keys.rb +4 -1
- 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/struct_inheritance.rb +1 -1
- data/lib/rubocop/cop/style/super_arguments.rb +156 -0
- 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 +68 -5
- data/lib/rubocop/cop/style/top_level_method_definition.rb +1 -1
- data/lib/rubocop/cop/style/trailing_body_on_class.rb +1 -0
- data/lib/rubocop/cop/style/trailing_underscore_variable.rb +1 -1
- data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
- data/lib/rubocop/cop/style/unless_logical_operators.rb +1 -0
- data/lib/rubocop/cop/style/unpack_first.rb +11 -14
- data/lib/rubocop/cop/style/word_array.rb +18 -6
- data/lib/rubocop/cop/style/yaml_file_read.rb +66 -0
- data/lib/rubocop/cop/style/yoda_condition.rb +17 -8
- data/lib/rubocop/cop/style/yoda_expression.rb +26 -9
- data/lib/rubocop/cop/style/zero_length_predicate.rb +9 -5
- data/lib/rubocop/cop/team.rb +36 -23
- data/lib/rubocop/cop/util.rb +14 -5
- data/lib/rubocop/cop/utils/regexp_ranges.rb +113 -0
- data/lib/rubocop/cop/variable_force/assignment.rb +45 -4
- data/lib/rubocop/cop/variable_force/scope.rb +3 -3
- data/lib/rubocop/cop/variable_force/variable.rb +5 -3
- data/lib/rubocop/cop/variable_force/variable_table.rb +5 -3
- data/lib/rubocop/cop/variable_force.rb +2 -1
- data/lib/rubocop/cops_documentation_generator.rb +26 -7
- data/lib/rubocop/directive_comment.rb +13 -11
- data/lib/rubocop/ext/comment.rb +18 -0
- data/lib/rubocop/ext/regexp_node.rb +10 -5
- data/lib/rubocop/ext/regexp_parser.rb +5 -2
- data/lib/rubocop/file_finder.rb +4 -7
- 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 +35 -14
- data/lib/rubocop/formatter/json_formatter.rb +0 -1
- data/lib/rubocop/formatter/junit_formatter.rb +4 -1
- data/lib/rubocop/formatter/offense_count_formatter.rb +12 -2
- data/lib/rubocop/formatter/simple_text_formatter.rb +1 -1
- data/lib/rubocop/formatter/tap_formatter.rb +3 -7
- data/lib/rubocop/formatter.rb +1 -2
- data/lib/rubocop/lockfile.rb +56 -7
- data/lib/rubocop/lsp/logger.rb +22 -0
- data/lib/rubocop/lsp/routes.rb +243 -0
- data/lib/rubocop/lsp/runtime.rb +99 -0
- data/lib/rubocop/lsp/server.rb +73 -0
- data/lib/rubocop/lsp/severity.rb +27 -0
- data/lib/rubocop/lsp.rb +36 -0
- data/lib/rubocop/magic_comment.rb +13 -11
- data/lib/rubocop/options.rb +49 -12
- data/lib/rubocop/path_util.rb +17 -8
- data/lib/rubocop/rake_task.rb +1 -1
- data/lib/rubocop/result_cache.rb +6 -3
- data/lib/rubocop/rspec/cop_helper.rb +9 -3
- data/lib/rubocop/rspec/expect_offense.rb +18 -8
- data/lib/rubocop/rspec/shared_contexts.rb +59 -19
- data/lib/rubocop/rspec/support.rb +3 -0
- data/lib/rubocop/runner.rb +59 -10
- data/lib/rubocop/server/cache.rb +11 -4
- data/lib/rubocop/server/cli.rb +37 -18
- data/lib/rubocop/server/client_command/exec.rb +4 -4
- data/lib/rubocop/server/client_command/start.rb +6 -1
- data/lib/rubocop/server/core.rb +24 -9
- data/lib/rubocop/server/helper.rb +1 -1
- data/lib/rubocop/server/server_command/exec.rb +1 -2
- data/lib/rubocop/string_interpreter.rb +3 -3
- data/lib/rubocop/target_finder.rb +91 -81
- data/lib/rubocop/target_ruby.rb +85 -78
- data/lib/rubocop/version.rb +27 -8
- data/lib/rubocop.rb +35 -0
- metadata +76 -35
- /data/lib/rubocop/formatter/{git_hub_actions_formatter.rb → github_actions_formatter.rb} +0 -0
@@ -8,6 +8,29 @@ 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
|
+
#
|
17
|
+
# In Ruby 3.2, anonymous args/kwargs forwarding has been added.
|
18
|
+
#
|
19
|
+
# This cop also identifies places where `use_args(*args)`/`use_kwargs(**kwargs)` can be
|
20
|
+
# replaced by `use_args(*)`/`use_kwargs(**)`; if desired, this functionality can be disabled
|
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`.
|
33
|
+
#
|
11
34
|
# @example
|
12
35
|
# # bad
|
13
36
|
# def foo(*args, &block)
|
@@ -24,7 +47,30 @@ module RuboCop
|
|
24
47
|
# bar(...)
|
25
48
|
# end
|
26
49
|
#
|
27
|
-
# @example
|
50
|
+
# @example UseAnonymousForwarding: true (default, only relevant for Ruby >= 3.2)
|
51
|
+
# # bad
|
52
|
+
# def foo(*args, **kwargs, &block)
|
53
|
+
# args_only(*args)
|
54
|
+
# kwargs_only(**kwargs)
|
55
|
+
# block_only(&block)
|
56
|
+
# end
|
57
|
+
#
|
58
|
+
# # good
|
59
|
+
# def foo(*, **, &)
|
60
|
+
# args_only(*)
|
61
|
+
# kwargs_only(**)
|
62
|
+
# block_only(&)
|
63
|
+
# end
|
64
|
+
#
|
65
|
+
# @example UseAnonymousForwarding: false (only relevant for Ruby >= 3.2)
|
66
|
+
# # good
|
67
|
+
# def foo(*args, **kwargs, &block)
|
68
|
+
# args_only(*args)
|
69
|
+
# kwargs_only(**kwargs)
|
70
|
+
# block_only(&block)
|
71
|
+
# end
|
72
|
+
#
|
73
|
+
# @example AllowOnlyRestArgument: true (default, only relevant for Ruby < 3.2)
|
28
74
|
# # good
|
29
75
|
# def foo(*args)
|
30
76
|
# bar(*args)
|
@@ -34,7 +80,7 @@ module RuboCop
|
|
34
80
|
# bar(**kwargs)
|
35
81
|
# end
|
36
82
|
#
|
37
|
-
# @example AllowOnlyRestArgument: false
|
83
|
+
# @example AllowOnlyRestArgument: false (only relevant for Ruby < 3.2)
|
38
84
|
# # bad
|
39
85
|
# # The following code can replace the arguments with `...`,
|
40
86
|
# # but it will change the behavior. Because `...` forwards block also.
|
@@ -46,6 +92,38 @@ module RuboCop
|
|
46
92
|
# bar(**kwargs)
|
47
93
|
# end
|
48
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
|
49
127
|
class ArgumentsForwarding < Base
|
50
128
|
include RangeHelp
|
51
129
|
extend AutoCorrector
|
@@ -53,101 +131,375 @@ module RuboCop
|
|
53
131
|
|
54
132
|
minimum_target_ruby_version 2.7
|
55
133
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
(send _ _ (hash (kwsplat (lvar %1))))
|
68
|
-
}
|
69
|
-
PATTERN
|
70
|
-
|
71
|
-
# @!method forwarding_method_arguments?(node, rest_name, block_name, kwargs_name)
|
72
|
-
def_node_matcher :forwarding_method_arguments?, <<~PATTERN
|
73
|
-
{
|
74
|
-
(send _ _
|
75
|
-
(splat (lvar %1))
|
76
|
-
(block-pass {(lvar %2) nil?}))
|
77
|
-
(send _ _
|
78
|
-
(splat (lvar %1))
|
79
|
-
(hash (kwsplat (lvar %3)))
|
80
|
-
(block-pass {(lvar %2) nil?}))
|
81
|
-
}
|
82
|
-
PATTERN
|
134
|
+
FORWARDING_LVAR_TYPES = %i[splat kwsplat block_pass].freeze
|
135
|
+
ADDITIONAL_ARG_TYPES = %i[lvar arg].freeze
|
136
|
+
|
137
|
+
FORWARDING_MSG = 'Use shorthand syntax `...` for arguments forwarding.'
|
138
|
+
ARGS_MSG = 'Use anonymous positional arguments forwarding (`*`).'
|
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
|
83
145
|
|
84
146
|
def on_def(node)
|
85
147
|
return unless node.body
|
86
|
-
return unless (rest_args_name, args = use_rest_arguments?(node.arguments))
|
87
148
|
|
88
|
-
node.
|
89
|
-
|
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).to_a
|
90
152
|
|
91
|
-
|
92
|
-
|
153
|
+
send_classifications = classify_send_nodes(
|
154
|
+
node, send_nodes, non_splat_or_block_pass_lvar_references(node.body), forwardable_args
|
155
|
+
)
|
93
156
|
|
94
|
-
|
95
|
-
|
157
|
+
return if send_classifications.empty?
|
158
|
+
|
159
|
+
if only_forwards_all?(send_classifications)
|
160
|
+
add_forward_all_offenses(node, send_classifications, forwardable_args)
|
161
|
+
elsif target_ruby_version >= 3.2
|
162
|
+
add_post_ruby_32_offenses(node, send_classifications, forwardable_args)
|
96
163
|
end
|
97
164
|
end
|
165
|
+
|
98
166
|
alias on_defs on_def
|
99
167
|
|
100
168
|
private
|
101
169
|
|
102
|
-
def
|
103
|
-
|
104
|
-
|
170
|
+
def extract_forwardable_args(args)
|
171
|
+
[args.find(&:restarg_type?), args.find(&:kwrestarg_type?), args.find(&:blockarg_type?)]
|
172
|
+
end
|
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
|
+
|
182
|
+
def only_forwards_all?(send_classifications)
|
183
|
+
send_classifications.all? { |_, c, _, _| c == :all }
|
184
|
+
end
|
185
|
+
|
186
|
+
# rubocop:disable Metrics/MethodLength
|
187
|
+
def add_forward_all_offenses(node, send_classifications, forwardable_args)
|
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
|
204
|
+
end
|
205
|
+
|
206
|
+
return if registered_block_arg_offense
|
105
207
|
|
106
|
-
|
208
|
+
rest_arg, _kwrest_arg, _block_arg = *forwardable_args
|
209
|
+
register_forward_all_offense(node, node.arguments, rest_arg)
|
107
210
|
end
|
211
|
+
# rubocop:enable Metrics/MethodLength
|
108
212
|
|
109
|
-
|
110
|
-
|
213
|
+
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
214
|
+
def add_post_ruby_32_offenses(def_node, send_classifications, forwardable_args)
|
215
|
+
return unless use_anonymous_forwarding?
|
111
216
|
|
112
|
-
|
217
|
+
rest_arg, kwrest_arg, block_arg = *forwardable_args
|
218
|
+
|
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)
|
221
|
+
register_forward_args_offense(def_node.arguments, rest_arg)
|
222
|
+
register_forward_args_offense(send_node, forward_rest)
|
223
|
+
end
|
224
|
+
|
225
|
+
if outside_block?(forward_kwrest)
|
226
|
+
register_forward_kwargs_offense(!forward_rest, def_node.arguments, kwrest_arg)
|
227
|
+
register_forward_kwargs_offense(!forward_rest, send_node, forward_kwrest)
|
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
|
236
|
+
end
|
113
237
|
end
|
238
|
+
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength
|
114
239
|
|
115
|
-
def
|
116
|
-
|
240
|
+
def non_splat_or_block_pass_lvar_references(body)
|
241
|
+
body.each_descendant(:lvar, :lvasgn).filter_map do |lvar|
|
242
|
+
parent = lvar.parent
|
117
243
|
|
118
|
-
|
119
|
-
end_pos = forwarding_method.source_range.end_pos
|
244
|
+
next if lvar.lvar_type? && FORWARDING_LVAR_TYPES.include?(parent.type)
|
120
245
|
|
121
|
-
|
246
|
+
lvar.children.first
|
247
|
+
end.uniq
|
122
248
|
end
|
123
249
|
|
124
|
-
def
|
125
|
-
|
126
|
-
|
127
|
-
|
250
|
+
def classify_send_nodes(def_node, send_nodes, referenced_lvars, forwardable_args)
|
251
|
+
send_nodes.filter_map do |send_node|
|
252
|
+
classification_and_forwards = classification_and_forwards(
|
253
|
+
def_node,
|
254
|
+
send_node,
|
255
|
+
referenced_lvars,
|
256
|
+
forwardable_args
|
128
257
|
)
|
129
|
-
|
258
|
+
|
259
|
+
next unless classification_and_forwards
|
260
|
+
|
261
|
+
[send_node, *classification_and_forwards]
|
130
262
|
end
|
131
263
|
end
|
132
264
|
|
133
|
-
def
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
265
|
+
def classification_and_forwards(def_node, send_node, referenced_lvars, forwardable_args)
|
266
|
+
classifier = SendNodeClassifier.new(
|
267
|
+
def_node, send_node, referenced_lvars, forwardable_args,
|
268
|
+
target_ruby_version: target_ruby_version,
|
269
|
+
allow_only_rest_arguments: allow_only_rest_arguments?
|
270
|
+
)
|
271
|
+
|
272
|
+
classification = classifier.classification
|
273
|
+
|
274
|
+
return unless classification
|
275
|
+
|
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?
|
298
|
+
end
|
299
|
+
|
300
|
+
def register_forward_args_offense(def_arguments_or_send, rest_arg_or_splat)
|
301
|
+
add_offense(rest_arg_or_splat, message: ARGS_MSG) do |corrector|
|
302
|
+
add_parens_if_missing(def_arguments_or_send, corrector)
|
303
|
+
|
304
|
+
corrector.replace(rest_arg_or_splat, '*')
|
305
|
+
end
|
306
|
+
end
|
307
|
+
|
308
|
+
def register_forward_kwargs_offense(add_parens, def_arguments_or_send, kwrest_arg_or_splat)
|
309
|
+
add_offense(kwrest_arg_or_splat, message: KWARGS_MSG) do |corrector|
|
310
|
+
add_parens_if_missing(def_arguments_or_send, corrector) if add_parens
|
311
|
+
|
312
|
+
corrector.replace(kwrest_arg_or_splat, '**')
|
139
313
|
end
|
140
314
|
end
|
141
315
|
|
142
|
-
def
|
143
|
-
|
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?
|
144
319
|
|
145
|
-
|
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
|
+
|
327
|
+
def register_forward_all_offense(def_or_send, send_or_arguments, rest_or_splat)
|
328
|
+
arg_range = arguments_range(def_or_send, rest_or_splat)
|
329
|
+
|
330
|
+
add_offense(arg_range, message: FORWARDING_MSG) do |corrector|
|
331
|
+
add_parens_if_missing(send_or_arguments, corrector)
|
332
|
+
|
333
|
+
corrector.replace(arg_range, '...')
|
334
|
+
end
|
335
|
+
end
|
336
|
+
|
337
|
+
def arguments_range(node, first_node)
|
338
|
+
arguments = node.arguments.reject { |arg| ADDITIONAL_ARG_TYPES.include?(arg.type) }
|
339
|
+
|
340
|
+
start_node = first_node || arguments.first
|
341
|
+
|
342
|
+
range_between(start_node.source_range.begin_pos, arguments.last.source_range.end_pos)
|
146
343
|
end
|
147
344
|
|
148
345
|
def allow_only_rest_arguments?
|
149
346
|
cop_config.fetch('AllowOnlyRestArgument', true)
|
150
347
|
end
|
348
|
+
|
349
|
+
def use_anonymous_forwarding?
|
350
|
+
cop_config.fetch('UseAnonymousForwarding', false)
|
351
|
+
end
|
352
|
+
|
353
|
+
def add_parens_if_missing(node, corrector)
|
354
|
+
return if parentheses?(node)
|
355
|
+
|
356
|
+
add_parentheses(node, corrector)
|
357
|
+
end
|
358
|
+
|
359
|
+
# Classifies send nodes for possible rest/kwrest/all (including block) forwarding.
|
360
|
+
class SendNodeClassifier
|
361
|
+
extend NodePattern::Macros
|
362
|
+
|
363
|
+
# @!method forwarded_rest_arg?(node, rest_name)
|
364
|
+
def_node_matcher :forwarded_rest_arg?, '(splat (lvar %1))'
|
365
|
+
|
366
|
+
# @!method extract_forwarded_kwrest_arg(node, kwrest_name)
|
367
|
+
def_node_matcher :extract_forwarded_kwrest_arg, '(hash <$(kwsplat (lvar %1)) ...>)'
|
368
|
+
|
369
|
+
# @!method forwarded_block_arg?(node, block_name)
|
370
|
+
def_node_matcher :forwarded_block_arg?, '(block_pass {(lvar %1) nil?})'
|
371
|
+
|
372
|
+
def initialize(def_node, send_node, referenced_lvars, forwardable_args, **config)
|
373
|
+
@def_node = def_node
|
374
|
+
@send_node = send_node
|
375
|
+
@referenced_lvars = referenced_lvars
|
376
|
+
@rest_arg, @kwrest_arg, @block_arg = *forwardable_args
|
377
|
+
@rest_arg_name, @kwrest_arg_name, @block_arg_name =
|
378
|
+
*forwardable_args.map { |a| a&.name }
|
379
|
+
@config = config
|
380
|
+
end
|
381
|
+
|
382
|
+
def forwarded_rest_arg
|
383
|
+
return nil if referenced_rest_arg?
|
384
|
+
|
385
|
+
arguments.find { |arg| forwarded_rest_arg?(arg, @rest_arg_name) }
|
386
|
+
end
|
387
|
+
|
388
|
+
def forwarded_kwrest_arg
|
389
|
+
return nil if referenced_kwrest_arg?
|
390
|
+
|
391
|
+
arguments.filter_map { |arg| extract_forwarded_kwrest_arg(arg, @kwrest_arg_name) }.first
|
392
|
+
end
|
393
|
+
|
394
|
+
def forwarded_block_arg
|
395
|
+
return nil if referenced_block_arg?
|
396
|
+
|
397
|
+
arguments.find { |arg| forwarded_block_arg?(arg, @block_arg_name) }
|
398
|
+
end
|
399
|
+
|
400
|
+
def classification
|
401
|
+
return nil unless forwarded_rest_arg || forwarded_kwrest_arg || forwarded_block_arg
|
402
|
+
|
403
|
+
if can_forward_all?
|
404
|
+
:all
|
405
|
+
else
|
406
|
+
:rest_or_kwrest
|
407
|
+
end
|
408
|
+
end
|
409
|
+
|
410
|
+
private
|
411
|
+
|
412
|
+
def can_forward_all?
|
413
|
+
return false if any_arg_referenced?
|
414
|
+
return false if ruby_32_missing_rest_or_kwest?
|
415
|
+
return false unless offensive_block_forwarding?
|
416
|
+
return false if additional_kwargs_or_forwarded_kwargs?
|
417
|
+
|
418
|
+
no_additional_args? || (target_ruby_version >= 3.0 && no_post_splat_args?)
|
419
|
+
end
|
420
|
+
|
421
|
+
def ruby_32_missing_rest_or_kwest?
|
422
|
+
target_ruby_version >= 3.2 && !forwarded_rest_and_kwrest_args
|
423
|
+
end
|
424
|
+
|
425
|
+
def offensive_block_forwarding?
|
426
|
+
@block_arg ? forwarded_block_arg : allow_offense_for_no_block?
|
427
|
+
end
|
428
|
+
|
429
|
+
def forwarded_rest_and_kwrest_args
|
430
|
+
forwarded_rest_arg && forwarded_kwrest_arg
|
431
|
+
end
|
432
|
+
|
433
|
+
def arguments
|
434
|
+
@send_node.arguments
|
435
|
+
end
|
436
|
+
|
437
|
+
def referenced_rest_arg?
|
438
|
+
@referenced_lvars.include?(@rest_arg_name)
|
439
|
+
end
|
440
|
+
|
441
|
+
def referenced_kwrest_arg?
|
442
|
+
@referenced_lvars.include?(@kwrest_arg_name)
|
443
|
+
end
|
444
|
+
|
445
|
+
def referenced_block_arg?
|
446
|
+
@referenced_lvars.include?(@block_arg_name)
|
447
|
+
end
|
448
|
+
|
449
|
+
def any_arg_referenced?
|
450
|
+
referenced_rest_arg? || referenced_kwrest_arg? || referenced_block_arg?
|
451
|
+
end
|
452
|
+
|
453
|
+
def target_ruby_version
|
454
|
+
@config.fetch(:target_ruby_version)
|
455
|
+
end
|
456
|
+
|
457
|
+
def no_post_splat_args?
|
458
|
+
return true unless (splat_index = arguments.index(forwarded_rest_arg))
|
459
|
+
|
460
|
+
arg_after_splat = arguments[splat_index + 1]
|
461
|
+
[nil, :hash, :block_pass].include?(arg_after_splat&.type)
|
462
|
+
end
|
463
|
+
|
464
|
+
def additional_kwargs_or_forwarded_kwargs?
|
465
|
+
additional_kwargs? || forward_additional_kwargs?
|
466
|
+
end
|
467
|
+
|
468
|
+
def additional_kwargs?
|
469
|
+
@def_node.arguments.any? { |a| a.kwarg_type? || a.kwoptarg_type? }
|
470
|
+
end
|
471
|
+
|
472
|
+
def forward_additional_kwargs?
|
473
|
+
return false unless forwarded_kwrest_arg
|
474
|
+
|
475
|
+
!forwarded_kwrest_arg.parent.children.one?
|
476
|
+
end
|
477
|
+
|
478
|
+
def allow_offense_for_no_block?
|
479
|
+
!@config.fetch(:allow_only_rest_arguments)
|
480
|
+
end
|
481
|
+
|
482
|
+
def no_additional_args?
|
483
|
+
forwardable_count = [@rest_arg, @kwrest_arg, @block_arg].compact.size
|
484
|
+
|
485
|
+
return false if missing_rest_arg_or_kwrest_arg?
|
486
|
+
|
487
|
+
@def_node.arguments.size == forwardable_count &&
|
488
|
+
@send_node.arguments.size == forwardable_count
|
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'
|
502
|
+
end
|
151
503
|
end
|
152
504
|
end
|
153
505
|
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
|
@@ -11,8 +11,17 @@ module RuboCop
|
|
11
11
|
# The `array1.intersect?(array2)` method is faster than
|
12
12
|
# `(array1 & array2).any?` and is more readable.
|
13
13
|
#
|
14
|
+
# In cases like the following, compatibility is not ensured,
|
15
|
+
# so it will not be detected when using block argument.
|
16
|
+
#
|
17
|
+
# [source,ruby]
|
18
|
+
# ----
|
19
|
+
# ([1] & [1,2]).any? { |x| false } # => false
|
20
|
+
# [1].intersect?([1,2]) { |x| false } # => true
|
21
|
+
# ----
|
22
|
+
#
|
14
23
|
# @safety
|
15
|
-
# This cop cannot guarantee that array1 and array2 are
|
24
|
+
# This cop cannot guarantee that `array1` and `array2` are
|
16
25
|
# actually arrays while method `intersect?` is for arrays only.
|
17
26
|
#
|
18
27
|
# @example
|
@@ -68,16 +77,15 @@ module RuboCop
|
|
68
77
|
RESTRICT_ON_SEND = (STRAIGHT_METHODS + NEGATED_METHODS).freeze
|
69
78
|
|
70
79
|
def on_send(node)
|
80
|
+
return if (parent = node.parent) && (parent.block_type? || parent.numblock_type?)
|
71
81
|
return unless (receiver, argument, method_name = bad_intersection_check?(node))
|
72
82
|
|
73
83
|
message = message(receiver.source, argument.source, method_name)
|
74
84
|
|
75
85
|
add_offense(node, message: message) do |corrector|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
corrector.replace(node, "!#{receiver.source}.intersect?(#{argument.source})")
|
80
|
-
end
|
86
|
+
bang = straight?(method_name) ? '' : '!'
|
87
|
+
|
88
|
+
corrector.replace(node, "#{bang}#{receiver.source}.intersect?(#{argument.source})")
|
81
89
|
end
|
82
90
|
end
|
83
91
|
|
@@ -30,7 +30,7 @@ module RuboCop
|
|
30
30
|
private
|
31
31
|
|
32
32
|
def first_offense_range(comment)
|
33
|
-
expression = comment.
|
33
|
+
expression = comment.source_range
|
34
34
|
first_offense = first_non_ascii_chars(comment.text)
|
35
35
|
|
36
36
|
start_position = expression.begin_pos + comment.text.index(first_offense)
|
@@ -24,7 +24,7 @@ module RuboCop
|
|
24
24
|
def on_send(node)
|
25
25
|
return unless node.command?(:attr) && node.arguments?
|
26
26
|
# check only for method definitions in class/module body
|
27
|
-
return if
|
27
|
+
return if allowed_context?(node)
|
28
28
|
|
29
29
|
message = message(node)
|
30
30
|
add_offense(node.loc.selector, message: message) do |corrector|
|
@@ -34,6 +34,16 @@ module RuboCop
|
|
34
34
|
|
35
35
|
private
|
36
36
|
|
37
|
+
def allowed_context?(node)
|
38
|
+
return false unless (class_node = node.each_ancestor(:class, :block).first)
|
39
|
+
|
40
|
+
(!class_node.class_type? && !class_eval?(class_node)) || define_attr_method?(class_node)
|
41
|
+
end
|
42
|
+
|
43
|
+
def define_attr_method?(node)
|
44
|
+
node.each_descendant(:def).any? { |def_node| def_node.method?(:attr) }
|
45
|
+
end
|
46
|
+
|
37
47
|
def autocorrect(corrector, node)
|
38
48
|
attr_name, setter = *node.arguments
|
39
49
|
|