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
|
@@ -12,6 +12,11 @@ module RuboCop
|
|
|
12
12
|
# exception class handle `StandardError` and its subclasses,
|
|
13
13
|
# but not `Exception` and its subclasses.
|
|
14
14
|
#
|
|
15
|
+
# When `AllCops/UseProjectIndex` is enabled and the `rubydex` gem is
|
|
16
|
+
# installed, indirect inheritance is also detected: a class whose parent
|
|
17
|
+
# (defined anywhere in the project) ultimately inherits from `Exception`
|
|
18
|
+
# is reported, without autocorrection.
|
|
19
|
+
#
|
|
15
20
|
# @example EnforcedStyle: standard_error (default)
|
|
16
21
|
# # bad
|
|
17
22
|
#
|
|
@@ -39,9 +44,11 @@ module RuboCop
|
|
|
39
44
|
# C = Class.new(RuntimeError)
|
|
40
45
|
class InheritException < Base
|
|
41
46
|
include ConfigurableEnforcedStyle
|
|
47
|
+
include ProjectIndexHelp
|
|
42
48
|
extend AutoCorrector
|
|
43
49
|
|
|
44
50
|
MSG = 'Inherit from `%<prefer>s` instead of `Exception`.'
|
|
51
|
+
INDIRECT_MSG = 'Inherit from `%<prefer>s` instead of `Exception` (inherited via `%<via>s`).'
|
|
45
52
|
PREFERRED_BASE_CLASS = {
|
|
46
53
|
runtime_error: 'RuntimeError',
|
|
47
54
|
standard_error: 'StandardError'
|
|
@@ -57,13 +64,20 @@ module RuboCop
|
|
|
57
64
|
PATTERN
|
|
58
65
|
|
|
59
66
|
def on_class(node)
|
|
60
|
-
|
|
61
|
-
return
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
+
parent_class = node.parent_class
|
|
68
|
+
return unless parent_class
|
|
69
|
+
|
|
70
|
+
if exception_class?(parent_class)
|
|
71
|
+
return if inherit_exception_class_with_omitted_namespace?(node)
|
|
72
|
+
|
|
73
|
+
add_offense(parent_class, message: message(parent_class)) do |corrector|
|
|
74
|
+
corrector.replace(parent_class, preferred_base_class)
|
|
75
|
+
end
|
|
76
|
+
elsif (via = inherits_exception_via(parent_class))
|
|
77
|
+
# No autocorrection: the `Exception` inheritance lives at another
|
|
78
|
+
# class' definition site, possibly in another file.
|
|
79
|
+
message = format(INDIRECT_MSG, prefer: preferred_base_class, via: via)
|
|
80
|
+
add_offense(parent_class, message: message)
|
|
67
81
|
end
|
|
68
82
|
end
|
|
69
83
|
|
|
@@ -88,6 +102,38 @@ module RuboCop
|
|
|
88
102
|
class_node.const_name == 'Exception'
|
|
89
103
|
end
|
|
90
104
|
|
|
105
|
+
# When `AllCops/UseProjectIndex` is enabled, indirect inheritance is
|
|
106
|
+
# detected by walking the parent's indexed ancestry: `Exception` itself
|
|
107
|
+
# is not indexed, so a chain ending in it shows up as an ancestor whose
|
|
108
|
+
# superclass reference is unresolved and literally named `Exception`.
|
|
109
|
+
# Returns the name of that ancestor, or `nil`.
|
|
110
|
+
def inherits_exception_via(parent_class)
|
|
111
|
+
return nil unless project_index && parent_class.const_type?
|
|
112
|
+
|
|
113
|
+
declaration = resolve_constant_in_index(parent_class)
|
|
114
|
+
return nil unless declaration.is_a?(Rubydex::Class)
|
|
115
|
+
|
|
116
|
+
exception_ancestor(declaration)&.name
|
|
117
|
+
rescue StandardError
|
|
118
|
+
nil
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def exception_ancestor(declaration)
|
|
122
|
+
declaration.ancestors.find do |ancestor|
|
|
123
|
+
ancestor.is_a?(Rubydex::Class) && exception_superclass_reference?(ancestor)
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def exception_superclass_reference?(ancestor)
|
|
128
|
+
ancestor.definitions.any? do |definition|
|
|
129
|
+
next false unless definition.is_a?(Rubydex::ClassDefinition)
|
|
130
|
+
|
|
131
|
+
superclass = definition.superclass
|
|
132
|
+
superclass.is_a?(Rubydex::UnresolvedConstantReference) &&
|
|
133
|
+
superclass.name.delete_prefix('::') == 'Exception'
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
|
|
91
137
|
def inherit_exception_class_with_omitted_namespace?(class_node)
|
|
92
138
|
return false if class_node.parent_class.namespace&.cbase_type?
|
|
93
139
|
|
|
@@ -24,8 +24,25 @@ module RuboCop
|
|
|
24
24
|
MSG = 'Interpolation in single quoted string detected. ' \
|
|
25
25
|
'Use double quoted strings if you need interpolation.'
|
|
26
26
|
|
|
27
|
-
# rubocop:disable Metrics/CyclomaticComplexity
|
|
28
27
|
def on_str(node)
|
|
28
|
+
check(node)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# A multiline single-quoted string is parsed as a `dstr` of `str` segments, so it
|
|
32
|
+
# is not covered by `on_str`. Inspect single-quoted `dstr`s here; double-quoted
|
|
33
|
+
# interpolation is also a `dstr`, hence the delimiter check.
|
|
34
|
+
def on_dstr(node)
|
|
35
|
+
# A heredoc is also a `dstr`, but its `loc` is a `Parser::Source::Map::Heredoc`
|
|
36
|
+
# with no `begin`, so bail before touching it.
|
|
37
|
+
return if heredoc?(node)
|
|
38
|
+
|
|
39
|
+
check(node) if node.loc.begin&.source == "'"
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
private
|
|
43
|
+
|
|
44
|
+
# rubocop:disable-next Metrics/CyclomaticComplexity
|
|
45
|
+
def check(node)
|
|
29
46
|
return if node.parent&.regexp_type?
|
|
30
47
|
return unless /(?<!\\)#\{.*\}/.match?(node.source)
|
|
31
48
|
return if heredoc?(node)
|
|
@@ -34,9 +51,6 @@ module RuboCop
|
|
|
34
51
|
|
|
35
52
|
add_offense(node) { |corrector| autocorrect(corrector, node) }
|
|
36
53
|
end
|
|
37
|
-
# rubocop:enable Metrics/CyclomaticComplexity
|
|
38
|
-
|
|
39
|
-
private
|
|
40
54
|
|
|
41
55
|
def autocorrect(corrector, node)
|
|
42
56
|
starting_token, ending_token = if node.source.include?('"')
|
|
@@ -54,9 +68,14 @@ module RuboCop
|
|
|
54
68
|
end
|
|
55
69
|
|
|
56
70
|
def valid_syntax?(node)
|
|
57
|
-
double_quoted_string = node.source.
|
|
71
|
+
double_quoted_string = if node.source.include?('"')
|
|
72
|
+
node.source.sub(/\A'/, '%{').sub(/'\z/, '}')
|
|
73
|
+
else
|
|
74
|
+
node.source.gsub(/\A'|'\z/, '"')
|
|
75
|
+
end
|
|
58
76
|
|
|
59
|
-
parse(double_quoted_string)
|
|
77
|
+
processed_source = parse(double_quoted_string)
|
|
78
|
+
processed_source.valid_syntax? && processed_source.ast.dstr_type?
|
|
60
79
|
end
|
|
61
80
|
end
|
|
62
81
|
end
|
|
@@ -18,12 +18,15 @@ module RuboCop
|
|
|
18
18
|
# end
|
|
19
19
|
#
|
|
20
20
|
# # bad
|
|
21
|
-
#
|
|
21
|
+
# # We're only interested in the left hand side being a truthy literal,
|
|
22
|
+
# # because it affects the evaluation of the &&, whereas the right hand
|
|
23
|
+
# # side will be conditionally executed/called and can be a literal.
|
|
24
|
+
# if true && some_var
|
|
22
25
|
# do_something
|
|
23
26
|
# end
|
|
24
27
|
#
|
|
25
28
|
# # good
|
|
26
|
-
# if some_var
|
|
29
|
+
# if some_var
|
|
27
30
|
# do_something
|
|
28
31
|
# end
|
|
29
32
|
#
|
|
@@ -34,30 +37,109 @@ module RuboCop
|
|
|
34
37
|
# end
|
|
35
38
|
class LiteralAsCondition < Base
|
|
36
39
|
include RangeHelp
|
|
40
|
+
extend AutoCorrector
|
|
37
41
|
|
|
38
42
|
MSG = 'Literal `%<literal>s` appeared as a condition.'
|
|
39
43
|
RESTRICT_ON_SEND = [:!].freeze
|
|
40
44
|
|
|
45
|
+
def on_and(node)
|
|
46
|
+
return unless node.lhs.truthy_literal?
|
|
47
|
+
|
|
48
|
+
add_offense(node.lhs) do |corrector|
|
|
49
|
+
# Don't autocorrect `'foo' && return` because having `return` as
|
|
50
|
+
# the leftmost node can lead to a void value expression syntax error.
|
|
51
|
+
next if void_value_expression?(node.rhs)
|
|
52
|
+
|
|
53
|
+
corrector.replace(node, node.rhs.source)
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def on_or(node)
|
|
58
|
+
return unless node.lhs.falsey_literal?
|
|
59
|
+
|
|
60
|
+
add_offense(node.lhs) do |corrector|
|
|
61
|
+
# Don't autocorrect `'foo' && return` because having `return` as
|
|
62
|
+
# the leftmost node can lead to a void value expression syntax error.
|
|
63
|
+
next if void_value_expression?(node.rhs)
|
|
64
|
+
|
|
65
|
+
corrector.replace(node, node.rhs.source)
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
41
69
|
def on_if(node)
|
|
42
|
-
|
|
70
|
+
cond = condition(node)
|
|
71
|
+
|
|
72
|
+
return unless cond.falsey_literal? || cond.truthy_literal?
|
|
73
|
+
|
|
74
|
+
correct_if_node(node, cond)
|
|
43
75
|
end
|
|
44
76
|
|
|
45
77
|
def on_while(node)
|
|
46
|
-
return if
|
|
78
|
+
return if node.condition.source == 'true'
|
|
47
79
|
|
|
48
|
-
|
|
80
|
+
if node.condition.truthy_literal?
|
|
81
|
+
add_offense(node.condition) do |corrector|
|
|
82
|
+
corrector.replace(node.condition, 'true')
|
|
83
|
+
end
|
|
84
|
+
elsif node.condition.falsey_literal?
|
|
85
|
+
add_offense(node.condition) do |corrector|
|
|
86
|
+
corrector.remove(node)
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# rubocop:disable-next Metrics/AbcSize
|
|
92
|
+
def on_while_post(node)
|
|
93
|
+
return if node.condition.source == 'true'
|
|
94
|
+
|
|
95
|
+
if node.condition.truthy_literal?
|
|
96
|
+
add_offense(node.condition) do |corrector|
|
|
97
|
+
corrector.replace(node, node.source.sub(node.condition.source, 'true'))
|
|
98
|
+
end
|
|
99
|
+
elsif node.condition.falsey_literal?
|
|
100
|
+
add_offense(node.condition) do |corrector|
|
|
101
|
+
next if orphans_loop_control_keyword?(node)
|
|
102
|
+
|
|
103
|
+
corrector.replace(node, node.body.child_nodes.map(&:source).join("\n"))
|
|
104
|
+
end
|
|
105
|
+
end
|
|
49
106
|
end
|
|
50
|
-
alias on_while_post on_while
|
|
51
107
|
|
|
52
108
|
def on_until(node)
|
|
53
|
-
return if
|
|
109
|
+
return if node.condition.source == 'false'
|
|
54
110
|
|
|
55
|
-
|
|
111
|
+
if node.condition.falsey_literal?
|
|
112
|
+
add_offense(node.condition) do |corrector|
|
|
113
|
+
corrector.replace(node.condition, 'false')
|
|
114
|
+
end
|
|
115
|
+
elsif node.condition.truthy_literal?
|
|
116
|
+
add_offense(node.condition) do |corrector|
|
|
117
|
+
corrector.remove(node)
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
# rubocop:disable-next Metrics/AbcSize
|
|
123
|
+
def on_until_post(node)
|
|
124
|
+
return if node.condition.source == 'false'
|
|
125
|
+
|
|
126
|
+
if node.condition.falsey_literal?
|
|
127
|
+
add_offense(node.condition) do |corrector|
|
|
128
|
+
corrector.replace(node, node.source.sub(node.condition.source, 'false'))
|
|
129
|
+
end
|
|
130
|
+
elsif node.condition.truthy_literal?
|
|
131
|
+
add_offense(node.condition) do |corrector|
|
|
132
|
+
next if orphans_loop_control_keyword?(node)
|
|
133
|
+
|
|
134
|
+
corrector.replace(node, node.body.child_nodes.map(&:source).join("\n"))
|
|
135
|
+
end
|
|
136
|
+
end
|
|
56
137
|
end
|
|
57
|
-
alias on_until_post on_until
|
|
58
138
|
|
|
59
139
|
def on_case(case_node)
|
|
60
|
-
if case_node.condition
|
|
140
|
+
if (cond = case_node.condition)
|
|
141
|
+
return if !cond.falsey_literal? && !cond.truthy_literal?
|
|
142
|
+
|
|
61
143
|
check_case(case_node)
|
|
62
144
|
else
|
|
63
145
|
case_node.when_branches.each do |when_node|
|
|
@@ -77,7 +159,7 @@ module RuboCop
|
|
|
77
159
|
|
|
78
160
|
check_case(case_match_node)
|
|
79
161
|
else
|
|
80
|
-
case_match_node.
|
|
162
|
+
case_match_node.in_pattern_branches.each do |in_pattern_node|
|
|
81
163
|
next unless in_pattern_node.condition.literal?
|
|
82
164
|
|
|
83
165
|
add_offense(in_pattern_node)
|
|
@@ -97,6 +179,21 @@ module RuboCop
|
|
|
97
179
|
|
|
98
180
|
private
|
|
99
181
|
|
|
182
|
+
# Unwrapping the body of a loop that runs once would leave a `break`,
|
|
183
|
+
# `next` or `redo` that belongs to it outside of any loop.
|
|
184
|
+
def orphans_loop_control_keyword?(node)
|
|
185
|
+
node.body.each_node(:next, :break, :redo).any? do |control|
|
|
186
|
+
inner = control.each_ancestor.take_while { |ancestor| !ancestor.equal?(node) }
|
|
187
|
+
inner.none? { |ancestor| ancestor.any_block_type? || ancestor.loop_keyword? }
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
def void_value_expression?(node)
|
|
192
|
+
node = node.children.last while node&.begin_type?
|
|
193
|
+
|
|
194
|
+
node&.type?(:return, :break, :next)
|
|
195
|
+
end
|
|
196
|
+
|
|
100
197
|
def check_for_literal(node)
|
|
101
198
|
cond = condition(node)
|
|
102
199
|
if cond.literal?
|
|
@@ -130,6 +227,8 @@ module RuboCop
|
|
|
130
227
|
|
|
131
228
|
def handle_node(node)
|
|
132
229
|
if node.literal?
|
|
230
|
+
return if node.parent.and_type?
|
|
231
|
+
|
|
133
232
|
add_offense(node)
|
|
134
233
|
elsif %i[send and or begin].include?(node.type)
|
|
135
234
|
check_node(node)
|
|
@@ -159,6 +258,48 @@ module RuboCop
|
|
|
159
258
|
when_node.conditions.last.source_range.end_pos
|
|
160
259
|
)
|
|
161
260
|
end
|
|
261
|
+
|
|
262
|
+
def condition_evaluation?(node, cond)
|
|
263
|
+
if node.unless?
|
|
264
|
+
cond.falsey_literal?
|
|
265
|
+
else
|
|
266
|
+
cond.truthy_literal?
|
|
267
|
+
end
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
# rubocop:disable-next Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
271
|
+
def correct_if_node(node, cond)
|
|
272
|
+
result = condition_evaluation?(node, cond)
|
|
273
|
+
|
|
274
|
+
# When the branch that survives the literal condition is missing,
|
|
275
|
+
# there is no meaningful correction, so no offense is registered.
|
|
276
|
+
surviving_branch = result ? node.if_branch : node.else_branch
|
|
277
|
+
return if surviving_branch.nil? && (node.elsif? || node.else?)
|
|
278
|
+
|
|
279
|
+
new_node = if node.elsif? && result
|
|
280
|
+
"else\n #{range_with_comments(node.if_branch).source}"
|
|
281
|
+
elsif node.elsif? && !result
|
|
282
|
+
"else\n #{node.else_branch.source}"
|
|
283
|
+
elsif node.if_branch && result
|
|
284
|
+
node.if_branch.source
|
|
285
|
+
elsif node.elsif_conditional?
|
|
286
|
+
"#{node.else_branch.source.sub('elsif', 'if')}\nend"
|
|
287
|
+
elsif node.else? || node.ternary?
|
|
288
|
+
node.else_branch.source
|
|
289
|
+
elsif node.value_used?
|
|
290
|
+
'nil'
|
|
291
|
+
else
|
|
292
|
+
'' # Equivalent to removing the node
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
add_offense(cond) do |corrector|
|
|
296
|
+
next if part_of_ignored_node?(node)
|
|
297
|
+
|
|
298
|
+
corrector.replace(node, new_node)
|
|
299
|
+
|
|
300
|
+
ignore_node(node)
|
|
301
|
+
end
|
|
302
|
+
end
|
|
162
303
|
end
|
|
163
304
|
end
|
|
164
305
|
end
|
|
@@ -56,7 +56,17 @@ module RuboCop
|
|
|
56
56
|
def traverse_node(node, &block)
|
|
57
57
|
yield node if node.equals_asgn?
|
|
58
58
|
|
|
59
|
-
node.each_child_node
|
|
59
|
+
node.each_child_node do |child|
|
|
60
|
+
next if scope_body?(node, child)
|
|
61
|
+
|
|
62
|
+
traverse_node(child, &block)
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# An assignment inside a block or method body within the condition belongs to
|
|
67
|
+
# that inner scope rather than the condition itself, so it is not inspected.
|
|
68
|
+
def scope_body?(node, child)
|
|
69
|
+
node.type?(:any_block, :any_def) && child == node.body
|
|
60
70
|
end
|
|
61
71
|
|
|
62
72
|
def all_literals?(node)
|
|
@@ -24,33 +24,18 @@ module RuboCop
|
|
|
24
24
|
MSG = 'Literal interpolation detected.'
|
|
25
25
|
COMPOSITE = %i[array hash pair irange erange].freeze
|
|
26
26
|
|
|
27
|
-
# rubocop:disable Metrics/AbcSize
|
|
28
27
|
def on_interpolation(begin_node)
|
|
29
28
|
final_node = begin_node.children.last
|
|
30
29
|
return unless offending?(final_node)
|
|
31
|
-
|
|
32
|
-
# %W and %I split the content into words before expansion
|
|
33
|
-
# treating each interpolation as a word component, so
|
|
34
|
-
# interpolation should not be removed if the expanded value
|
|
35
|
-
# contains a space character.
|
|
36
|
-
expanded_value = autocorrected_value(final_node)
|
|
37
|
-
expanded_value = handle_special_regexp_chars(begin_node, expanded_value)
|
|
38
|
-
|
|
39
|
-
return if in_array_percent_literal?(begin_node) && /\s|\A\z/.match?(expanded_value)
|
|
30
|
+
return unless (expanded_value = correctable_value(begin_node, final_node))
|
|
40
31
|
|
|
41
32
|
add_offense(final_node) do |corrector|
|
|
42
33
|
next if final_node.dstr_type? # nested, fixed in next iteration
|
|
34
|
+
next if follows_literal_interpolation?(begin_node)
|
|
43
35
|
|
|
44
|
-
|
|
45
|
-
final_node.source.delete_prefix('"').delete_suffix('"')
|
|
46
|
-
else
|
|
47
|
-
expanded_value
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
corrector.replace(final_node.parent, replacement)
|
|
36
|
+
corrector.replace(final_node.parent, replacement(final_node, expanded_value))
|
|
51
37
|
end
|
|
52
38
|
end
|
|
53
|
-
# rubocop:enable Metrics/AbcSize
|
|
54
39
|
|
|
55
40
|
private
|
|
56
41
|
|
|
@@ -66,7 +51,7 @@ module RuboCop
|
|
|
66
51
|
|
|
67
52
|
def special_keyword?(node)
|
|
68
53
|
# handle strings like __FILE__
|
|
69
|
-
(node.str_type? && !node.loc
|
|
54
|
+
(node.str_type? && !node.loc?(:begin)) || node.source_range.is?('__LINE__')
|
|
70
55
|
end
|
|
71
56
|
|
|
72
57
|
def array_in_regexp?(node)
|
|
@@ -74,7 +59,23 @@ module RuboCop
|
|
|
74
59
|
node.array_type? && grandparent.regexp_type?
|
|
75
60
|
end
|
|
76
61
|
|
|
77
|
-
|
|
62
|
+
def correctable_value(begin_node, final_node)
|
|
63
|
+
value = autocorrected_value(final_node)
|
|
64
|
+
value = handle_special_regexp_chars(begin_node, value)
|
|
65
|
+
return if starts_interpolation_after_hash_sign?(begin_node, value)
|
|
66
|
+
|
|
67
|
+
value = escape_trailing_hash_sign(begin_node, value)
|
|
68
|
+
|
|
69
|
+
# %W and %I split the content into words before expansion
|
|
70
|
+
# treating each interpolation as a word component, so
|
|
71
|
+
# interpolation should not be removed if the expanded value
|
|
72
|
+
# contains a space character.
|
|
73
|
+
return if in_array_percent_literal?(begin_node) && /\s|\A\z/.match?(value)
|
|
74
|
+
|
|
75
|
+
value
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# rubocop:disable-next Metrics/MethodLength, Metrics/CyclomaticComplexity
|
|
78
79
|
def autocorrected_value(node)
|
|
79
80
|
case node.type
|
|
80
81
|
when :int
|
|
@@ -95,7 +96,6 @@ module RuboCop
|
|
|
95
96
|
node.source.gsub('"', '\"')
|
|
96
97
|
end
|
|
97
98
|
end
|
|
98
|
-
# rubocop:enable Metrics/MethodLength, Metrics/CyclomaticComplexity
|
|
99
99
|
|
|
100
100
|
def handle_special_regexp_chars(begin_node, value)
|
|
101
101
|
parent_node = begin_node.parent
|
|
@@ -118,12 +118,25 @@ module RuboCop
|
|
|
118
118
|
end
|
|
119
119
|
end
|
|
120
120
|
|
|
121
|
+
def starts_interpolation_after_hash_sign?(begin_node, value)
|
|
122
|
+
source = processed_source.buffer.source
|
|
123
|
+
range = begin_node.source_range
|
|
124
|
+
# Removing an empty value puts the `#` right before what follows the interpolation.
|
|
125
|
+
following = "#{value}#{source[range.end_pos]}"
|
|
126
|
+
return false unless following.start_with?('{', '@', '$')
|
|
127
|
+
return false unless source[range.begin_pos - 1] == '#'
|
|
128
|
+
|
|
129
|
+
unescaped_hash_sign?(source[0...range.begin_pos])
|
|
130
|
+
end
|
|
131
|
+
|
|
121
132
|
def autocorrected_value_for_string(node)
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
133
|
+
return node.source.delete_prefix('"').delete_suffix('"') unless node.value.valid_encoding?
|
|
134
|
+
|
|
135
|
+
escape_string_content(node.children.last)
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def escape_string_content(string)
|
|
139
|
+
string.gsub(/[\\"]|#(?=[@{$])/, '\\\\\&')
|
|
127
140
|
end
|
|
128
141
|
|
|
129
142
|
def autocorrected_value_for_symbol(node)
|
|
@@ -134,12 +147,7 @@ module RuboCop
|
|
|
134
147
|
end
|
|
135
148
|
|
|
136
149
|
def autocorrected_value_in_hash_for_symbol(node)
|
|
137
|
-
|
|
138
|
-
if / |"|'/.match?(node.value.to_s)
|
|
139
|
-
":\\\"#{node.value.to_s.gsub('"') { '\\\\\"' }}\\\""
|
|
140
|
-
else
|
|
141
|
-
":#{node.value}"
|
|
142
|
-
end
|
|
150
|
+
escape_string_content(node.value.inspect)
|
|
143
151
|
end
|
|
144
152
|
|
|
145
153
|
def autocorrected_value_for_array(node)
|
|
@@ -158,7 +166,7 @@ module RuboCop
|
|
|
158
166
|
"{#{hash_string}}"
|
|
159
167
|
end
|
|
160
168
|
|
|
161
|
-
# rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
|
169
|
+
# rubocop:disable-next Metrics/MethodLength, Metrics/AbcSize
|
|
162
170
|
def autocorrected_value_in_hash(node)
|
|
163
171
|
case node.type
|
|
164
172
|
when :int
|
|
@@ -166,7 +174,7 @@ module RuboCop
|
|
|
166
174
|
when :float
|
|
167
175
|
node.children.last.to_f.to_s
|
|
168
176
|
when :str
|
|
169
|
-
|
|
177
|
+
escape_string_content(node.value.inspect)
|
|
170
178
|
when :sym
|
|
171
179
|
autocorrected_value_in_hash_for_symbol(node)
|
|
172
180
|
when :array
|
|
@@ -177,7 +185,6 @@ module RuboCop
|
|
|
177
185
|
node.source.gsub('"', '\"')
|
|
178
186
|
end
|
|
179
187
|
end
|
|
180
|
-
# rubocop:enable Metrics/MethodLength, Metrics/AbcSize
|
|
181
188
|
|
|
182
189
|
# Does node print its own source when converted to a string?
|
|
183
190
|
def prints_as_self?(node)
|
|
@@ -186,7 +193,9 @@ module RuboCop
|
|
|
186
193
|
end
|
|
187
194
|
|
|
188
195
|
def space_literal?(node)
|
|
189
|
-
|
|
196
|
+
# `String#blank?` misses Unicode spaces such as U+3000 that
|
|
197
|
+
# `Layout/TrailingWhitespace` treats as trailing whitespace.
|
|
198
|
+
node.str_type? && node.value.valid_encoding? && node.value.match?(/\A[[:space:]]*\z/)
|
|
190
199
|
end
|
|
191
200
|
|
|
192
201
|
def ends_heredoc_line?(node)
|
|
@@ -194,7 +203,8 @@ module RuboCop
|
|
|
194
203
|
return false unless grandparent&.dstr_type? && grandparent.heredoc?
|
|
195
204
|
|
|
196
205
|
line = processed_source.lines[node.last_line - 1]
|
|
197
|
-
|
|
206
|
+
|
|
207
|
+
line.size == node.parent.source_range.last_column
|
|
198
208
|
end
|
|
199
209
|
|
|
200
210
|
def in_array_percent_literal?(node)
|
|
@@ -204,6 +214,34 @@ module RuboCop
|
|
|
204
214
|
grandparent = parent.parent
|
|
205
215
|
grandparent&.array_type? && grandparent.percent_literal?
|
|
206
216
|
end
|
|
217
|
+
|
|
218
|
+
def escape_trailing_hash_sign(begin_node, value)
|
|
219
|
+
following = processed_source.buffer.source[begin_node.source_range.end_pos]
|
|
220
|
+
return value unless %w[{ @ $].include?(following) && unescaped_hash_sign?(value)
|
|
221
|
+
|
|
222
|
+
"#{value.delete_suffix('#')}\\#"
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
def unescaped_hash_sign?(text)
|
|
226
|
+
text.end_with?('#') && text.delete_suffix('#')[/\\*\z/].length.even?
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
# Each interpolation is checked against the original source, so correcting it in the
|
|
230
|
+
# same pass as a preceding one that leaves a `#` (or nothing) could join that `#` and
|
|
231
|
+
# a `{` from this one. It's left for the next iteration instead.
|
|
232
|
+
def follows_literal_interpolation?(begin_node)
|
|
233
|
+
previous = begin_node.left_sibling
|
|
234
|
+
return false unless previous&.begin_type? && offending?(previous.children.last)
|
|
235
|
+
|
|
236
|
+
value = correctable_value(previous, previous.children.last)
|
|
237
|
+
value && (value.empty? || value.end_with?('#'))
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
def replacement(node, expanded_value)
|
|
241
|
+
return expanded_value unless node.str_type? && !node.value.valid_encoding?
|
|
242
|
+
|
|
243
|
+
node.source.delete_prefix('"').delete_suffix('"')
|
|
244
|
+
end
|
|
207
245
|
end
|
|
208
246
|
end
|
|
209
247
|
end
|
|
@@ -42,6 +42,8 @@ module RuboCop
|
|
|
42
42
|
# break if some_condition
|
|
43
43
|
# end
|
|
44
44
|
class Loop < Base
|
|
45
|
+
include Alignment
|
|
46
|
+
include RangeHelp
|
|
45
47
|
extend AutoCorrector
|
|
46
48
|
|
|
47
49
|
MSG = 'Use `Kernel#loop` with `break` rather than `begin/end/until`(or `while`).'
|
|
@@ -62,7 +64,8 @@ module RuboCop
|
|
|
62
64
|
add_offense(node.loc.keyword) do |corrector|
|
|
63
65
|
corrector.replace(body.loc.begin, 'loop do')
|
|
64
66
|
corrector.remove(keyword_and_condition_range(node))
|
|
65
|
-
|
|
67
|
+
|
|
68
|
+
insert_break_line(corrector, node, body)
|
|
66
69
|
end
|
|
67
70
|
end
|
|
68
71
|
|
|
@@ -70,9 +73,28 @@ module RuboCop
|
|
|
70
73
|
node.body.loc.end.end.join(node.source_range.end)
|
|
71
74
|
end
|
|
72
75
|
|
|
76
|
+
def insert_break_line(corrector, node, body)
|
|
77
|
+
if body.single_line?
|
|
78
|
+
corrector.replace(space_before_end(body), build_break_line(node))
|
|
79
|
+
else
|
|
80
|
+
corrector.insert_before(body.loc.end, build_break_line(node))
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def space_before_end(body)
|
|
85
|
+
range = range_with_surrounding_space(range: body.loc.end, side: :left, newlines: false)
|
|
86
|
+
|
|
87
|
+
range.with(end_pos: body.loc.end.begin_pos)
|
|
88
|
+
end
|
|
89
|
+
|
|
73
90
|
def build_break_line(node)
|
|
74
91
|
conditional_keyword = node.while_post_type? ? 'unless' : 'if'
|
|
75
|
-
"break #{conditional_keyword} #{node.condition.source}\n#{indent(node)}"
|
|
92
|
+
break_line = "break #{conditional_keyword} #{node.condition.source}\n#{indent(node)}"
|
|
93
|
+
return break_line unless node.body.single_line?
|
|
94
|
+
|
|
95
|
+
# A single-line `begin ... end` keeps its body and `end` on one line,
|
|
96
|
+
# so the `break` has to start a line of its own.
|
|
97
|
+
"\n#{indent(node, offset: configured_indentation_width)}#{break_line}"
|
|
76
98
|
end
|
|
77
99
|
end
|
|
78
100
|
end
|