rubocop 1.71.1 → 1.92.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 +23 -19
- data/config/default.yml +885 -168
- data/config/internal_affairs.yml +20 -0
- data/config/obsoletion.yml +47 -4
- data/exe/rubocop +2 -9
- data/lib/rubocop/cache_config.rb +29 -0
- data/lib/rubocop/cached_data.rb +50 -5
- data/lib/rubocop/changed_files.rb +134 -0
- data/lib/rubocop/cli/command/auto_generate_config.rb +36 -4
- data/lib/rubocop/cli/command/cop_names.rb +57 -0
- data/lib/rubocop/cli/command/execute_runner.rb +54 -3
- data/lib/rubocop/cli/command/explain.rb +34 -0
- data/lib/rubocop/cli/command/list_enabled_cops_for.rb +40 -0
- data/lib/rubocop/cli/command/lsp.rb +1 -1
- data/lib/rubocop/cli/command/mcp.rb +19 -0
- data/lib/rubocop/cli/command/show_cops.rb +8 -2
- data/lib/rubocop/cli/command/show_docs_url.rb +8 -10
- data/lib/rubocop/cli/command/suggest_extensions.rb +8 -2
- data/lib/rubocop/cli.rb +59 -17
- data/lib/rubocop/comment_config/directive_range.rb +34 -0
- data/lib/rubocop/comment_config/disable_next.rb +143 -0
- data/lib/rubocop/comment_config/push_pop.rb +55 -0
- data/lib/rubocop/comment_config.rb +98 -45
- data/lib/rubocop/config.rb +137 -19
- data/lib/rubocop/config_finder.rb +1 -1
- data/lib/rubocop/config_loader.rb +75 -49
- data/lib/rubocop/config_loader_resolver.rb +124 -33
- data/lib/rubocop/config_obsoletion/cop_rule.rb +2 -1
- data/lib/rubocop/config_obsoletion/extracted_cop.rb +6 -3
- data/lib/rubocop/config_obsoletion/removed_cop.rb +9 -1
- data/lib/rubocop/config_obsoletion/renamed_cop.rb +18 -3
- data/lib/rubocop/config_obsoletion.rb +47 -3
- data/lib/rubocop/config_store.rb +7 -2
- data/lib/rubocop/config_validator.rb +75 -12
- data/lib/rubocop/cop/autocorrect_logic.rb +43 -17
- data/lib/rubocop/cop/badge.rb +9 -1
- data/lib/rubocop/cop/base.rb +128 -35
- data/lib/rubocop/cop/bundler/gem_comment.rb +5 -4
- data/lib/rubocop/cop/bundler/gem_version.rb +28 -28
- data/lib/rubocop/cop/bundler/ordered_gems.rb +2 -11
- data/lib/rubocop/cop/bundler.rb +19 -0
- data/lib/rubocop/cop/commissioner.rb +13 -11
- data/lib/rubocop/cop/cop_documentation.rb +81 -0
- data/lib/rubocop/cop/cop_explanation.rb +140 -0
- data/lib/rubocop/cop/corrector.rb +4 -4
- data/lib/rubocop/cop/correctors/alignment_corrector.rb +92 -11
- data/lib/rubocop/cop/correctors/condition_corrector.rb +1 -1
- data/lib/rubocop/cop/correctors/each_to_for_corrector.rb +22 -7
- data/lib/rubocop/cop/correctors/empty_line_corrector.rb +1 -1
- data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +7 -2
- data/lib/rubocop/cop/correctors/lambda_literal_to_method_corrector.rb +29 -2
- data/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +1 -5
- data/lib/rubocop/cop/correctors/ordered_gem_corrector.rb +8 -1
- data/lib/rubocop/cop/correctors/parentheses_corrector.rb +73 -2
- data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +2 -2
- data/lib/rubocop/cop/correctors.rb +28 -0
- data/lib/rubocop/cop/documentation.rb +3 -4
- data/lib/rubocop/cop/exclude_limit.rb +31 -5
- data/lib/rubocop/cop/gemspec/attribute_assignment.rb +91 -0
- data/lib/rubocop/cop/gemspec/dependency_version.rb +0 -6
- data/lib/rubocop/cop/gemspec/development_dependencies.rb +1 -1
- data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +49 -17
- data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +2 -9
- data/lib/rubocop/cop/gemspec/require_mfa.rb +22 -5
- data/lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb +12 -7
- data/lib/rubocop/cop/gemspec.rb +22 -0
- data/lib/rubocop/cop/generator/registration_injector.rb +188 -0
- data/lib/rubocop/cop/generator.rb +5 -1
- data/lib/rubocop/cop/internal_affairs/example_description.rb +9 -5
- data/lib/rubocop/cop/internal_affairs/example_heredoc_delimiter.rb +8 -8
- data/lib/rubocop/cop/internal_affairs/itblock_handler.rb +69 -0
- data/lib/rubocop/cop/internal_affairs/location_exists.rb +142 -0
- data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +1 -0
- data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +16 -20
- data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_processor.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_walker.rb +1 -2
- data/lib/rubocop/cop/internal_affairs/node_pattern_groups.rb +6 -2
- data/lib/rubocop/cop/internal_affairs/node_type_group.rb +85 -0
- data/lib/rubocop/cop/internal_affairs/on_send_without_on_csend.rb +2 -2
- data/lib/rubocop/cop/internal_affairs/plugin.rb +33 -0
- data/lib/rubocop/cop/internal_affairs/redundant_context_config_parameter.rb +1 -7
- data/lib/rubocop/cop/internal_affairs/redundant_described_class_as_subject.rb +6 -5
- data/lib/rubocop/cop/internal_affairs/redundant_let_rubocop_config_new.rb +5 -3
- data/lib/rubocop/cop/internal_affairs/style_detected_api_use.rb +1 -7
- data/lib/rubocop/cop/internal_affairs/undefined_config.rb +13 -2
- data/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +4 -4
- data/lib/rubocop/cop/internal_affairs/useless_restrict_on_send.rb +1 -1
- data/lib/rubocop/cop/internal_affairs.rb +3 -16
- data/lib/rubocop/cop/layout/argument_alignment.rb +4 -2
- data/lib/rubocop/cop/layout/array_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/begin_end_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/block_alignment.rb +86 -4
- data/lib/rubocop/cop/layout/block_end_newline.rb +1 -0
- data/lib/rubocop/cop/layout/case_indentation.rb +28 -10
- data/lib/rubocop/cop/layout/class_structure.rb +172 -36
- data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +5 -5
- data/lib/rubocop/cop/layout/comment_indentation.rb +17 -7
- data/lib/rubocop/cop/layout/condition_position.rb +13 -3
- data/lib/rubocop/cop/layout/def_end_alignment.rb +5 -1
- data/lib/rubocop/cop/layout/dot_position.rb +2 -2
- data/lib/rubocop/cop/layout/else_alignment.rb +3 -15
- data/lib/rubocop/cop/layout/empty_comment.rb +8 -10
- data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +27 -9
- data/lib/rubocop/cop/layout/empty_line_after_magic_comment.rb +63 -5
- data/lib/rubocop/cop/layout/empty_line_after_multiline_condition.rb +14 -5
- data/lib/rubocop/cop/layout/empty_line_between_defs.rb +46 -21
- data/lib/rubocop/cop/layout/empty_lines.rb +5 -2
- data/lib/rubocop/cop/layout/empty_lines_after_module_inclusion.rb +101 -0
- data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +34 -4
- data/lib/rubocop/cop/layout/empty_lines_around_arguments.rb +8 -29
- data/lib/rubocop/cop/layout/empty_lines_around_attribute_accessor.rb +2 -0
- data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +14 -3
- data/lib/rubocop/cop/layout/empty_lines_around_class_body.rb +17 -3
- data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +23 -1
- data/lib/rubocop/cop/layout/empty_lines_around_method_body.rb +22 -2
- data/lib/rubocop/cop/layout/empty_lines_around_module_body.rb +16 -2
- data/lib/rubocop/cop/layout/end_alignment.rb +20 -8
- data/lib/rubocop/cop/layout/extra_spacing.rb +109 -3
- data/lib/rubocop/cop/layout/first_argument_indentation.rb +57 -3
- data/lib/rubocop/cop/layout/first_array_element_indentation.rb +18 -5
- data/lib/rubocop/cop/layout/first_array_element_line_break.rb +26 -0
- data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +25 -18
- data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +25 -25
- data/lib/rubocop/cop/layout/first_method_argument_line_break.rb +6 -0
- data/lib/rubocop/cop/layout/first_method_parameter_line_break.rb +4 -0
- data/lib/rubocop/cop/layout/first_parameter_indentation.rb +11 -0
- data/lib/rubocop/cop/layout/hash_alignment.rb +20 -18
- data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +5 -3
- data/lib/rubocop/cop/layout/heredoc_indentation.rb +48 -3
- data/lib/rubocop/cop/layout/indentation_style.rb +5 -2
- data/lib/rubocop/cop/layout/indentation_width.rb +159 -12
- data/lib/rubocop/cop/layout/leading_comment_space.rb +40 -1
- data/lib/rubocop/cop/layout/line_continuation_spacing.rb +10 -4
- data/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb +25 -9
- data/lib/rubocop/cop/layout/line_length.rb +201 -30
- data/lib/rubocop/cop/layout/multiline_array_brace_layout.rb +69 -57
- data/lib/rubocop/cop/layout/multiline_assignment_layout.rb +8 -2
- data/lib/rubocop/cop/layout/multiline_block_layout.rb +11 -1
- data/lib/rubocop/cop/layout/multiline_hash_brace_layout.rb +63 -56
- data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +7 -1
- data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +259 -40
- data/lib/rubocop/cop/layout/multiline_method_definition_brace_layout.rb +4 -0
- data/lib/rubocop/cop/layout/multiline_method_parameter_line_breaks.rb +1 -0
- data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +9 -5
- data/lib/rubocop/cop/layout/parameter_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/redundant_line_break.rb +111 -7
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +29 -9
- data/lib/rubocop/cop/layout/single_line_block_chain.rb +10 -2
- data/lib/rubocop/cop/layout/space_after_comma.rb +2 -10
- data/lib/rubocop/cop/layout/space_after_not.rb +5 -0
- data/lib/rubocop/cop/layout/space_after_semicolon.rb +11 -1
- data/lib/rubocop/cop/layout/space_around_block_parameters.rb +10 -4
- data/lib/rubocop/cop/layout/space_around_keyword.rb +20 -3
- data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +1 -1
- data/lib/rubocop/cop/layout/space_around_operators.rb +30 -4
- data/lib/rubocop/cop/layout/space_before_block_braces.rb +5 -1
- data/lib/rubocop/cop/layout/space_before_brackets.rb +6 -39
- data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +9 -8
- data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +55 -36
- data/lib/rubocop/cop/layout/space_inside_block_braces.rb +32 -8
- data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +3 -0
- data/lib/rubocop/cop/layout/trailing_whitespace.rb +1 -1
- data/lib/rubocop/cop/layout.rb +114 -0
- data/lib/rubocop/cop/lazy_loader.rb +41 -0
- data/lib/rubocop/cop/lint/ambiguous_assignment.rb +9 -17
- data/lib/rubocop/cop/lint/ambiguous_block_association.rb +72 -1
- data/lib/rubocop/cop/lint/ambiguous_operator.rb +1 -1
- data/lib/rubocop/cop/lint/ambiguous_operator_precedence.rb +3 -11
- data/lib/rubocop/cop/lint/ambiguous_range.rb +6 -2
- data/lib/rubocop/cop/lint/argument_mismatch.rb +99 -0
- data/lib/rubocop/cop/lint/array_literal_in_regexp.rb +2 -3
- data/lib/rubocop/cop/lint/assignment_in_condition.rb +15 -1
- data/lib/rubocop/cop/lint/boolean_symbol.rb +1 -1
- data/lib/rubocop/cop/lint/circular_argument_reference.rb +47 -8
- data/lib/rubocop/cop/lint/constant_overwritten_in_rescue.rb +4 -3
- data/lib/rubocop/cop/lint/constant_reassignment.rb +94 -15
- data/lib/rubocop/cop/lint/constant_resolution.rb +31 -6
- data/lib/rubocop/cop/lint/cop_directive_syntax.rb +240 -0
- data/lib/rubocop/cop/lint/data_define_override.rb +63 -0
- data/lib/rubocop/cop/lint/debugger.rb +13 -4
- data/lib/rubocop/cop/lint/deprecated_class_methods.rb +1 -1
- data/lib/rubocop/cop/lint/deprecated_constants.rb +2 -8
- data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +5 -2
- data/lib/rubocop/cop/lint/deprecated_reference.rb +194 -0
- data/lib/rubocop/cop/lint/duplicate_match_pattern.rb +4 -4
- data/lib/rubocop/cop/lint/duplicate_methods.rb +506 -41
- data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +5 -42
- data/lib/rubocop/cop/lint/else_layout.rb +19 -0
- data/lib/rubocop/cop/lint/empty_block.rb +4 -4
- data/lib/rubocop/cop/lint/empty_conditional_body.rb +22 -65
- data/lib/rubocop/cop/lint/empty_expression.rb +0 -2
- data/lib/rubocop/cop/lint/empty_in_pattern.rb +8 -1
- data/lib/rubocop/cop/lint/empty_interpolation.rb +14 -1
- data/lib/rubocop/cop/lint/empty_when.rb +8 -1
- data/lib/rubocop/cop/lint/ensure_return.rb +19 -1
- data/lib/rubocop/cop/lint/erb_new_arguments.rb +4 -8
- data/lib/rubocop/cop/lint/float_comparison.rb +33 -10
- data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +1 -1
- data/lib/rubocop/cop/lint/identity_comparison.rb +19 -15
- data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +1 -2
- data/lib/rubocop/cop/lint/incompatible_io_select_with_fiber_scheduler.rb +5 -1
- data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +1 -2
- data/lib/rubocop/cop/lint/inherit_exception.rb +53 -7
- data/lib/rubocop/cop/lint/interpolation_check.rb +25 -6
- data/lib/rubocop/cop/lint/lambda_without_literal_block.rb +1 -1
- data/lib/rubocop/cop/lint/literal_as_condition.rb +152 -11
- data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +11 -1
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +75 -37
- data/lib/rubocop/cop/lint/loop.rb +24 -2
- data/lib/rubocop/cop/lint/misplaced_magic_comment.rb +245 -0
- data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +60 -23
- data/lib/rubocop/cop/lint/missing_super.rb +31 -1
- data/lib/rubocop/cop/lint/mixed_case_range.rb +2 -2
- data/lib/rubocop/cop/lint/multiple_comparison.rb +2 -2
- data/lib/rubocop/cop/lint/name_typo.rb +270 -0
- data/lib/rubocop/cop/lint/nested_method_definition.rb +2 -2
- data/lib/rubocop/cop/lint/next_without_accumulator.rb +2 -0
- data/lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +20 -0
- data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +4 -2
- data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +4 -4
- data/lib/rubocop/cop/lint/number_conversion.rb +20 -11
- data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +1 -1
- data/lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +11 -0
- data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +1 -1
- data/lib/rubocop/cop/lint/ordered_magic_comments.rb +7 -7
- data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +15 -4
- data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +20 -14
- data/lib/rubocop/cop/lint/raise_exception.rb +30 -11
- data/lib/rubocop/cop/lint/rand_one.rb +1 -1
- data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +160 -39
- data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +53 -19
- data/lib/rubocop/cop/lint/redundant_dir_glob_sort.rb +28 -6
- data/lib/rubocop/cop/lint/redundant_regexp_quantifiers.rb +1 -1
- data/lib/rubocop/cop/lint/redundant_require_statement.rb +5 -25
- data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +134 -12
- data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +13 -4
- data/lib/rubocop/cop/lint/redundant_type_conversion.rb +267 -0
- data/lib/rubocop/cop/lint/redundant_with_index.rb +5 -3
- data/lib/rubocop/cop/lint/redundant_with_object.rb +8 -0
- data/lib/rubocop/cop/lint/refinement_import_methods.rb +8 -1
- data/lib/rubocop/cop/lint/regexp_as_condition.rb +9 -1
- data/lib/rubocop/cop/lint/require_parentheses.rb +13 -4
- data/lib/rubocop/cop/lint/require_range_parentheses.rb +3 -2
- data/lib/rubocop/cop/lint/require_relative_self_path.rb +7 -5
- data/lib/rubocop/cop/lint/rescue_exception.rb +1 -4
- data/lib/rubocop/cop/lint/rescue_type.rb +2 -2
- data/lib/rubocop/cop/lint/return_in_void_context.rb +9 -11
- data/lib/rubocop/cop/lint/safe_navigation_chain.rb +28 -4
- data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +9 -5
- data/lib/rubocop/cop/lint/safe_navigation_with_empty.rb +1 -1
- data/lib/rubocop/cop/lint/script_permission.rb +5 -1
- data/lib/rubocop/cop/lint/self_assignment.rb +63 -6
- data/lib/rubocop/cop/lint/send_with_mixin_argument.rb +1 -1
- data/lib/rubocop/cop/lint/shadowed_argument.rb +7 -7
- data/lib/rubocop/cop/lint/shadowed_exception.rb +1 -1
- data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +27 -1
- data/lib/rubocop/cop/lint/shared_mutable_default.rb +14 -1
- data/lib/rubocop/cop/lint/struct_new_override.rb +17 -1
- data/lib/rubocop/cop/lint/super_argument_mismatch.rb +179 -0
- data/lib/rubocop/cop/lint/suppressed_exception.rb +1 -1
- data/lib/rubocop/cop/lint/suppressed_exception_in_number_conversion.rb +122 -0
- data/lib/rubocop/cop/lint/symbol_conversion.rb +21 -4
- data/lib/rubocop/cop/lint/syntax.rb +25 -1
- data/lib/rubocop/cop/lint/to_enum_arguments.rb +73 -5
- data/lib/rubocop/cop/lint/to_json.rb +20 -17
- data/lib/rubocop/cop/lint/top_level_return_with_argument.rb +1 -1
- data/lib/rubocop/cop/lint/trailing_comma_in_attribute_declaration.rb +5 -1
- data/lib/rubocop/cop/lint/unescaped_bracket_in_regexp.rb +54 -11
- data/lib/rubocop/cop/lint/unexpected_block_arity.rb +2 -0
- data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +2 -1
- data/lib/rubocop/cop/lint/unreachable_code.rb +16 -9
- data/lib/rubocop/cop/lint/unreachable_loop.rb +5 -5
- data/lib/rubocop/cop/lint/unreachable_pattern_branch.rb +113 -0
- data/lib/rubocop/cop/lint/unused_method_argument.rb +10 -0
- data/lib/rubocop/cop/lint/unused_private_method.rb +234 -0
- data/lib/rubocop/cop/lint/uri_escape_unescape.rb +2 -0
- data/lib/rubocop/cop/lint/useless_access_modifier.rb +31 -6
- data/lib/rubocop/cop/lint/useless_assignment.rb +63 -27
- data/lib/rubocop/cop/lint/useless_constant_scoping.rb +107 -0
- data/lib/rubocop/cop/lint/useless_default_value_argument.rb +92 -0
- data/lib/rubocop/cop/lint/useless_method_definition.rb +1 -1
- data/lib/rubocop/cop/lint/useless_numeric_operation.rb +11 -10
- data/lib/rubocop/cop/lint/useless_or.rb +111 -0
- data/lib/rubocop/cop/lint/useless_rescue.rb +2 -3
- data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +13 -7
- data/lib/rubocop/cop/lint/useless_setter_call.rb +4 -1
- data/lib/rubocop/cop/lint/useless_times.rb +22 -1
- data/lib/rubocop/cop/lint/utils/nil_receiver_checker.rb +201 -0
- data/lib/rubocop/cop/lint/void.rb +68 -22
- data/lib/rubocop/cop/lint.rb +179 -0
- data/lib/rubocop/cop/message_annotator.rb +7 -3
- data/lib/rubocop/cop/metrics/abc_size.rb +1 -1
- data/lib/rubocop/cop/metrics/block_length.rb +2 -1
- data/lib/rubocop/cop/metrics/block_nesting.rb +23 -0
- data/lib/rubocop/cop/metrics/class_length.rb +4 -2
- data/lib/rubocop/cop/metrics/collection_literal_length.rb +1 -1
- data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +0 -4
- data/lib/rubocop/cop/metrics/method_length.rb +3 -2
- data/lib/rubocop/cop/metrics/module_length.rb +4 -2
- data/lib/rubocop/cop/metrics/perceived_complexity.rb +37 -7
- data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +4 -3
- data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +2 -2
- data/lib/rubocop/cop/metrics/utils/iterating_block.rb +1 -1
- data/lib/rubocop/cop/metrics/utils/repeated_attribute_discount.rb +7 -7
- data/lib/rubocop/cop/metrics.rb +31 -0
- data/lib/rubocop/cop/migration/department_name.rb +11 -5
- data/lib/rubocop/cop/migration.rb +13 -0
- data/lib/rubocop/cop/mixin/alignment.rb +7 -3
- data/lib/rubocop/cop/mixin/allowed_methods.rb +5 -5
- data/lib/rubocop/cop/mixin/allowed_pattern.rb +9 -5
- data/lib/rubocop/cop/mixin/annotation_comment.rb +1 -1
- data/lib/rubocop/cop/mixin/check_line_breakable.rb +44 -23
- data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +10 -8
- data/lib/rubocop/cop/mixin/code_length.rb +10 -2
- data/lib/rubocop/cop/mixin/comments_help.rb +2 -3
- data/lib/rubocop/cop/mixin/configurable_enforced_style.rb +1 -2
- data/lib/rubocop/cop/mixin/configurable_max.rb +6 -5
- data/lib/rubocop/cop/mixin/def_node.rb +1 -1
- data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +13 -2
- data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +1 -7
- data/lib/rubocop/cop/mixin/endless_method_body_help.rb +69 -0
- data/lib/rubocop/cop/mixin/endless_method_rewriter.rb +13 -5
- data/lib/rubocop/cop/mixin/forbidden_identifiers.rb +20 -0
- data/lib/rubocop/cop/mixin/forbidden_pattern.rb +20 -0
- data/lib/rubocop/cop/mixin/frozen_string_literal.rb +1 -2
- data/lib/rubocop/cop/mixin/gemspec_help.rb +22 -0
- data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +59 -17
- data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +52 -25
- data/lib/rubocop/cop/mixin/hash_subset.rb +28 -6
- data/lib/rubocop/cop/mixin/hash_transform_method/autocorrection.rb +63 -0
- data/lib/rubocop/cop/mixin/hash_transform_method.rb +32 -78
- data/lib/rubocop/cop/mixin/indexed_method_arity.rb +94 -0
- data/lib/rubocop/cop/mixin/line_length_help.rb +52 -11
- data/lib/rubocop/cop/mixin/method_complexity.rb +2 -1
- data/lib/rubocop/cop/mixin/min_branches_count.rb +3 -1
- data/lib/rubocop/cop/mixin/multiline_element_line_breaks.rb +11 -1
- data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +3 -1
- data/lib/rubocop/cop/mixin/multiline_literal_brace_layout.rb +10 -1
- data/lib/rubocop/cop/mixin/ordered_gem_node.rb +2 -2
- data/lib/rubocop/cop/mixin/pattern_matching_help.rb +35 -0
- data/lib/rubocop/cop/mixin/percent_literal.rb +1 -1
- data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +79 -8
- data/lib/rubocop/cop/mixin/project_index_help.rb +203 -0
- data/lib/rubocop/cop/mixin/range_help.rb +16 -5
- data/lib/rubocop/cop/mixin/reparsed_equivalence.rb +181 -0
- data/lib/rubocop/cop/mixin/space_after_punctuation.rb +5 -4
- data/lib/rubocop/cop/mixin/statement_modifier.rb +66 -10
- data/lib/rubocop/cop/mixin/string_help.rb +1 -1
- data/lib/rubocop/cop/mixin/target_ruby_version.rb +1 -1
- data/lib/rubocop/cop/mixin/trailing_comma.rb +23 -6
- data/lib/rubocop/cop/mixin.rb +93 -0
- data/lib/rubocop/cop/naming/accessor_method_name.rb +8 -0
- data/lib/rubocop/cop/naming/binary_operator_parameter_name.rb +17 -1
- data/lib/rubocop/cop/naming/block_forwarding.rb +7 -4
- data/lib/rubocop/cop/naming/block_parameter_name.rb +1 -1
- data/lib/rubocop/cop/naming/file_name.rb +6 -5
- data/lib/rubocop/cop/naming/heredoc_delimiter_case.rb +9 -2
- data/lib/rubocop/cop/naming/heredoc_delimiter_naming.rb +5 -3
- data/lib/rubocop/cop/naming/inclusive_language.rb +8 -2
- data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +13 -6
- data/lib/rubocop/cop/naming/method_name.rb +190 -15
- data/lib/rubocop/cop/naming/predicate_method.rb +330 -0
- data/lib/rubocop/cop/naming/{predicate_name.rb → predicate_prefix.rb} +65 -8
- data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +11 -6
- data/lib/rubocop/cop/naming/variable_name.rb +51 -6
- data/lib/rubocop/cop/naming/variable_number.rb +3 -1
- data/lib/rubocop/cop/naming.rb +31 -0
- data/lib/rubocop/cop/offense.rb +108 -9
- data/lib/rubocop/cop/registry.rb +234 -65
- data/lib/rubocop/cop/security/eval.rb +17 -3
- data/lib/rubocop/cop/security/io_methods.rb +2 -2
- data/lib/rubocop/cop/security/json_load.rb +45 -11
- data/lib/rubocop/cop/security/marshal_load.rb +1 -1
- data/lib/rubocop/cop/security/open.rb +1 -0
- data/lib/rubocop/cop/security.rb +19 -0
- data/lib/rubocop/cop/severity.rb +12 -0
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +54 -13
- data/lib/rubocop/cop/style/accessor_grouping.rb +47 -10
- data/lib/rubocop/cop/style/alias.rb +33 -8
- data/lib/rubocop/cop/style/ambiguous_endless_method_definition.rb +4 -3
- data/lib/rubocop/cop/style/and_or.rb +6 -1
- data/lib/rubocop/cop/style/arguments_forwarding.rb +52 -37
- data/lib/rubocop/cop/style/array_first_last.rb +13 -3
- data/lib/rubocop/cop/style/array_intersect.rb +136 -38
- data/lib/rubocop/cop/style/array_intersect_with_single_element.rb +50 -0
- data/lib/rubocop/cop/style/array_join.rb +4 -2
- data/lib/rubocop/cop/style/ascii_comments.rb +6 -3
- data/lib/rubocop/cop/style/attr.rb +8 -6
- data/lib/rubocop/cop/style/bare_percent_literals.rb +4 -3
- data/lib/rubocop/cop/style/begin_block.rb +3 -1
- data/lib/rubocop/cop/style/bitwise_predicate.rb +13 -5
- data/lib/rubocop/cop/style/block_delimiters.rb +71 -40
- data/lib/rubocop/cop/style/case_equality.rb +29 -15
- data/lib/rubocop/cop/style/case_like_if.rb +12 -11
- data/lib/rubocop/cop/style/character_literal.rb +2 -2
- data/lib/rubocop/cop/style/class_and_module_children.rb +179 -27
- data/lib/rubocop/cop/style/class_equality_comparison.rb +22 -14
- data/lib/rubocop/cop/style/class_methods_definitions.rb +19 -5
- data/lib/rubocop/cop/style/collection_compact.rb +37 -17
- data/lib/rubocop/cop/style/collection_methods.rb +1 -0
- data/lib/rubocop/cop/style/collection_querying.rb +167 -0
- data/lib/rubocop/cop/style/colon_method_call.rb +16 -7
- data/lib/rubocop/cop/style/combinable_loops.rb +88 -9
- data/lib/rubocop/cop/style/command_literal.rb +1 -1
- data/lib/rubocop/cop/style/commented_keyword.rb +12 -5
- data/lib/rubocop/cop/style/comparable_between.rb +78 -0
- data/lib/rubocop/cop/style/comparable_clamp.rb +12 -1
- data/lib/rubocop/cop/style/concat_array_literals.rb +53 -9
- data/lib/rubocop/cop/style/conditional_assignment.rb +58 -24
- data/lib/rubocop/cop/style/constant_visibility.rb +23 -12
- data/lib/rubocop/cop/style/copyright.rb +27 -12
- data/lib/rubocop/cop/style/data_inheritance.rb +25 -0
- data/lib/rubocop/cop/style/date_time.rb +4 -4
- data/lib/rubocop/cop/style/def_with_parentheses.rb +22 -5
- data/lib/rubocop/cop/style/dig_chain.rb +6 -1
- data/lib/rubocop/cop/style/dir_empty.rb +4 -0
- data/lib/rubocop/cop/style/directive_scope.rb +304 -0
- data/lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb +184 -20
- data/lib/rubocop/cop/style/document_dynamic_eval_definition.rb +6 -1
- data/lib/rubocop/cop/style/documentation.rb +53 -6
- data/lib/rubocop/cop/style/documentation_method.rb +8 -12
- data/lib/rubocop/cop/style/double_negation.rb +14 -3
- data/lib/rubocop/cop/style/each_for_simple_loop.rb +1 -1
- data/lib/rubocop/cop/style/each_with_object.rb +4 -3
- data/lib/rubocop/cop/style/empty_block_parameter.rb +1 -1
- data/lib/rubocop/cop/style/empty_case_condition.rb +13 -4
- data/lib/rubocop/cop/style/empty_class_definition.rb +126 -0
- data/lib/rubocop/cop/style/empty_heredoc.rb +4 -0
- data/lib/rubocop/cop/style/empty_lambda_parameter.rb +1 -1
- data/lib/rubocop/cop/style/empty_literal.rb +12 -3
- data/lib/rubocop/cop/style/empty_method.rb +15 -9
- data/lib/rubocop/cop/style/empty_string_inside_interpolation.rb +110 -0
- data/lib/rubocop/cop/style/encoding.rb +7 -1
- data/lib/rubocop/cop/style/end_block.rb +3 -1
- data/lib/rubocop/cop/style/endless_method.rb +252 -19
- data/lib/rubocop/cop/style/env_home.rb +4 -0
- data/lib/rubocop/cop/style/eval_with_location.rb +3 -3
- data/lib/rubocop/cop/style/even_odd.rb +11 -1
- data/lib/rubocop/cop/style/exact_regexp_match.rb +52 -8
- data/lib/rubocop/cop/style/expand_path_arguments.rb +2 -7
- data/lib/rubocop/cop/style/explicit_block_argument.rb +62 -9
- data/lib/rubocop/cop/style/exponential_notation.rb +5 -4
- data/lib/rubocop/cop/style/fetch_env_var.rb +33 -7
- data/lib/rubocop/cop/style/file_null.rb +6 -4
- data/lib/rubocop/cop/style/file_open.rb +84 -0
- data/lib/rubocop/cop/style/file_write.rb +21 -16
- data/lib/rubocop/cop/style/float_division.rb +43 -15
- data/lib/rubocop/cop/style/for.rb +48 -1
- data/lib/rubocop/cop/style/format_string.rb +44 -9
- data/lib/rubocop/cop/style/format_string_token.rb +86 -16
- data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +5 -3
- data/lib/rubocop/cop/style/global_std_stream.rb +3 -0
- data/lib/rubocop/cop/style/global_vars.rb +5 -2
- data/lib/rubocop/cop/style/guard_clause.rb +41 -24
- data/lib/rubocop/cop/style/hash_as_last_array_item.rb +27 -9
- data/lib/rubocop/cop/style/hash_conversion.rb +52 -16
- data/lib/rubocop/cop/style/hash_each_methods.rb +4 -4
- data/lib/rubocop/cop/style/hash_fetch_chain.rb +104 -0
- data/lib/rubocop/cop/style/hash_lookup_method.rb +128 -0
- data/lib/rubocop/cop/style/hash_slice.rb +16 -0
- data/lib/rubocop/cop/style/hash_syntax.rb +23 -6
- data/lib/rubocop/cop/style/hash_transform_keys.rb +19 -9
- data/lib/rubocop/cop/style/hash_transform_values.rb +19 -9
- data/lib/rubocop/cop/style/identical_conditional_branches.rb +39 -11
- data/lib/rubocop/cop/style/if_inside_else.rb +46 -21
- data/lib/rubocop/cop/style/if_unless_modifier.rb +90 -66
- data/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +19 -19
- data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +5 -2
- data/lib/rubocop/cop/style/if_with_semicolon.rb +61 -8
- data/lib/rubocop/cop/style/infinite_loop.rb +1 -1
- data/lib/rubocop/cop/style/inline_comment.rb +5 -2
- data/lib/rubocop/cop/style/inverse_methods.rb +34 -8
- data/lib/rubocop/cop/style/invertible_unless_condition.rb +27 -7
- data/lib/rubocop/cop/style/ip_addresses.rb +3 -4
- data/lib/rubocop/cop/style/it_assignment.rb +69 -12
- data/lib/rubocop/cop/style/it_block_parameter.rb +150 -0
- data/lib/rubocop/cop/style/keyword_arguments_merging.rb +4 -0
- data/lib/rubocop/cop/style/keyword_parameters_order.rb +23 -11
- data/lib/rubocop/cop/style/lambda.rb +30 -1
- data/lib/rubocop/cop/style/lambda_call.rb +31 -10
- data/lib/rubocop/cop/style/line_end_concatenation.rb +10 -4
- data/lib/rubocop/cop/style/magic_comment_format.rb +4 -4
- data/lib/rubocop/cop/style/map_compact_with_conditional_block.rb +11 -0
- data/lib/rubocop/cop/style/map_into_array.rb +6 -4
- data/lib/rubocop/cop/style/map_join.rb +123 -0
- data/lib/rubocop/cop/style/map_to_hash.rb +13 -5
- data/lib/rubocop/cop/style/map_to_set.rb +1 -3
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +75 -24
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/require_parentheses.rb +15 -2
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +58 -6
- data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +36 -8
- data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +2 -1
- data/lib/rubocop/cop/style/method_def_parentheses.rb +36 -8
- data/lib/rubocop/cop/style/min_max_comparison.rb +17 -6
- data/lib/rubocop/cop/style/missing_else.rb +7 -1
- data/lib/rubocop/cop/style/missing_respond_to_missing.rb +40 -7
- data/lib/rubocop/cop/style/mixin_usage.rb +1 -1
- data/lib/rubocop/cop/style/module_function.rb +4 -2
- data/lib/rubocop/cop/style/module_member_existence_check.rb +110 -0
- data/lib/rubocop/cop/style/multiline_block_chain.rb +2 -1
- data/lib/rubocop/cop/style/multiline_if_modifier.rb +47 -5
- data/lib/rubocop/cop/style/multiline_if_then.rb +10 -4
- data/lib/rubocop/cop/style/multiline_in_pattern_then.rb +7 -0
- data/lib/rubocop/cop/style/multiline_memoization.rb +7 -1
- data/lib/rubocop/cop/style/multiline_method_signature.rb +15 -22
- data/lib/rubocop/cop/style/multiline_ternary_operator.rb +7 -3
- data/lib/rubocop/cop/style/multiline_when_then.rb +7 -0
- data/lib/rubocop/cop/style/multiple_comparison.rb +33 -22
- data/lib/rubocop/cop/style/mutable_constant.rb +139 -13
- data/lib/rubocop/cop/style/negated_if_else_condition.rb +3 -3
- data/lib/rubocop/cop/style/negative_array_index.rb +228 -0
- data/lib/rubocop/cop/style/nested_modifier.rb +36 -12
- data/lib/rubocop/cop/style/nested_ternary_operator.rb +26 -8
- data/lib/rubocop/cop/style/next.rb +68 -10
- data/lib/rubocop/cop/style/nil_comparison.rb +53 -13
- data/lib/rubocop/cop/style/nil_lambda.rb +9 -1
- data/lib/rubocop/cop/style/non_nil_check.rb +21 -11
- data/lib/rubocop/cop/style/not.rb +12 -3
- data/lib/rubocop/cop/style/numeric_literal_prefix.rb +11 -1
- data/lib/rubocop/cop/style/numeric_literals.rb +3 -2
- data/lib/rubocop/cop/style/numeric_predicate.rb +22 -6
- data/lib/rubocop/cop/style/object_then.rb +1 -0
- data/lib/rubocop/cop/style/one_class_per_file.rb +115 -0
- data/lib/rubocop/cop/style/one_line_conditional.rb +35 -15
- data/lib/rubocop/cop/style/open_struct_use.rb +1 -1
- data/lib/rubocop/cop/style/operator_method_call.rb +10 -2
- data/lib/rubocop/cop/style/option_hash.rb +1 -1
- data/lib/rubocop/cop/style/optional_arguments.rb +1 -0
- data/lib/rubocop/cop/style/parallel_assignment.rb +58 -27
- data/lib/rubocop/cop/style/parentheses_around_condition.rb +6 -1
- data/lib/rubocop/cop/style/partition_instead_of_double_select.rb +270 -0
- data/lib/rubocop/cop/style/percent_literal_delimiters.rb +18 -3
- data/lib/rubocop/cop/style/percent_q_literals.rb +1 -1
- data/lib/rubocop/cop/style/perl_backrefs.rb +5 -3
- data/lib/rubocop/cop/style/predicate_with_kind.rb +84 -0
- data/lib/rubocop/cop/style/preferred_hash_methods.rb +12 -12
- data/lib/rubocop/cop/style/proc.rb +4 -2
- data/lib/rubocop/cop/style/raise_args.rb +9 -9
- data/lib/rubocop/cop/style/reduce_to_hash.rb +216 -0
- data/lib/rubocop/cop/style/redundant_argument.rb +2 -0
- data/lib/rubocop/cop/style/redundant_array_constructor.rb +2 -2
- data/lib/rubocop/cop/style/redundant_array_flatten.rb +50 -0
- data/lib/rubocop/cop/style/redundant_assignment.rb +12 -2
- data/lib/rubocop/cop/style/redundant_begin.rb +58 -6
- data/lib/rubocop/cop/style/redundant_condition.rb +93 -18
- data/lib/rubocop/cop/style/redundant_constant_base.rb +42 -6
- data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +26 -4
- data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +17 -3
- data/lib/rubocop/cop/style/redundant_each.rb +4 -5
- data/lib/rubocop/cop/style/redundant_exception.rb +22 -4
- data/lib/rubocop/cop/style/redundant_fetch_block.rb +11 -11
- data/lib/rubocop/cop/style/redundant_file_extension_in_require.rb +9 -0
- data/lib/rubocop/cop/style/redundant_filter_chain.rb +1 -1
- data/lib/rubocop/cop/style/redundant_format.rb +319 -0
- data/lib/rubocop/cop/style/redundant_freeze.rb +12 -3
- data/lib/rubocop/cop/style/redundant_heredoc_delimiter_quotes.rb +6 -1
- data/lib/rubocop/cop/style/redundant_interpolation.rb +12 -3
- data/lib/rubocop/cop/style/redundant_interpolation_unfreeze.rb +26 -10
- data/lib/rubocop/cop/style/redundant_line_continuation.rb +83 -119
- data/lib/rubocop/cop/style/redundant_min_max_by.rb +93 -0
- data/lib/rubocop/cop/style/redundant_parentheses.rb +176 -83
- data/lib/rubocop/cop/style/redundant_percent_q.rb +5 -3
- data/lib/rubocop/cop/style/redundant_regexp_argument.rb +15 -0
- data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +6 -5
- data/lib/rubocop/cop/style/redundant_regexp_constructor.rb +27 -7
- data/lib/rubocop/cop/style/redundant_regexp_escape.rb +16 -0
- data/lib/rubocop/cop/style/redundant_return.rb +4 -3
- data/lib/rubocop/cop/style/redundant_self.rb +20 -7
- data/lib/rubocop/cop/style/redundant_self_assignment.rb +2 -3
- data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +0 -5
- data/lib/rubocop/cop/style/redundant_sort.rb +7 -7
- data/lib/rubocop/cop/style/redundant_sort_by.rb +17 -1
- data/lib/rubocop/cop/style/redundant_string_escape.rb +1 -2
- data/lib/rubocop/cop/style/redundant_struct_keyword_init.rb +133 -0
- data/lib/rubocop/cop/style/regexp_literal.rb +107 -29
- data/lib/rubocop/cop/style/require_order.rb +9 -0
- data/lib/rubocop/cop/style/rescue_modifier.rb +10 -12
- data/lib/rubocop/cop/style/return_nil.rb +19 -4
- data/lib/rubocop/cop/style/return_nil_in_predicate_method_definition.rb +11 -1
- data/lib/rubocop/cop/style/reverse_find.rb +51 -0
- data/lib/rubocop/cop/style/safe_navigation.rb +76 -20
- data/lib/rubocop/cop/style/sample.rb +19 -13
- data/lib/rubocop/cop/style/select_by_kind.rb +158 -0
- data/lib/rubocop/cop/style/select_by_range.rb +197 -0
- data/lib/rubocop/cop/style/select_by_regexp.rb +54 -22
- data/lib/rubocop/cop/style/self_assignment.rb +13 -16
- data/lib/rubocop/cop/style/semicolon.rb +56 -14
- data/lib/rubocop/cop/style/single_line_block_params.rb +2 -2
- data/lib/rubocop/cop/style/single_line_do_end_block.rb +22 -8
- data/lib/rubocop/cop/style/single_line_methods.rb +28 -11
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +96 -104
- data/lib/rubocop/cop/style/special_global_vars.rb +7 -2
- data/lib/rubocop/cop/style/stabby_lambda_parentheses.rb +32 -6
- data/lib/rubocop/cop/style/static_class.rb +21 -0
- data/lib/rubocop/cop/style/string_concatenation.rb +38 -16
- data/lib/rubocop/cop/style/string_hash_keys.rb +1 -0
- data/lib/rubocop/cop/style/struct_inheritance.rb +38 -2
- data/lib/rubocop/cop/style/super_arguments.rb +7 -6
- data/lib/rubocop/cop/style/symbol_array.rb +1 -1
- data/lib/rubocop/cop/style/symbol_proc.rb +34 -14
- data/lib/rubocop/cop/style/tally_method.rb +181 -0
- data/lib/rubocop/cop/style/ternary_parentheses.rb +34 -1
- data/lib/rubocop/cop/style/time_now.rb +41 -0
- data/lib/rubocop/cop/style/top_level_method_definition.rb +3 -2
- data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +52 -1
- data/lib/rubocop/cop/style/trailing_comma_in_array_literal.rb +47 -6
- data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +2 -2
- data/lib/rubocop/cop/style/trailing_comma_in_hash_literal.rb +48 -6
- data/lib/rubocop/cop/style/trailing_method_end_statement.rb +1 -0
- data/lib/rubocop/cop/style/trailing_underscore_variable.rb +35 -32
- data/lib/rubocop/cop/style/trivial_accessors.rb +2 -2
- data/lib/rubocop/cop/style/unless_else.rb +10 -9
- data/lib/rubocop/cop/style/unless_logical_operators.rb +3 -3
- data/lib/rubocop/cop/style/while_until_do.rb +7 -0
- data/lib/rubocop/cop/style/while_until_modifier.rb +16 -1
- data/lib/rubocop/cop/style/word_array.rb +1 -0
- data/lib/rubocop/cop/style/yoda_condition.rb +26 -12
- data/lib/rubocop/cop/style/yoda_expression.rb +11 -2
- data/lib/rubocop/cop/style/zero_length_predicate.rb +6 -3
- data/lib/rubocop/cop/style.rb +311 -0
- data/lib/rubocop/cop/team.rb +172 -49
- data/lib/rubocop/cop/util.rb +7 -10
- data/lib/rubocop/cop/utils/format_string.rb +20 -5
- data/lib/rubocop/cop/variable_force/assignment.rb +8 -4
- data/lib/rubocop/cop/variable_force/branch.rb +30 -6
- data/lib/rubocop/cop/variable_force/scope.rb +1 -1
- data/lib/rubocop/cop/variable_force/variable.rb +42 -11
- data/lib/rubocop/cop/variable_force.rb +26 -9
- data/lib/rubocop/cops_documentation_generator.rb +49 -15
- data/lib/rubocop/directive_comment.rb +147 -5
- data/lib/rubocop/ext/regexp_node.rb +0 -1
- data/lib/rubocop/feature_loader.rb +0 -6
- data/lib/rubocop/file_patterns.rb +9 -1
- data/lib/rubocop/formatter/base_formatter.rb +22 -0
- data/lib/rubocop/formatter/clang_style_formatter.rb +5 -2
- data/lib/rubocop/formatter/disabled_config_formatter.rb +57 -14
- data/lib/rubocop/formatter/emacs_style_formatter.rb +3 -1
- data/lib/rubocop/formatter/formatter_set.rb +7 -2
- data/lib/rubocop/formatter/fuubar_style_formatter.rb +1 -1
- data/lib/rubocop/formatter/github_actions_formatter.rb +6 -5
- data/lib/rubocop/formatter/html_formatter.rb +3 -5
- data/lib/rubocop/formatter/json_formatter.rb +82 -7
- data/lib/rubocop/formatter/junit_formatter.rb +27 -10
- data/lib/rubocop/formatter/markdown_formatter.rb +1 -0
- data/lib/rubocop/formatter/offense_count_formatter.rb +5 -4
- data/lib/rubocop/formatter/pacman_formatter.rb +5 -2
- data/lib/rubocop/formatter/sarif_formatter.rb +186 -0
- data/lib/rubocop/formatter/simple_text_formatter.rb +4 -5
- data/lib/rubocop/formatter/tap_formatter.rb +8 -3
- data/lib/rubocop/formatter/worst_offenders_formatter.rb +5 -4
- data/lib/rubocop/formatter.rb +23 -21
- data/lib/rubocop/lockfile.rb +18 -0
- data/lib/rubocop/lsp/diagnostic.rb +22 -41
- data/lib/rubocop/lsp/disable_comment_edits.rb +135 -0
- data/lib/rubocop/lsp/routes.rb +136 -33
- data/lib/rubocop/lsp/runtime.rb +66 -15
- data/lib/rubocop/lsp/server.rb +4 -2
- data/lib/rubocop/lsp/stdin_runner.rb +38 -19
- data/lib/rubocop/lsp.rb +5 -2
- data/lib/rubocop/magic_comment.rb +55 -0
- data/lib/rubocop/mcp/autocorrection_request.rb +52 -0
- data/lib/rubocop/mcp/explain_tool.rb +68 -0
- data/lib/rubocop/mcp/scope.rb +65 -0
- data/lib/rubocop/mcp/server.rb +307 -0
- data/lib/rubocop/mcp/source_files.rb +35 -0
- data/lib/rubocop/offense_limit.rb +30 -0
- data/lib/rubocop/options.rb +166 -23
- data/lib/rubocop/path_util.rb +20 -5
- data/lib/rubocop/pending_cops_reporter.rb +51 -0
- data/lib/rubocop/plugin/configuration_integrator.rb +153 -0
- data/lib/rubocop/plugin/load_error.rb +26 -0
- data/lib/rubocop/plugin/loader.rb +100 -0
- data/lib/rubocop/plugin/not_supported_error.rb +29 -0
- data/lib/rubocop/plugin.rb +46 -0
- data/lib/rubocop/project_index_loader.rb +82 -0
- data/lib/rubocop/rake_task.rb +6 -4
- data/lib/rubocop/remote_config.rb +18 -13
- data/lib/rubocop/result_cache.rb +110 -65
- data/lib/rubocop/rspec/cop_helper.rb +21 -1
- data/lib/rubocop/rspec/expect_offense.rb +11 -7
- data/lib/rubocop/rspec/shared_contexts.rb +85 -3
- data/lib/rubocop/rspec/support.rb +4 -0
- data/lib/rubocop/runner.rb +368 -106
- data/lib/rubocop/server/cache.rb +67 -48
- data/lib/rubocop/server/cli.rb +2 -4
- data/lib/rubocop/server/client_command/base.rb +10 -0
- data/lib/rubocop/server/client_command/exec.rb +2 -1
- data/lib/rubocop/server/client_command/start.rb +11 -1
- data/lib/rubocop/server/core.rb +8 -0
- data/lib/rubocop/server.rb +14 -0
- data/lib/rubocop/target_finder.rb +25 -11
- data/lib/rubocop/target_ruby.rb +31 -14
- data/lib/rubocop/todo_audit.rb +111 -0
- data/lib/rubocop/unified_diff.rb +257 -0
- data/lib/rubocop/util.rb +69 -0
- data/lib/rubocop/version.rb +48 -10
- data/lib/rubocop.rb +35 -682
- data/lib/ruby_lsp/rubocop/addon.rb +28 -17
- data/lib/ruby_lsp/rubocop/runtime_adapter.rb +99 -0
- metadata +129 -21
- data/lib/rubocop/cop/style/double_cop_disable_directive.rb +0 -46
- data/lib/rubocop/cop/utils/regexp_ranges.rb +0 -113
- data/lib/ruby_lsp/rubocop/wraps_built_in_lsp_runtime.rb +0 -50
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module Cop
|
|
5
|
+
module Style
|
|
6
|
+
# Use `Hash#dig` instead of chaining potentially null `fetch` calls.
|
|
7
|
+
#
|
|
8
|
+
# When `fetch(identifier, nil)` calls are chained on a hash, the expectation
|
|
9
|
+
# is that each step in the chain returns either `nil` or another hash,
|
|
10
|
+
# and in both cases, these can be simplified with a single call to `dig` with
|
|
11
|
+
# multiple arguments.
|
|
12
|
+
#
|
|
13
|
+
# If the 2nd parameter is `{}` or `Hash.new`, an offense will also be registered,
|
|
14
|
+
# as long as the final call in the chain is a nil value. If a non-nil value is given,
|
|
15
|
+
# the chain will not be registered as an offense, as the default value cannot be safely
|
|
16
|
+
# given with `dig`.
|
|
17
|
+
#
|
|
18
|
+
# NOTE: See `Style/DigChain` for replacing chains of `dig` calls with
|
|
19
|
+
# a single method call.
|
|
20
|
+
#
|
|
21
|
+
# @safety
|
|
22
|
+
# This cop is unsafe because it cannot be guaranteed that the receiver
|
|
23
|
+
# is a `Hash` or that `fetch` or `dig` have the expected standard implementation.
|
|
24
|
+
#
|
|
25
|
+
# @example
|
|
26
|
+
# # bad
|
|
27
|
+
# hash.fetch('foo', nil)&.fetch('bar', nil)
|
|
28
|
+
#
|
|
29
|
+
# # bad
|
|
30
|
+
# # earlier members of the chain can return `{}` as long as the final `fetch`
|
|
31
|
+
# # has `nil` as a default value
|
|
32
|
+
# hash.fetch('foo', {}).fetch('bar', nil)
|
|
33
|
+
#
|
|
34
|
+
# # good
|
|
35
|
+
# hash.dig('foo', 'bar')
|
|
36
|
+
#
|
|
37
|
+
# # ok - not handled by the cop since the final `fetch` value is non-nil
|
|
38
|
+
# hash.fetch('foo', {}).fetch('bar', {})
|
|
39
|
+
#
|
|
40
|
+
class HashFetchChain < Base
|
|
41
|
+
extend AutoCorrector
|
|
42
|
+
extend TargetRubyVersion
|
|
43
|
+
|
|
44
|
+
MSG = 'Use `%<replacement>s` instead.'
|
|
45
|
+
RESTRICT_ON_SEND = %i[fetch].freeze
|
|
46
|
+
|
|
47
|
+
minimum_target_ruby_version 2.3
|
|
48
|
+
|
|
49
|
+
# @!method diggable?(node)
|
|
50
|
+
def_node_matcher :diggable?, <<~PATTERN
|
|
51
|
+
(call _ :fetch $_arg {nil (hash) (send (const {nil? cbase} :Hash) :new)})
|
|
52
|
+
PATTERN
|
|
53
|
+
|
|
54
|
+
def on_send(node)
|
|
55
|
+
return if ignored_node?(node)
|
|
56
|
+
return if last_fetch_non_nil?(node)
|
|
57
|
+
|
|
58
|
+
last_replaceable_node, arguments = inspect_chain(node)
|
|
59
|
+
return unless last_replaceable_node
|
|
60
|
+
return unless arguments.size > 1
|
|
61
|
+
|
|
62
|
+
range = last_replaceable_node.selector.join(node.loc.end)
|
|
63
|
+
replacement = replacement(arguments)
|
|
64
|
+
message = format(MSG, replacement: replacement)
|
|
65
|
+
|
|
66
|
+
add_offense(range, message: message) do |corrector|
|
|
67
|
+
corrector.replace(range, replacement)
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
alias on_csend on_send
|
|
71
|
+
|
|
72
|
+
private
|
|
73
|
+
|
|
74
|
+
def last_fetch_non_nil?(node)
|
|
75
|
+
# When chaining `fetch` methods, `fetch(x, {})` is acceptable within
|
|
76
|
+
# the chain, as long as the last method in the chain has a `nil`
|
|
77
|
+
# default value.
|
|
78
|
+
|
|
79
|
+
return false unless node.method?(:fetch)
|
|
80
|
+
|
|
81
|
+
!node.last_argument&.nil_type?
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def inspect_chain(node)
|
|
85
|
+
arguments = []
|
|
86
|
+
|
|
87
|
+
while (arg = diggable?(node))
|
|
88
|
+
arguments.unshift(arg)
|
|
89
|
+
ignore_node(node)
|
|
90
|
+
last_replaceable_node = node
|
|
91
|
+
node = node.receiver
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
[last_replaceable_node, arguments]
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def replacement(arguments)
|
|
98
|
+
values = arguments.map(&:source).join(', ')
|
|
99
|
+
"dig(#{values})"
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
end
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module Cop
|
|
5
|
+
module Style
|
|
6
|
+
# Enforces the use of either `Hash#[]` or `Hash#fetch` for hash lookup.
|
|
7
|
+
#
|
|
8
|
+
# This cop can be configured to prefer either bracket-style (`[]`)
|
|
9
|
+
# or fetch-style lookup. It is disabled by default.
|
|
10
|
+
#
|
|
11
|
+
# When enforcing `fetch` style, only single-argument bracket access is flagged.
|
|
12
|
+
# When enforcing `brackets` style, only `fetch` calls with a single key
|
|
13
|
+
# argument are flagged (not those with default values or blocks).
|
|
14
|
+
#
|
|
15
|
+
# @safety
|
|
16
|
+
# This cop is unsafe because `Hash#[]` and `Hash#fetch` have different
|
|
17
|
+
# semantics. `Hash#[]` returns `nil` for missing keys, while `Hash#fetch`
|
|
18
|
+
# raises a `KeyError`. Replacing one with the other can change program
|
|
19
|
+
# behavior in cases where the key is missing.
|
|
20
|
+
#
|
|
21
|
+
# Additionally, it cannot be guaranteed that the receiver is a `Hash`
|
|
22
|
+
# or responds to the replacement method.
|
|
23
|
+
#
|
|
24
|
+
# @example EnforcedStyle: brackets (default)
|
|
25
|
+
# # bad
|
|
26
|
+
# hash.fetch(key)
|
|
27
|
+
#
|
|
28
|
+
# # good
|
|
29
|
+
# hash[key]
|
|
30
|
+
#
|
|
31
|
+
# # good - fetch with default value is allowed
|
|
32
|
+
# hash.fetch(key, default)
|
|
33
|
+
#
|
|
34
|
+
# # good - fetch with block is allowed
|
|
35
|
+
# hash.fetch(key) { default }
|
|
36
|
+
#
|
|
37
|
+
# # good - `ENV.fetch` is left to `Style/FetchEnvVar` when it is enabled
|
|
38
|
+
# ENV.fetch(key)
|
|
39
|
+
#
|
|
40
|
+
# @example EnforcedStyle: fetch
|
|
41
|
+
# # bad
|
|
42
|
+
# hash[key]
|
|
43
|
+
#
|
|
44
|
+
# # good
|
|
45
|
+
# hash.fetch(key)
|
|
46
|
+
#
|
|
47
|
+
# @example AllowedReceivers: ['Rails.cache']
|
|
48
|
+
# # good
|
|
49
|
+
# Rails.cache.fetch(name, options) { block }
|
|
50
|
+
#
|
|
51
|
+
class HashLookupMethod < Base
|
|
52
|
+
include ConfigurableEnforcedStyle
|
|
53
|
+
include AllowedReceivers
|
|
54
|
+
extend AutoCorrector
|
|
55
|
+
|
|
56
|
+
BRACKET_MSG = 'Use `Hash#[]` instead of `Hash#fetch`.'
|
|
57
|
+
FETCH_MSG = 'Use `Hash#fetch` instead of `Hash#[]`.'
|
|
58
|
+
|
|
59
|
+
RESTRICT_ON_SEND = %i[[] fetch].freeze
|
|
60
|
+
|
|
61
|
+
# @!method env_const?(node)
|
|
62
|
+
def_node_matcher :env_const?, '(const {nil? cbase} :ENV)'
|
|
63
|
+
|
|
64
|
+
def on_send(node)
|
|
65
|
+
return if (receiver = node.receiver) && allowed_receiver?(receiver)
|
|
66
|
+
return if part_of_ignored_node?(node)
|
|
67
|
+
|
|
68
|
+
if offense_for_brackets?(node)
|
|
69
|
+
ignore_node(node.first_argument)
|
|
70
|
+
add_offense(node.loc.selector, message: BRACKET_MSG) do |corrector|
|
|
71
|
+
correct_fetch_to_brackets(corrector, node)
|
|
72
|
+
end
|
|
73
|
+
elsif offense_for_fetch?(node)
|
|
74
|
+
ignore_node(node.first_argument)
|
|
75
|
+
add_offense(node, message: FETCH_MSG) do |corrector|
|
|
76
|
+
correct_brackets_to_fetch(corrector, node)
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
alias on_csend on_send
|
|
81
|
+
|
|
82
|
+
private
|
|
83
|
+
|
|
84
|
+
def offense_for_brackets?(node)
|
|
85
|
+
return false if style != :brackets || !node.receiver
|
|
86
|
+
return false if !node.method?(:fetch) || !node.arguments.one?
|
|
87
|
+
return false if node.block_literal? || node.csend_type?
|
|
88
|
+
|
|
89
|
+
!exempt_from_brackets?(node)
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def exempt_from_brackets?(node)
|
|
93
|
+
comment_before_dot?(node) || env_fetch_preferred?(node.receiver)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def comment_before_dot?(node)
|
|
97
|
+
processed_source.contains_comment?(node.receiver.source_range.end.join(node.loc.dot))
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def env_fetch_preferred?(receiver)
|
|
101
|
+
env_const?(receiver) && processed_source.registry.enabled?(Style::FetchEnvVar, config)
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def offense_for_fetch?(node)
|
|
105
|
+
style == :fetch && node.method?(:[]) && node.arguments.one? &&
|
|
106
|
+
!compound_assignment_target?(node)
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def compound_assignment_target?(node)
|
|
110
|
+
node.parent&.type?(:op_asgn, :or_asgn, :and_asgn) && node.parent.children.first == node
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def correct_fetch_to_brackets(corrector, node)
|
|
114
|
+
key = node.first_argument.source
|
|
115
|
+
|
|
116
|
+
corrector.replace(node.receiver.source_range.end.join(node.source_range.end), "[#{key}]")
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def correct_brackets_to_fetch(corrector, node)
|
|
120
|
+
key = node.first_argument.source
|
|
121
|
+
replacement = node.loc.dot ? "fetch(#{key})" : ".fetch(#{key})"
|
|
122
|
+
|
|
123
|
+
corrector.replace(node.loc.selector.join(node.source_range.end), replacement)
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
end
|
|
@@ -19,6 +19,22 @@ module RuboCop
|
|
|
19
19
|
# This cop is unsafe because it cannot be guaranteed that the receiver
|
|
20
20
|
# is a `Hash` or responds to the replacement method.
|
|
21
21
|
#
|
|
22
|
+
# Additionally, the replacement may change the order of the resulting
|
|
23
|
+
# hash: `Hash#slice` returns entries in the order the keys are given,
|
|
24
|
+
# whereas `select`, `filter`, and `reject` preserve the entry order of
|
|
25
|
+
# the receiver.
|
|
26
|
+
#
|
|
27
|
+
# For example:
|
|
28
|
+
#
|
|
29
|
+
# [source,ruby]
|
|
30
|
+
# ----
|
|
31
|
+
# hash = {foo: 1, bar: 2, baz: 3}
|
|
32
|
+
# keys = %i[baz foo]
|
|
33
|
+
#
|
|
34
|
+
# hash.select { |k, _v| keys.include?(k) } # => {foo: 1, baz: 3}
|
|
35
|
+
# hash.slice(*keys) # => {baz: 3, foo: 1}
|
|
36
|
+
# ----
|
|
37
|
+
#
|
|
22
38
|
# @example
|
|
23
39
|
#
|
|
24
40
|
# # bad
|
|
@@ -76,6 +76,9 @@ module RuboCop
|
|
|
76
76
|
# # good
|
|
77
77
|
# {foo:, bar:}
|
|
78
78
|
#
|
|
79
|
+
# # good - allowed to mix syntaxes
|
|
80
|
+
# {foo:, bar: baz}
|
|
81
|
+
#
|
|
79
82
|
# @example EnforcedShorthandSyntax: never
|
|
80
83
|
#
|
|
81
84
|
# # bad
|
|
@@ -139,6 +142,13 @@ module RuboCop
|
|
|
139
142
|
MSG_HASH_ROCKETS = 'Use hash rockets syntax.'
|
|
140
143
|
NO_MIXED_KEYS_STYLES = %i[ruby19_no_mixed_keys no_mixed_keys].freeze
|
|
141
144
|
|
|
145
|
+
# Omitting the last hash value of a call without parentheses adds the parentheses,
|
|
146
|
+
# which `Style/MethodCallWithArgsParentheses` and `Style/SuperWithArgsParentheses`
|
|
147
|
+
# would add again in the same pass.
|
|
148
|
+
def self.autocorrect_incompatible_with
|
|
149
|
+
[Style::MethodCallWithArgsParentheses, Style::SuperWithArgsParentheses]
|
|
150
|
+
end
|
|
151
|
+
|
|
142
152
|
def on_hash(node)
|
|
143
153
|
pairs = node.pairs
|
|
144
154
|
|
|
@@ -209,12 +219,12 @@ module RuboCop
|
|
|
209
219
|
end
|
|
210
220
|
|
|
211
221
|
def word_symbol_pair?(pair)
|
|
212
|
-
return false unless pair.key.
|
|
222
|
+
return false unless pair.key.any_sym_type?
|
|
213
223
|
|
|
214
224
|
acceptable_19_syntax_symbol?(pair.key.source)
|
|
215
225
|
end
|
|
216
226
|
|
|
217
|
-
# rubocop:disable Metrics/CyclomaticComplexity
|
|
227
|
+
# rubocop:disable-next Metrics/CyclomaticComplexity
|
|
218
228
|
def acceptable_19_syntax_symbol?(sym_name)
|
|
219
229
|
sym_name.delete_prefix!(':')
|
|
220
230
|
|
|
@@ -234,11 +244,12 @@ module RuboCop
|
|
|
234
244
|
(sym_name.start_with?("'") && sym_name.end_with?("'")) ||
|
|
235
245
|
(sym_name.start_with?('"') && sym_name.end_with?('"'))
|
|
236
246
|
end
|
|
237
|
-
# rubocop:enable Metrics/CyclomaticComplexity
|
|
238
247
|
|
|
239
248
|
def check(pairs, delim, msg)
|
|
240
249
|
pairs.each do |pair|
|
|
241
250
|
if pair.delimiter == delim
|
|
251
|
+
next if pair.value_omission? && keyword_value?(pair)
|
|
252
|
+
|
|
242
253
|
location = pair.source_range.begin.join(pair.loc.operator)
|
|
243
254
|
add_offense(location, message: msg) do |corrector|
|
|
244
255
|
autocorrect(corrector, pair)
|
|
@@ -260,6 +271,8 @@ module RuboCop
|
|
|
260
271
|
|
|
261
272
|
hash_node = pair_node.parent
|
|
262
273
|
return unless hash_node.parent&.return_type? && !hash_node.braces?
|
|
274
|
+
# This runs once per pair, but the hash must only be wrapped once.
|
|
275
|
+
return unless pair_node.equal?(hash_node.pairs.first)
|
|
263
276
|
|
|
264
277
|
corrector.wrap(hash_node, '{', '}')
|
|
265
278
|
end
|
|
@@ -279,12 +292,16 @@ module RuboCop
|
|
|
279
292
|
end
|
|
280
293
|
|
|
281
294
|
def autocorrect_hash_rockets(corrector, pair_node)
|
|
282
|
-
op = pair_node.loc.operator
|
|
283
|
-
|
|
284
295
|
key_with_hash_rocket = ":#{pair_node.key.source}#{pair_node.inverse_delimiter(true)}"
|
|
285
296
|
key_with_hash_rocket += pair_node.key.source if pair_node.value_omission?
|
|
286
297
|
corrector.replace(pair_node.key, key_with_hash_rocket)
|
|
287
|
-
corrector.remove(
|
|
298
|
+
corrector.remove(operator_range(pair_node))
|
|
299
|
+
end
|
|
300
|
+
|
|
301
|
+
def operator_range(pair_node)
|
|
302
|
+
op = pair_node.loc.operator
|
|
303
|
+
|
|
304
|
+
range_with_surrounding_space(op, newlines: !pair_node.value_omission?)
|
|
288
305
|
end
|
|
289
306
|
|
|
290
307
|
def autocorrect_no_mixed_keys(corrector, pair_node)
|
|
@@ -3,17 +3,19 @@
|
|
|
3
3
|
module RuboCop
|
|
4
4
|
module Cop
|
|
5
5
|
module Style
|
|
6
|
-
# Looks for uses of
|
|
7
|
-
#
|
|
6
|
+
# Looks for uses of `+_.each_with_object({}) {...}+`,
|
|
7
|
+
# `+_.map {...}.to_h+`, and `+Hash[_.map {...}]+` that are actually just
|
|
8
8
|
# transforming the keys of a hash, and tries to use a simpler & faster
|
|
9
9
|
# call to `transform_keys` instead.
|
|
10
10
|
# It should only be enabled on Ruby version 2.5 or newer.
|
|
11
11
|
# (`transform_keys` was added in Ruby 2.5.)
|
|
12
12
|
#
|
|
13
13
|
# @safety
|
|
14
|
-
# This cop
|
|
15
|
-
#
|
|
16
|
-
#
|
|
14
|
+
# This cop identifies the receiver as a hash by checking for literal hash
|
|
15
|
+
# syntax and common methods that are known to return hashes (e.g. `to_h`,
|
|
16
|
+
# `merge`, `invert`, `group_by`, etc.). However, it is unsafe because it
|
|
17
|
+
# is possible for a custom class to define one of these methods and return
|
|
18
|
+
# something other than a hash.
|
|
17
19
|
#
|
|
18
20
|
# @example
|
|
19
21
|
# # bad
|
|
@@ -21,10 +23,18 @@ module RuboCop
|
|
|
21
23
|
# Hash[{a: 1, b: 2}.collect { |k, v| [foo(k), v] }]
|
|
22
24
|
# {a: 1, b: 2}.map { |k, v| [k.to_s, v] }.to_h
|
|
23
25
|
# {a: 1, b: 2}.to_h { |k, v| [k.to_s, v] }
|
|
26
|
+
# foo.to_h.each_with_object({}) { |(k, v), h| h[k.to_sym] = v }
|
|
27
|
+
# foo.merge(bar).map { |k, v| [k.to_s, v] }.to_h
|
|
24
28
|
#
|
|
25
29
|
# # good
|
|
26
30
|
# {a: 1, b: 2}.transform_keys { |k| foo(k) }
|
|
27
31
|
# {a: 1, b: 2}.transform_keys { |k| k.to_s }
|
|
32
|
+
# foo.to_h.transform_keys { |k| k.to_sym }
|
|
33
|
+
# foo.merge(bar).transform_keys { |k| k.to_s }
|
|
34
|
+
#
|
|
35
|
+
# # Won't register an offense - receiver is not known to be a hash
|
|
36
|
+
# foo.bar.each_with_object({}) { |(k, v), h| h[k.to_s] = v }
|
|
37
|
+
# baz.map { |k, v| [k.to_s, v] }.to_h
|
|
28
38
|
class HashTransformKeys < Base
|
|
29
39
|
include HashTransformMethod
|
|
30
40
|
extend AutoCorrector
|
|
@@ -35,7 +45,7 @@ module RuboCop
|
|
|
35
45
|
# @!method on_bad_each_with_object(node)
|
|
36
46
|
def_node_matcher :on_bad_each_with_object, <<~PATTERN
|
|
37
47
|
(block
|
|
38
|
-
(call
|
|
48
|
+
(call #hash_receiver? :each_with_object (hash))
|
|
39
49
|
(args
|
|
40
50
|
(mlhs
|
|
41
51
|
(arg $_)
|
|
@@ -50,7 +60,7 @@ module RuboCop
|
|
|
50
60
|
(const _ :Hash)
|
|
51
61
|
:[]
|
|
52
62
|
(block
|
|
53
|
-
(call
|
|
63
|
+
(call #hash_receiver? {:map :collect})
|
|
54
64
|
(args
|
|
55
65
|
(arg $_)
|
|
56
66
|
(arg _val))
|
|
@@ -61,7 +71,7 @@ module RuboCop
|
|
|
61
71
|
def_node_matcher :on_bad_map_to_h, <<~PATTERN
|
|
62
72
|
(call
|
|
63
73
|
(block
|
|
64
|
-
(call
|
|
74
|
+
(call #hash_receiver? {:map :collect})
|
|
65
75
|
(args
|
|
66
76
|
(arg $_)
|
|
67
77
|
(arg _val))
|
|
@@ -72,7 +82,7 @@ module RuboCop
|
|
|
72
82
|
# @!method on_bad_to_h(node)
|
|
73
83
|
def_node_matcher :on_bad_to_h, <<~PATTERN
|
|
74
84
|
(block
|
|
75
|
-
(call
|
|
85
|
+
(call #hash_receiver? :to_h)
|
|
76
86
|
(args
|
|
77
87
|
(arg $_)
|
|
78
88
|
(arg _val))
|
|
@@ -3,15 +3,17 @@
|
|
|
3
3
|
module RuboCop
|
|
4
4
|
module Cop
|
|
5
5
|
module Style
|
|
6
|
-
# Looks for uses of
|
|
7
|
-
#
|
|
6
|
+
# Looks for uses of `+_.each_with_object({}) {...}+`,
|
|
7
|
+
# `+_.map {...}.to_h+`, and `+Hash[_.map {...}]+` that are actually just
|
|
8
8
|
# transforming the values of a hash, and tries to use a simpler & faster
|
|
9
9
|
# call to `transform_values` instead.
|
|
10
10
|
#
|
|
11
11
|
# @safety
|
|
12
|
-
# This cop
|
|
13
|
-
#
|
|
14
|
-
#
|
|
12
|
+
# This cop identifies the receiver as a hash by checking for literal hash
|
|
13
|
+
# syntax and common methods that are known to return hashes (e.g. `to_h`,
|
|
14
|
+
# `merge`, `invert`, `group_by`, etc.). However, it is unsafe because it
|
|
15
|
+
# is possible for a custom class to define one of these methods and return
|
|
16
|
+
# something other than a hash.
|
|
15
17
|
#
|
|
16
18
|
# @example
|
|
17
19
|
# # bad
|
|
@@ -19,10 +21,18 @@ module RuboCop
|
|
|
19
21
|
# Hash[{a: 1, b: 2}.collect { |k, v| [k, foo(v)] }]
|
|
20
22
|
# {a: 1, b: 2}.map { |k, v| [k, v * v] }.to_h
|
|
21
23
|
# {a: 1, b: 2}.to_h { |k, v| [k, v * v] }
|
|
24
|
+
# foo.to_h.each_with_object({}) { |(k, v), h| h[k] = foo(v) }
|
|
25
|
+
# foo.merge(bar).map { |k, v| [k, v.to_s] }.to_h
|
|
22
26
|
#
|
|
23
27
|
# # good
|
|
24
28
|
# {a: 1, b: 2}.transform_values { |v| foo(v) }
|
|
25
29
|
# {a: 1, b: 2}.transform_values { |v| v * v }
|
|
30
|
+
# foo.to_h.transform_values { |v| foo(v) }
|
|
31
|
+
# foo.merge(bar).transform_values { |v| v.to_s }
|
|
32
|
+
#
|
|
33
|
+
# # Won't register an offense - receiver is not known to be a hash
|
|
34
|
+
# foo.bar.each_with_object({}) { |(k, v), h| h[k] = v.to_s }
|
|
35
|
+
# baz.map { |k, v| [k, v.to_s] }.to_h
|
|
26
36
|
class HashTransformValues < Base
|
|
27
37
|
include HashTransformMethod
|
|
28
38
|
extend AutoCorrector
|
|
@@ -33,7 +43,7 @@ module RuboCop
|
|
|
33
43
|
# @!method on_bad_each_with_object(node)
|
|
34
44
|
def_node_matcher :on_bad_each_with_object, <<~PATTERN
|
|
35
45
|
(block
|
|
36
|
-
(call
|
|
46
|
+
(call #hash_receiver? :each_with_object (hash))
|
|
37
47
|
(args
|
|
38
48
|
(mlhs
|
|
39
49
|
(arg _key)
|
|
@@ -48,7 +58,7 @@ module RuboCop
|
|
|
48
58
|
(const _ :Hash)
|
|
49
59
|
:[]
|
|
50
60
|
(block
|
|
51
|
-
(call
|
|
61
|
+
(call #hash_receiver? {:map :collect})
|
|
52
62
|
(args
|
|
53
63
|
(arg _key)
|
|
54
64
|
(arg $_))
|
|
@@ -59,7 +69,7 @@ module RuboCop
|
|
|
59
69
|
def_node_matcher :on_bad_map_to_h, <<~PATTERN
|
|
60
70
|
(call
|
|
61
71
|
(block
|
|
62
|
-
(call
|
|
72
|
+
(call #hash_receiver? {:map :collect})
|
|
63
73
|
(args
|
|
64
74
|
(arg _key)
|
|
65
75
|
(arg $_))
|
|
@@ -70,7 +80,7 @@ module RuboCop
|
|
|
70
80
|
# @!method on_bad_to_h(node)
|
|
71
81
|
def_node_matcher :on_bad_to_h, <<~PATTERN
|
|
72
82
|
(block
|
|
73
|
-
(call
|
|
83
|
+
(call #hash_receiver? :to_h)
|
|
74
84
|
(args
|
|
75
85
|
(arg _key)
|
|
76
86
|
(arg $_))
|
|
@@ -136,7 +136,7 @@ module RuboCop
|
|
|
136
136
|
|
|
137
137
|
private
|
|
138
138
|
|
|
139
|
-
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
139
|
+
# rubocop:disable-next Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
140
140
|
def check_branches(node, branches)
|
|
141
141
|
# return if any branch is empty. An empty branch can be an `if`
|
|
142
142
|
# without an `else` or a branch that contains only comments.
|
|
@@ -168,7 +168,6 @@ module RuboCop
|
|
|
168
168
|
|
|
169
169
|
check_expressions(node, heads, :before_condition)
|
|
170
170
|
end
|
|
171
|
-
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
172
171
|
|
|
173
172
|
def duplicated_expressions?(node, expressions)
|
|
174
173
|
unique_expressions = expressions.uniq
|
|
@@ -189,7 +188,7 @@ module RuboCop
|
|
|
189
188
|
end
|
|
190
189
|
end
|
|
191
190
|
|
|
192
|
-
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
|
191
|
+
# rubocop:disable-next Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
|
193
192
|
def check_expressions(node, expressions, insert_position)
|
|
194
193
|
return if expressions.any?(&:nil?)
|
|
195
194
|
|
|
@@ -197,10 +196,9 @@ module RuboCop
|
|
|
197
196
|
|
|
198
197
|
expressions.each do |expression|
|
|
199
198
|
add_offense(expression) do |corrector|
|
|
200
|
-
next if node.if_type? && node.ternary?
|
|
199
|
+
next if node.if_type? && (node.ternary? || node.then?)
|
|
201
200
|
|
|
202
|
-
|
|
203
|
-
corrector.remove(range)
|
|
201
|
+
corrector.remove(removal_range(expression))
|
|
204
202
|
next if inserted_expression
|
|
205
203
|
|
|
206
204
|
if node.parent&.assignment?
|
|
@@ -213,26 +211,56 @@ module RuboCop
|
|
|
213
211
|
end
|
|
214
212
|
end
|
|
215
213
|
end
|
|
216
|
-
|
|
214
|
+
|
|
215
|
+
def removal_range(expression)
|
|
216
|
+
range = expression.source_range
|
|
217
|
+
whole_lines = range_by_whole_lines(range, include_final_newline: true)
|
|
218
|
+
return whole_lines if whole_lines.source.strip == expression.source
|
|
219
|
+
|
|
220
|
+
range_with_separator(range)
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
def range_with_separator(range)
|
|
224
|
+
source = range.source_buffer.source
|
|
225
|
+
|
|
226
|
+
if (following = source[range.end_pos..][/\A[ \t]*;[ \t]*/])
|
|
227
|
+
range.adjust(end_pos: following.length)
|
|
228
|
+
elsif (preceding = source[0...range.begin_pos][/[ \t]*;[ \t]*\z/])
|
|
229
|
+
range.adjust(begin_pos: -preceding.length)
|
|
230
|
+
else
|
|
231
|
+
range_with_surrounding_space(range, side: :right, newlines: false)
|
|
232
|
+
end
|
|
233
|
+
end
|
|
217
234
|
|
|
218
235
|
def correct_assignment(corrector, node, expression, insert_position)
|
|
236
|
+
indentation = indentation_of(node.parent)
|
|
237
|
+
|
|
219
238
|
if insert_position == :after_condition
|
|
220
239
|
assignment = node.parent.source_range.with(end_pos: node.source_range.begin_pos)
|
|
221
240
|
corrector.remove(assignment)
|
|
222
|
-
corrector.insert_after(node, "\n#{assignment.source}#{expression.source}")
|
|
241
|
+
corrector.insert_after(node, "\n#{indentation}#{assignment.source}#{expression.source}")
|
|
223
242
|
else
|
|
224
|
-
corrector.insert_before(node.parent, "#{expression.source}\n")
|
|
243
|
+
corrector.insert_before(node.parent, "#{expression.source}\n#{indentation}")
|
|
225
244
|
end
|
|
226
245
|
end
|
|
227
246
|
|
|
228
247
|
def correct_no_assignment(corrector, node, expression, insert_position)
|
|
248
|
+
indentation = indentation_of(node)
|
|
249
|
+
|
|
229
250
|
if insert_position == :after_condition
|
|
230
|
-
corrector.insert_after(node, "\n#{expression.source}")
|
|
251
|
+
corrector.insert_after(node, "\n#{indentation}#{expression.source}")
|
|
231
252
|
else
|
|
232
|
-
corrector.insert_before(node, "#{expression.source}\n")
|
|
253
|
+
corrector.insert_before(node, "#{expression.source}\n#{indentation}")
|
|
233
254
|
end
|
|
234
255
|
end
|
|
235
256
|
|
|
257
|
+
# The leading indentation of the line the conditional starts on, so a
|
|
258
|
+
# hoisted expression keeps the surrounding nesting instead of landing
|
|
259
|
+
# at column zero.
|
|
260
|
+
def indentation_of(node)
|
|
261
|
+
' ' * node.source_range.column
|
|
262
|
+
end
|
|
263
|
+
|
|
236
264
|
def last_child_of_parent?(node)
|
|
237
265
|
return true unless (parent = node.parent)
|
|
238
266
|
|