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,270 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
begin
|
|
4
|
+
require 'did_you_mean'
|
|
5
|
+
rescue LoadError
|
|
6
|
+
nil
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
module RuboCop
|
|
10
|
+
module Cop
|
|
11
|
+
module Lint
|
|
12
|
+
# Checks for probable typos in constant and method names: a name that
|
|
13
|
+
# does not resolve anywhere in the project, used in a namespace the
|
|
14
|
+
# project does define, with a close-named sibling to suggest instead.
|
|
15
|
+
#
|
|
16
|
+
# The check is powered by the project-wide index, so it only runs when
|
|
17
|
+
# `AllCops/UseProjectIndex` is enabled and the `rubydex` gem is installed.
|
|
18
|
+
# Without the index the cop does nothing.
|
|
19
|
+
#
|
|
20
|
+
# Constants are checked only in qualified references (`Foo::Bar`) whose
|
|
21
|
+
# namespace resolves in the index; bare names cannot be distinguished
|
|
22
|
+
# from constants provided by gems or the standard library. Methods are
|
|
23
|
+
# checked only in calls on constant receivers (`Foo.bar`) whose entire
|
|
24
|
+
# indexed ancestry is resolved, so methods gained through gem classes or
|
|
25
|
+
# dynamic definitions never produce offenses. In both cases an offense
|
|
26
|
+
# requires a similarly named alternative to exist — an unknown name
|
|
27
|
+
# alone is not reported, since the index does not see gems or the
|
|
28
|
+
# standard library.
|
|
29
|
+
#
|
|
30
|
+
# For the same reason, a namespace whose root segment names a gem in the
|
|
31
|
+
# bundle (`Flipper` for the `flipper` gem) is left alone: a project that
|
|
32
|
+
# reopens it (`module Flipper; module Adapters; ...`) makes it resolve in
|
|
33
|
+
# the index, while the members the gem itself defines stay invisible and
|
|
34
|
+
# would look like typos. Enabling `AllCops/ProjectIndexIncludesGems`
|
|
35
|
+
# indexes those sources and restores the check.
|
|
36
|
+
#
|
|
37
|
+
# Names that appear as symbols or inside string literals in the same
|
|
38
|
+
# file are never reported, since they usually belong to runtime
|
|
39
|
+
# definitions the index cannot see (`stub_const`, `const_set`,
|
|
40
|
+
# `define_method`, and the like).
|
|
41
|
+
#
|
|
42
|
+
# @example
|
|
43
|
+
# # bad - Services::UserCraetor is not defined, Services::UserCreator is
|
|
44
|
+
# Services::UserCraetor.new
|
|
45
|
+
#
|
|
46
|
+
# # good
|
|
47
|
+
# Services::UserCreator.new
|
|
48
|
+
#
|
|
49
|
+
# # bad - Report.generate_sumary is not defined, Report.generate_summary is
|
|
50
|
+
# Report.generate_sumary
|
|
51
|
+
#
|
|
52
|
+
# # good
|
|
53
|
+
# Report.generate_summary
|
|
54
|
+
#
|
|
55
|
+
# @example CheckConstants: false
|
|
56
|
+
# # good - constant references are not checked
|
|
57
|
+
# Services::UserCraetor.new
|
|
58
|
+
#
|
|
59
|
+
# @example CheckMethods: false
|
|
60
|
+
# # good - method calls are not checked
|
|
61
|
+
# Report.generate_sumary
|
|
62
|
+
#
|
|
63
|
+
# @example AllowedNames: ['generate_sumary']
|
|
64
|
+
# # good - the name is explicitly allowed
|
|
65
|
+
# Report.generate_sumary
|
|
66
|
+
#
|
|
67
|
+
class NameTypo < Base
|
|
68
|
+
include ProjectIndexHelp
|
|
69
|
+
|
|
70
|
+
CONSTANT_MSG = 'Possible typo: `%<name>s` is not defined in `%<namespace>s`. ' \
|
|
71
|
+
'Did you mean `%<suggestion>s`?'
|
|
72
|
+
METHOD_MSG = 'Possible typo: `%<receiver>s` does not respond to `%<name>s`. ' \
|
|
73
|
+
'Did you mean `%<suggestion>s`?'
|
|
74
|
+
|
|
75
|
+
METHOD_MEMBER_REGEXP = /#([a-zA-Z_]\w*[?!]?)\(\)\z/.freeze
|
|
76
|
+
LITERAL_IDENTIFIER_PATTERN = /[a-zA-Z_]\w*[?!]?/.freeze
|
|
77
|
+
|
|
78
|
+
def on_const(node)
|
|
79
|
+
return unless check?('CheckConstants') && checkable_constant?(node)
|
|
80
|
+
|
|
81
|
+
suggestion = constant_typo_suggestion(node)
|
|
82
|
+
return unless suggestion
|
|
83
|
+
|
|
84
|
+
message = format(CONSTANT_MSG, name: node.short_name,
|
|
85
|
+
namespace: node.namespace.const_name,
|
|
86
|
+
suggestion: suggestion)
|
|
87
|
+
add_offense(node.loc.name, message: message)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def on_send(node)
|
|
91
|
+
return unless check?('CheckMethods')
|
|
92
|
+
return unless node.receiver&.const_type?
|
|
93
|
+
return if allowed_name?(node.method_name) || defined_check?(node)
|
|
94
|
+
|
|
95
|
+
suggestion = method_typo_suggestion(node)
|
|
96
|
+
return unless suggestion
|
|
97
|
+
|
|
98
|
+
message = format(METHOD_MSG, receiver: node.receiver.const_name,
|
|
99
|
+
name: node.method_name,
|
|
100
|
+
suggestion: suggestion)
|
|
101
|
+
add_offense(node.loc.selector, message: message)
|
|
102
|
+
end
|
|
103
|
+
alias on_csend on_send
|
|
104
|
+
|
|
105
|
+
def on_new_investigation
|
|
106
|
+
@literal_names = nil
|
|
107
|
+
super
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
private
|
|
111
|
+
|
|
112
|
+
def check?(key)
|
|
113
|
+
project_index && defined?(DidYouMean::SpellChecker) && cop_config.fetch(key, true)
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def checkable_constant?(node)
|
|
117
|
+
node.namespace&.const_type? &&
|
|
118
|
+
!allowed_name?(node.short_name) &&
|
|
119
|
+
!definition_identifier?(node) && !defined_check?(node)
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def allowed_name?(name)
|
|
123
|
+
cop_config.fetch('AllowedNames', []).include?(name.to_s)
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
# The last segment of a class, module or constant definition is being
|
|
127
|
+
# defined, not referenced.
|
|
128
|
+
def definition_identifier?(node)
|
|
129
|
+
node.parent&.defined_module
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
# `defined?(Foo::Bar)` probes whether a name exists; unknown names
|
|
133
|
+
# there are deliberate.
|
|
134
|
+
def defined_check?(node)
|
|
135
|
+
node.each_ancestor(:defined?).any?
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def constant_typo_suggestion(node)
|
|
139
|
+
namespace = resolve_constant_in_index(node.namespace)
|
|
140
|
+
return nil unless namespace.is_a?(Rubydex::Namespace)
|
|
141
|
+
return nil if namespace.find_member(node.short_name.to_s)
|
|
142
|
+
return nil unless complete_index_members?(namespace)
|
|
143
|
+
return nil if literal_names.include?(node.short_name.to_s)
|
|
144
|
+
|
|
145
|
+
spell_check(node.short_name, constant_member_names(namespace))
|
|
146
|
+
rescue StandardError
|
|
147
|
+
nil
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
# Whether the index can be trusted to list everything the namespace
|
|
151
|
+
# defines. A name missing from an incomplete member list is not
|
|
152
|
+
# evidence of a typo, so both gaps have to be ruled out first:
|
|
153
|
+
# an ancestor that does not resolve may contribute the name, and so
|
|
154
|
+
# may a gem that reopens the namespace.
|
|
155
|
+
def complete_index_members?(declaration)
|
|
156
|
+
fully_resolved_index_ancestry?(declaration) && !gem_owned_namespace?(declaration)
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
# Whether the namespace's root segment names a gem in the bundle,
|
|
160
|
+
# which is then free to define members the index never sees: gem
|
|
161
|
+
# sources are only indexed when `AllCops/ProjectIndexIncludesGems`
|
|
162
|
+
# is enabled. A project that reopens such a namespace to add its own
|
|
163
|
+
# members (`module Flipper; module Adapters; ...`) makes it resolve
|
|
164
|
+
# in the index while most of what it holds stays invisible.
|
|
165
|
+
def gem_owned_namespace?(declaration)
|
|
166
|
+
return false if config.for_all_cops['ProjectIndexIncludesGems']
|
|
167
|
+
|
|
168
|
+
root = declaration.name.to_s.split('::').first.to_s
|
|
169
|
+
bundled_gem_namespaces.include?(root.downcase)
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
# Gem names normalized towards the constant they conventionally
|
|
173
|
+
# provide: `flipper` for `Flipper`, `activerecord` for `ActiveRecord`.
|
|
174
|
+
def bundled_gem_namespaces
|
|
175
|
+
@bundled_gem_namespaces ||= bundled_gem_names.to_set { |name| name.delete('-_').downcase }
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
# The bundle's gems except those sourced from a local path, whose code
|
|
179
|
+
# lives in the project and is indexed like the rest of it — among them
|
|
180
|
+
# the project's own gem, which its lockfile lists in the `PATH` section.
|
|
181
|
+
def bundled_gem_names
|
|
182
|
+
(config.gem_versions_in_target || {}).keys - (config.path_sourced_gems_in_target || [])
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
# Writers are indexed under the reader's name, so setter calls are
|
|
186
|
+
# verified and spell-checked through the base name.
|
|
187
|
+
def method_typo_suggestion(node)
|
|
188
|
+
setter = setter_call?(node)
|
|
189
|
+
base = setter ? node.method_name.to_s.delete_suffix('=') : node.method_name.to_s
|
|
190
|
+
|
|
191
|
+
declaration = unknown_method_owner(node, base)
|
|
192
|
+
return nil unless declaration
|
|
193
|
+
return nil if literal_names.include?(base)
|
|
194
|
+
|
|
195
|
+
suggestion = spell_check(base, method_member_names(declaration))
|
|
196
|
+
suggestion && setter ? "#{suggestion}=" : suggestion
|
|
197
|
+
rescue StandardError
|
|
198
|
+
nil
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
# The receiver's declaration when it resolves in the index, everything
|
|
202
|
+
# it can inherit or be reopened with is visible there, and the method
|
|
203
|
+
# is not found — nil otherwise.
|
|
204
|
+
def unknown_method_owner(node, base)
|
|
205
|
+
declaration = resolve_constant_in_index(node.receiver)
|
|
206
|
+
return nil unless declaration.is_a?(Rubydex::Namespace)
|
|
207
|
+
return nil if responds_in_index?(declaration, node.method_name.to_s, base)
|
|
208
|
+
return nil unless fully_resolved_index_ancestry?(declaration)
|
|
209
|
+
return nil if gem_owned_namespace?(declaration)
|
|
210
|
+
|
|
211
|
+
declaration
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
def setter_call?(node)
|
|
215
|
+
node.assignment_method? && !node.operator_method?
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
def responds_in_index?(declaration, name, base)
|
|
219
|
+
# Instance methods of a module are also callable on the module
|
|
220
|
+
# itself when exposed with `module_function`.
|
|
221
|
+
[name, base].uniq.any? do |candidate|
|
|
222
|
+
member_name = "#{candidate}()"
|
|
223
|
+
indexed_singleton_member(declaration, member_name) ||
|
|
224
|
+
declaration.find_member(member_name)
|
|
225
|
+
end
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
# Names mentioned as symbols or inside string literals in the current
|
|
229
|
+
# file belong to runtime definitions (`stub_const`, `const_set`,
|
|
230
|
+
# `define_method`) that the index cannot see.
|
|
231
|
+
def literal_names
|
|
232
|
+
@literal_names ||=
|
|
233
|
+
processed_source.ast.each_descendant(:sym, :str)
|
|
234
|
+
.with_object(Set.new) do |literal, names|
|
|
235
|
+
if literal.sym_type?
|
|
236
|
+
names << literal.value.to_s
|
|
237
|
+
else
|
|
238
|
+
# `scan` raises on binary string literals with invalid byte sequences.
|
|
239
|
+
value = literal.value
|
|
240
|
+
value = value.scrub unless value.valid_encoding?
|
|
241
|
+
value.scan(LITERAL_IDENTIFIER_PATTERN) { |token| names << token }
|
|
242
|
+
end
|
|
243
|
+
end
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
def constant_member_names(namespace)
|
|
247
|
+
namespace.members.filter_map do |member|
|
|
248
|
+
name = member.name
|
|
249
|
+
name.split('::').last unless name.include?('#') || name.include?('<')
|
|
250
|
+
end
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
def method_member_names(declaration)
|
|
254
|
+
scopes = declaration.ancestors.filter_map { |ancestor| indexed_singleton_of(ancestor) }
|
|
255
|
+
scopes << declaration
|
|
256
|
+
|
|
257
|
+
scopes.flat_map do |scope|
|
|
258
|
+
scope.members.filter_map { |member| member.name[METHOD_MEMBER_REGEXP, 1] }
|
|
259
|
+
end
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
def spell_check(name, dictionary)
|
|
263
|
+
return nil if dictionary.empty?
|
|
264
|
+
|
|
265
|
+
DidYouMean::SpellChecker.new(dictionary: dictionary.uniq).correct(name.to_s).first
|
|
266
|
+
end
|
|
267
|
+
end
|
|
268
|
+
end
|
|
269
|
+
end
|
|
270
|
+
end
|
|
@@ -95,10 +95,10 @@ module RuboCop
|
|
|
95
95
|
MSG = 'Method definitions must not be nested. Use `lambda` instead.'
|
|
96
96
|
|
|
97
97
|
def on_def(node)
|
|
98
|
-
subject, = *node # rubocop:disable InternalAffairs/NodeDestructuring
|
|
98
|
+
subject, = *node # rubocop:disable InternalAffairs/NodeDestructuring -- the first child differs between `def` and `defs`
|
|
99
99
|
return if node.defs_type? && allowed_subject_type?(subject)
|
|
100
100
|
|
|
101
|
-
def_ancestor = node.each_ancestor(:
|
|
101
|
+
def_ancestor = node.each_ancestor(:any_def).first
|
|
102
102
|
return unless def_ancestor
|
|
103
103
|
|
|
104
104
|
within_scoping_def =
|
|
@@ -31,6 +31,7 @@ module RuboCop
|
|
|
31
31
|
end
|
|
32
32
|
end
|
|
33
33
|
alias on_numblock on_block
|
|
34
|
+
alias on_itblock on_block
|
|
34
35
|
|
|
35
36
|
private
|
|
36
37
|
|
|
@@ -39,6 +40,7 @@ module RuboCop
|
|
|
39
40
|
{
|
|
40
41
|
(block (call _recv {:reduce :inject} !sym) _blockargs $(begin ...))
|
|
41
42
|
(numblock (call _recv {:reduce :inject} !sym) _argscount $(begin ...))
|
|
43
|
+
(itblock (call _recv {:reduce :inject} !sym) _argscount $(begin ...))
|
|
42
44
|
}
|
|
43
45
|
PATTERN
|
|
44
46
|
|
|
@@ -41,12 +41,32 @@ module RuboCop
|
|
|
41
41
|
def on_lvasgn(node)
|
|
42
42
|
node.each_node(:kwbegin) do |kwbegin_node|
|
|
43
43
|
kwbegin_node.each_node(:return) do |return_node|
|
|
44
|
+
next if return_from_inner_scope?(return_node, kwbegin_node)
|
|
45
|
+
|
|
44
46
|
add_offense(return_node)
|
|
45
47
|
end
|
|
46
48
|
end
|
|
47
49
|
end
|
|
50
|
+
alias on_ivasgn on_lvasgn
|
|
51
|
+
alias on_cvasgn on_lvasgn
|
|
52
|
+
alias on_gvasgn on_lvasgn
|
|
53
|
+
alias on_casgn on_lvasgn
|
|
48
54
|
alias on_or_asgn on_lvasgn
|
|
49
55
|
alias on_op_asgn on_lvasgn
|
|
56
|
+
|
|
57
|
+
private
|
|
58
|
+
|
|
59
|
+
# A `return` inside a nested method definition or lambda within the
|
|
60
|
+
# `begin..end` returns from that inner scope rather than the assignment
|
|
61
|
+
# context, so it is not an offense. A `return` inside a plain block (or
|
|
62
|
+
# `proc`) does propagate out, so it remains an offense.
|
|
63
|
+
def return_from_inner_scope?(return_node, kwbegin_node)
|
|
64
|
+
return_node.each_ancestor do |ancestor|
|
|
65
|
+
break if ancestor == kwbegin_node
|
|
66
|
+
return true if ancestor.any_def_type? || (ancestor.any_block_type? && ancestor.lambda?)
|
|
67
|
+
end
|
|
68
|
+
false
|
|
69
|
+
end
|
|
50
70
|
end
|
|
51
71
|
end
|
|
52
72
|
end
|
|
@@ -12,7 +12,7 @@ module RuboCop
|
|
|
12
12
|
# always sort the list.
|
|
13
13
|
#
|
|
14
14
|
# `Dir.glob` and `Dir[]` sort globbed results by default in Ruby 3.0.
|
|
15
|
-
# So all bad cases are acceptable when Ruby 3.0 or higher
|
|
15
|
+
# So all bad cases are acceptable when Ruby 3.0 or higher is used.
|
|
16
16
|
#
|
|
17
17
|
# NOTE: This cop will be deprecated and removed when supporting only Ruby 3.0 and higher.
|
|
18
18
|
#
|
|
@@ -65,7 +65,9 @@ module RuboCop
|
|
|
65
65
|
|
|
66
66
|
maximum_target_ruby_version 2.7
|
|
67
67
|
|
|
68
|
-
|
|
68
|
+
# NOTE: itblock is not handled because this cop is limited to Ruby <= 2.7
|
|
69
|
+
# via `maximum_target_ruby_version`, so itblock nodes (Ruby 3.4+) are never encountered.
|
|
70
|
+
def on_block(node) # rubocop:disable InternalAffairs/ItblockHandler -- limited to Ruby <= 2.7, where `it` blocks do not exist
|
|
69
71
|
return unless node.body
|
|
70
72
|
return unless unsorted_dir_loop?(node.send_node)
|
|
71
73
|
|
|
@@ -46,7 +46,7 @@ module RuboCop
|
|
|
46
46
|
def on_return(return_node)
|
|
47
47
|
return if return_value?(return_node)
|
|
48
48
|
|
|
49
|
-
return_node.each_ancestor(:
|
|
49
|
+
return_node.each_ancestor(:any_block, :any_def) do |node|
|
|
50
50
|
break if scoped_node?(node)
|
|
51
51
|
|
|
52
52
|
# if a proc is passed to `Module#define_method` or
|
|
@@ -54,7 +54,7 @@ module RuboCop
|
|
|
54
54
|
# non-local exit error
|
|
55
55
|
break if define_method?(node.send_node)
|
|
56
56
|
|
|
57
|
-
next
|
|
57
|
+
next if node.argument_list.empty?
|
|
58
58
|
|
|
59
59
|
if chained_send?(node.send_node)
|
|
60
60
|
add_offense(return_node.loc.keyword)
|
|
@@ -66,7 +66,7 @@ module RuboCop
|
|
|
66
66
|
private
|
|
67
67
|
|
|
68
68
|
def scoped_node?(node)
|
|
69
|
-
node.
|
|
69
|
+
node.any_def_type? || node.lambda?
|
|
70
70
|
end
|
|
71
71
|
|
|
72
72
|
def return_value?(return_node)
|
|
@@ -74,7 +74,7 @@ module RuboCop
|
|
|
74
74
|
end
|
|
75
75
|
|
|
76
76
|
# @!method chained_send?(node)
|
|
77
|
-
def_node_matcher :chained_send?, '(
|
|
77
|
+
def_node_matcher :chained_send?, '(call !nil? ...)'
|
|
78
78
|
|
|
79
79
|
# @!method define_method?(node)
|
|
80
80
|
def_node_matcher :define_method?, <<~PATTERN
|
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
module RuboCop
|
|
4
4
|
module Cop
|
|
5
5
|
module Lint
|
|
6
|
-
# Warns the usage of unsafe number conversions. Unsafe
|
|
7
|
-
# number conversion can cause unexpected error if auto type conversion
|
|
8
|
-
# fails.
|
|
6
|
+
# Warns against the usage of unsafe number conversions. Unsafe
|
|
7
|
+
# number conversion can cause an unexpected error if auto type conversion
|
|
8
|
+
# fails. The cop prefers parsing with a number class instead.
|
|
9
9
|
#
|
|
10
10
|
# Conversion with `Integer`, `Float`, etc. will raise an `ArgumentError`
|
|
11
11
|
# if given input that is not numeric (eg. an empty string), whereas
|
|
@@ -14,10 +14,10 @@ module RuboCop
|
|
|
14
14
|
# always correct to raise if a value is not numeric.
|
|
15
15
|
#
|
|
16
16
|
# NOTE: Some values cannot be converted properly using one of the `Kernel`
|
|
17
|
-
#
|
|
17
|
+
# methods (for instance, `Time` and `DateTime` values are allowed by this
|
|
18
18
|
# cop by default). Similarly, Rails' duration methods do not work well
|
|
19
19
|
# with `Integer()` and can be allowed with `AllowedMethods`. By default,
|
|
20
|
-
# there are no methods
|
|
20
|
+
# there are no allowed methods.
|
|
21
21
|
#
|
|
22
22
|
# @safety
|
|
23
23
|
# Autocorrection is unsafe because it is not guaranteed that the
|
|
@@ -66,7 +66,7 @@ module RuboCop
|
|
|
66
66
|
# # good
|
|
67
67
|
# 10.minutes.to_i
|
|
68
68
|
#
|
|
69
|
-
# @example
|
|
69
|
+
# @example AllowedClasses: [Time, DateTime] (default)
|
|
70
70
|
#
|
|
71
71
|
# # good
|
|
72
72
|
# Time.now.to_datetime.to_i
|
|
@@ -117,11 +117,11 @@ module RuboCop
|
|
|
117
117
|
|
|
118
118
|
message = format(
|
|
119
119
|
MSG,
|
|
120
|
-
current:
|
|
120
|
+
current: current_method(node, receiver, to_method),
|
|
121
121
|
corrected_method: correct_method(node, receiver)
|
|
122
122
|
)
|
|
123
123
|
add_offense(node, message: message) do |corrector|
|
|
124
|
-
next if part_of_ignored_node?(node)
|
|
124
|
+
next if safe_navigation?(node) || part_of_ignored_node?(node)
|
|
125
125
|
|
|
126
126
|
corrector.replace(node, correct_method(node, node.receiver))
|
|
127
127
|
|
|
@@ -132,7 +132,7 @@ module RuboCop
|
|
|
132
132
|
|
|
133
133
|
def handle_as_symbol(node)
|
|
134
134
|
to_method_symbol(node) do |receiver, sym_node, to_method|
|
|
135
|
-
next if receiver.nil? || !node.arguments.one?
|
|
135
|
+
next if receiver.nil? || !node.arguments.one? || node.operator_method?
|
|
136
136
|
|
|
137
137
|
message = format(
|
|
138
138
|
MSG,
|
|
@@ -156,13 +156,22 @@ module RuboCop
|
|
|
156
156
|
"{ |i| #{body} }"
|
|
157
157
|
end
|
|
158
158
|
|
|
159
|
+
def current_method(node, receiver, to_method)
|
|
160
|
+
operator = node.csend_type? ? '&.' : '.'
|
|
161
|
+
"#{receiver.source}#{operator}#{to_method}"
|
|
162
|
+
end
|
|
163
|
+
|
|
159
164
|
def remove_parentheses(corrector, node)
|
|
160
165
|
corrector.replace(node.loc.begin, ' ')
|
|
161
166
|
corrector.remove(node.loc.end)
|
|
162
167
|
end
|
|
163
168
|
|
|
169
|
+
def safe_navigation?(node)
|
|
170
|
+
node.csend_type? || node.each_descendant(:csend).any?
|
|
171
|
+
end
|
|
172
|
+
|
|
164
173
|
def allow_receiver?(receiver)
|
|
165
|
-
if receiver.numeric_type? || (receiver.
|
|
174
|
+
if receiver.numeric_type? || (receiver.call_type? &&
|
|
166
175
|
(conversion_method?(receiver.method_name) ||
|
|
167
176
|
allowed_method_name?(receiver.method_name)))
|
|
168
177
|
true
|
|
@@ -188,7 +197,7 @@ module RuboCop
|
|
|
188
197
|
end
|
|
189
198
|
|
|
190
199
|
def ignored_classes
|
|
191
|
-
cop_config.fetch('
|
|
200
|
+
cop_config.fetch('AllowedClasses', [])
|
|
192
201
|
end
|
|
193
202
|
|
|
194
203
|
def ignored_class?(name)
|
|
@@ -16,7 +16,7 @@ module RuboCop
|
|
|
16
16
|
# ruby 3.0.0p0 (2020-12-25 revision 95aff21468) [x86_64-darwin19]
|
|
17
17
|
# -e:1: _1 is reserved for numbered parameter
|
|
18
18
|
#
|
|
19
|
-
# NOTE: The
|
|
19
|
+
# NOTE: The numbered parameters are from `_1` to `_9`. This cop checks `_0`, and over `_10`
|
|
20
20
|
# as well to prevent confusion.
|
|
21
21
|
#
|
|
22
22
|
# @example
|
|
@@ -15,6 +15,13 @@ module RuboCop
|
|
|
15
15
|
# can't determine the type of `x`. If `x` is an `Array` or `String`, it doesn't perform
|
|
16
16
|
# a numeric operation.
|
|
17
17
|
#
|
|
18
|
+
# @safety
|
|
19
|
+
# This cop is unsafe because the autocorrection drops the operands, which
|
|
20
|
+
# discards any side effects of evaluating them and can change behavior when
|
|
21
|
+
# the result is not actually constant. For example, `x / x` raises
|
|
22
|
+
# `ZeroDivisionError` when `x` is `0`, and returns `Float::NAN` (not `1`)
|
|
23
|
+
# when `x` is `0.0`; replacing it with `1` silences that.
|
|
24
|
+
#
|
|
18
25
|
# @example
|
|
19
26
|
#
|
|
20
27
|
# # bad
|
|
@@ -45,6 +52,7 @@ module RuboCop
|
|
|
45
52
|
#
|
|
46
53
|
class NumericOperationWithConstantResult < Base
|
|
47
54
|
extend AutoCorrector
|
|
55
|
+
|
|
48
56
|
MSG = 'Numeric operation with a constant result detected.'
|
|
49
57
|
RESTRICT_ON_SEND = %i[* / **].freeze
|
|
50
58
|
|
|
@@ -57,6 +65,9 @@ module RuboCop
|
|
|
57
65
|
'(op-asgn (lvasgn $_lhs) $_operation ({int lvar} $_rhs))'
|
|
58
66
|
|
|
59
67
|
def on_send(node)
|
|
68
|
+
# Safe navigation short-circuits to `nil` when the receiver is `nil`, so the
|
|
69
|
+
# result is not constant and replacing it with `0`/`1` would change behavior.
|
|
70
|
+
return if node.csend_type?
|
|
60
71
|
return unless (lhs, operation, rhs = operation_with_constant_result?(node))
|
|
61
72
|
return unless (result = constant_result?(lhs, operation, rhs))
|
|
62
73
|
|
|
@@ -38,23 +38,23 @@ module RuboCop
|
|
|
38
38
|
def on_new_investigation
|
|
39
39
|
return if processed_source.buffer.source.empty?
|
|
40
40
|
|
|
41
|
-
encoding_line,
|
|
41
|
+
encoding_line, other_magic_comment_line = magic_comment_lines
|
|
42
42
|
|
|
43
|
-
return unless encoding_line &&
|
|
44
|
-
return if encoding_line <
|
|
43
|
+
return unless encoding_line && other_magic_comment_line
|
|
44
|
+
return if encoding_line < other_magic_comment_line
|
|
45
45
|
|
|
46
46
|
range = processed_source.buffer.line_range(encoding_line + 1)
|
|
47
47
|
|
|
48
48
|
add_offense(range) do |corrector|
|
|
49
|
-
autocorrect(corrector, encoding_line,
|
|
49
|
+
autocorrect(corrector, encoding_line, other_magic_comment_line)
|
|
50
50
|
end
|
|
51
51
|
end
|
|
52
52
|
|
|
53
53
|
private
|
|
54
54
|
|
|
55
|
-
def autocorrect(corrector, encoding_line,
|
|
55
|
+
def autocorrect(corrector, encoding_line, other_magic_comment_line)
|
|
56
56
|
range1 = processed_source.buffer.line_range(encoding_line + 1)
|
|
57
|
-
range2 = processed_source.buffer.line_range(
|
|
57
|
+
range2 = processed_source.buffer.line_range(other_magic_comment_line + 1)
|
|
58
58
|
|
|
59
59
|
corrector.replace(range1, range2.source)
|
|
60
60
|
corrector.replace(range2, range1.source)
|
|
@@ -66,7 +66,7 @@ module RuboCop
|
|
|
66
66
|
leading_magic_comments.each.with_index do |comment, index|
|
|
67
67
|
if comment.encoding_specified?
|
|
68
68
|
lines[0] = index
|
|
69
|
-
elsif comment.
|
|
69
|
+
elsif comment.valid?
|
|
70
70
|
lines[1] = index
|
|
71
71
|
end
|
|
72
72
|
|
|
@@ -53,6 +53,8 @@ module RuboCop
|
|
|
53
53
|
end
|
|
54
54
|
|
|
55
55
|
def after_send(node)
|
|
56
|
+
return if backrefs_unaffected?(node)
|
|
57
|
+
|
|
56
58
|
@valid_ref = nil
|
|
57
59
|
|
|
58
60
|
if regexp_first_argument?(node)
|
|
@@ -111,6 +113,19 @@ module RuboCop
|
|
|
111
113
|
end
|
|
112
114
|
end
|
|
113
115
|
|
|
116
|
+
# A call such as `hash[:key]` or `array[0]` cannot involve a regexp match:
|
|
117
|
+
# a non-string literal cannot act as a pattern (whereas `sub`, `gsub`,
|
|
118
|
+
# and `match` treat a string one as a pattern and do set backreferences),
|
|
119
|
+
# and `$~` is frame-local, so a user-defined method cannot change
|
|
120
|
+
# the caller's backreferences either.
|
|
121
|
+
def backrefs_unaffected?(send_node)
|
|
122
|
+
first_argument = send_node.first_argument
|
|
123
|
+
return false unless first_argument&.basic_literal?
|
|
124
|
+
return false if first_argument.str_type?
|
|
125
|
+
|
|
126
|
+
!regexp_receiver?(send_node)
|
|
127
|
+
end
|
|
128
|
+
|
|
114
129
|
def regexp_first_argument?(send_node)
|
|
115
130
|
send_node.first_argument&.regexp_type? \
|
|
116
131
|
&& REGEXP_ARGUMENT_METHODS.include?(send_node.method_name)
|
|
@@ -119,10 +134,6 @@ module RuboCop
|
|
|
119
134
|
def regexp_receiver?(send_node)
|
|
120
135
|
send_node.receiver&.regexp_type?
|
|
121
136
|
end
|
|
122
|
-
|
|
123
|
-
def nth_ref_receiver?(send_node)
|
|
124
|
-
send_node.receiver&.nth_ref_type?
|
|
125
|
-
end
|
|
126
137
|
end
|
|
127
138
|
end
|
|
128
139
|
end
|
|
@@ -46,13 +46,29 @@ module RuboCop
|
|
|
46
46
|
|
|
47
47
|
def valid_first_argument?(first_arg)
|
|
48
48
|
first_arg.operator_keyword? || first_arg.hash_type? || ternary_expression?(first_arg) ||
|
|
49
|
-
compound_range?(first_arg)
|
|
49
|
+
compound_range?(first_arg) || invalid_bare_argument?(first_arg)
|
|
50
50
|
end
|
|
51
51
|
|
|
52
52
|
def compound_range?(first_arg)
|
|
53
53
|
first_arg.range_type? && first_arg.parenthesized_call?
|
|
54
54
|
end
|
|
55
55
|
|
|
56
|
+
def invalid_bare_argument?(node)
|
|
57
|
+
node = node.children.first while node&.begin_type? && node.children.one?
|
|
58
|
+
return false unless node
|
|
59
|
+
|
|
60
|
+
keyword_operator?(node) || modifier_expression?(node)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def keyword_operator?(node)
|
|
64
|
+
(node.operator_keyword? && node.semantic_operator?) ||
|
|
65
|
+
node.rescue_type? || (node.send_type? && node.prefix_not?)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def modifier_expression?(node)
|
|
69
|
+
node.type?(:if, :while, :until) && node.modifier_form?
|
|
70
|
+
end
|
|
71
|
+
|
|
56
72
|
def chained_calls?(node)
|
|
57
73
|
first_argument = node.first_argument
|
|
58
74
|
first_argument.call_type? && (node.children.last&.children&.count || 0) > 1
|
|
@@ -63,19 +79,9 @@ module RuboCop
|
|
|
63
79
|
end
|
|
64
80
|
|
|
65
81
|
def spaces_before_left_parenthesis(node)
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
else
|
|
70
|
-
0
|
|
71
|
-
end
|
|
72
|
-
without_receiver = node.source[receiver_length..]
|
|
73
|
-
|
|
74
|
-
# Escape question mark if any.
|
|
75
|
-
method_regexp = Regexp.escape(node.method_name)
|
|
76
|
-
|
|
77
|
-
match = without_receiver.match(/^\s*&?\.?\s*#{method_regexp}(\s+)\(/)
|
|
78
|
-
match ? match.captures[0].length : 0
|
|
82
|
+
return 0 if node.parenthesized? || !node.first_argument.source.start_with?('(')
|
|
83
|
+
|
|
84
|
+
node.first_argument.source_range.begin_pos - node.loc.selector.end_pos
|
|
79
85
|
end
|
|
80
86
|
|
|
81
87
|
def space_range(expr, space_length)
|