rubocop 1.53.0 → 1.90.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 +93 -88
- data/assets/output.css.erb +159 -0
- data/assets/output.html.erb +1 -160
- data/config/default.yml +949 -185
- data/config/internal_affairs.yml +31 -0
- data/config/obsoletion.yml +43 -4
- data/exe/rubocop +2 -8
- data/lib/rubocop/cache_config.rb +29 -0
- data/lib/rubocop/cached_data.rb +28 -7
- data/lib/rubocop/cli/command/auto_generate_config.rb +63 -18
- data/lib/rubocop/cli/command/execute_runner.rb +35 -4
- data/lib/rubocop/cli/command/list_enabled_cops_for.rb +40 -0
- data/lib/rubocop/cli/command/lsp.rb +4 -4
- data/lib/rubocop/cli/command/mcp.rb +19 -0
- data/lib/rubocop/cli/command/show_cops.rb +26 -4
- data/lib/rubocop/cli/command/show_docs_url.rb +5 -9
- data/lib/rubocop/cli/command/suggest_extensions.rb +8 -2
- data/lib/rubocop/cli/command/version.rb +2 -2
- data/lib/rubocop/cli.rb +60 -16
- data/lib/rubocop/comment_config/directive_range.rb +32 -0
- data/lib/rubocop/comment_config/disable_next.rb +97 -0
- data/lib/rubocop/comment_config.rb +123 -49
- data/lib/rubocop/config.rb +180 -35
- data/lib/rubocop/config_finder.rb +15 -5
- data/lib/rubocop/config_loader.rb +83 -59
- data/lib/rubocop/config_loader_resolver.rb +65 -25
- data/lib/rubocop/config_obsoletion/extracted_cop.rb +6 -3
- data/lib/rubocop/config_obsoletion/parameter_rule.rb +9 -1
- data/lib/rubocop/config_obsoletion/renamed_cop.rb +18 -3
- data/lib/rubocop/config_obsoletion.rb +56 -9
- data/lib/rubocop/config_store.rb +7 -2
- data/lib/rubocop/config_validator.rb +76 -21
- data/lib/rubocop/cop/autocorrect_logic.rb +70 -25
- data/lib/rubocop/cop/badge.rb +8 -0
- data/lib/rubocop/cop/base.rb +151 -30
- data/lib/rubocop/cop/bundler/duplicated_gem.rb +3 -2
- data/lib/rubocop/cop/bundler/duplicated_group.rb +127 -0
- data/lib/rubocop/cop/bundler/gem_comment.rb +6 -4
- data/lib/rubocop/cop/bundler/gem_filename.rb +0 -1
- data/lib/rubocop/cop/bundler/gem_version.rb +32 -33
- data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +0 -1
- data/lib/rubocop/cop/bundler/ordered_gems.rb +11 -4
- data/lib/rubocop/cop/bundler.rb +19 -0
- data/lib/rubocop/cop/commissioner.rb +13 -11
- data/lib/rubocop/cop/cop.rb +30 -4
- data/lib/rubocop/cop/corrector.rb +4 -4
- data/lib/rubocop/cop/correctors/alignment_corrector.rb +80 -22
- data/lib/rubocop/cop/correctors/condition_corrector.rb +1 -1
- data/lib/rubocop/cop/correctors/each_to_for_corrector.rb +5 -9
- data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +13 -16
- data/lib/rubocop/cop/correctors/lambda_literal_to_method_corrector.rb +14 -5
- data/lib/rubocop/cop/correctors/line_break_corrector.rb +2 -0
- 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 +37 -3
- data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +10 -0
- data/lib/rubocop/cop/correctors.rb +28 -0
- data/lib/rubocop/cop/documentation.rb +31 -5
- data/lib/rubocop/cop/exclude_limit.rb +32 -6
- data/lib/rubocop/cop/force.rb +12 -0
- data/lib/rubocop/cop/gemspec/add_runtime_dependency.rb +38 -0
- data/lib/rubocop/cop/gemspec/attribute_assignment.rb +91 -0
- data/lib/rubocop/cop/gemspec/dependency_version.rb +3 -5
- data/lib/rubocop/cop/gemspec/deprecated_attribute_assignment.rb +3 -4
- data/lib/rubocop/cop/gemspec/development_dependencies.rb +1 -1
- data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +51 -19
- data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +11 -4
- data/lib/rubocop/cop/gemspec/require_mfa.rb +22 -5
- data/lib/rubocop/cop/gemspec/required_ruby_version.rb +5 -3
- data/lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb +15 -10
- data/lib/rubocop/cop/gemspec.rb +22 -0
- data/lib/rubocop/cop/generator/registration_injector.rb +188 -0
- data/lib/rubocop/cop/generator/require_file_injector.rb +1 -1
- data/lib/rubocop/cop/generator.rb +10 -0
- data/lib/rubocop/cop/internal_affairs/cop_description.rb +0 -4
- data/lib/rubocop/cop/internal_affairs/cop_enabled.rb +85 -0
- data/lib/rubocop/cop/internal_affairs/empty_line_between_expect_offense_and_correction.rb +2 -1
- data/lib/rubocop/cop/internal_affairs/example_description.rb +51 -25
- 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_expression.rb +2 -1
- data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +7 -5
- data/lib/rubocop/cop/internal_affairs/method_name_end_with.rb +8 -6
- data/lib/rubocop/cop/internal_affairs/method_name_equal.rb +19 -20
- data/lib/rubocop/cop/internal_affairs/node_first_or_last_argument.rb +54 -0
- data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +132 -39
- data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_processor.rb +63 -0
- data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_walker.rb +130 -0
- data/lib/rubocop/cop/internal_affairs/node_pattern_groups.rb +233 -0
- data/lib/rubocop/cop/internal_affairs/node_type_group.rb +92 -0
- data/lib/rubocop/cop/internal_affairs/node_type_multiple_predicates.rb +126 -0
- data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +4 -3
- data/lib/rubocop/cop/internal_affairs/numblock_handler.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/on_send_without_on_csend.rb +90 -0
- data/lib/rubocop/cop/internal_affairs/operator_keyword.rb +48 -0
- data/lib/rubocop/cop/internal_affairs/plugin.rb +33 -0
- data/lib/rubocop/cop/internal_affairs/redundant_described_class_as_subject.rb +6 -5
- data/lib/rubocop/cop/internal_affairs/redundant_expect_offense_arguments.rb +34 -0
- data/lib/rubocop/cop/internal_affairs/redundant_let_rubocop_config_new.rb +5 -3
- data/lib/rubocop/cop/internal_affairs/redundant_message_argument.rb +6 -21
- data/lib/rubocop/cop/internal_affairs/redundant_method_dispatch_node.rb +11 -2
- data/lib/rubocop/cop/internal_affairs/redundant_source_range.rb +11 -2
- data/lib/rubocop/cop/internal_affairs/single_line_comparison.rb +5 -4
- data/lib/rubocop/cop/internal_affairs/style_detected_api_use.rb +0 -2
- data/lib/rubocop/cop/internal_affairs/undefined_config.rb +23 -2
- data/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +6 -9
- data/lib/rubocop/cop/internal_affairs/useless_restrict_on_send.rb +1 -1
- data/lib/rubocop/cop/internal_affairs.rb +10 -0
- data/lib/rubocop/cop/layout/access_modifier_indentation.rb +6 -2
- data/lib/rubocop/cop/layout/argument_alignment.rb +4 -11
- data/lib/rubocop/cop/layout/array_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/assignment_indentation.rb +3 -2
- data/lib/rubocop/cop/layout/begin_end_alignment.rb +1 -2
- data/lib/rubocop/cop/layout/block_alignment.rb +89 -17
- data/lib/rubocop/cop/layout/block_end_newline.rb +1 -0
- data/lib/rubocop/cop/layout/case_indentation.rb +4 -2
- data/lib/rubocop/cop/layout/class_structure.rb +171 -43
- data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +5 -5
- data/lib/rubocop/cop/layout/comment_indentation.rb +10 -3
- data/lib/rubocop/cop/layout/condition_position.rb +13 -7
- data/lib/rubocop/cop/layout/def_end_alignment.rb +2 -2
- data/lib/rubocop/cop/layout/dot_position.rb +3 -7
- data/lib/rubocop/cop/layout/else_alignment.rb +2 -15
- data/lib/rubocop/cop/layout/empty_comment.rb +11 -11
- data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +66 -15
- data/lib/rubocop/cop/layout/empty_line_after_magic_comment.rb +75 -10
- data/lib/rubocop/cop/layout/empty_line_after_multiline_condition.rb +1 -1
- data/lib/rubocop/cop/layout/empty_line_between_defs.rb +71 -20
- data/lib/rubocop/cop/layout/empty_lines_after_module_inclusion.rb +101 -0
- data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +37 -7
- data/lib/rubocop/cop/layout/empty_lines_around_arguments.rb +8 -29
- data/lib/rubocop/cop/layout/empty_lines_around_attribute_accessor.rb +1 -0
- data/lib/rubocop/cop/layout/empty_lines_around_begin_body.rb +5 -6
- data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +13 -2
- 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 +12 -8
- data/lib/rubocop/cop/layout/empty_lines_around_method_body.rb +23 -1
- data/lib/rubocop/cop/layout/empty_lines_around_module_body.rb +16 -2
- data/lib/rubocop/cop/layout/end_alignment.rb +24 -6
- data/lib/rubocop/cop/layout/extra_spacing.rb +110 -14
- data/lib/rubocop/cop/layout/first_argument_indentation.rb +59 -11
- data/lib/rubocop/cop/layout/first_array_element_indentation.rb +20 -11
- data/lib/rubocop/cop/layout/first_array_element_line_break.rb +26 -0
- data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +22 -22
- data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +26 -26
- data/lib/rubocop/cop/layout/first_method_argument_line_break.rb +8 -0
- data/lib/rubocop/cop/layout/first_parameter_indentation.rb +3 -3
- data/lib/rubocop/cop/layout/hash_alignment.rb +11 -12
- data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +6 -5
- data/lib/rubocop/cop/layout/heredoc_indentation.rb +38 -5
- data/lib/rubocop/cop/layout/indentation_style.rb +1 -1
- data/lib/rubocop/cop/layout/indentation_width.rb +168 -22
- data/lib/rubocop/cop/layout/leading_comment_space.rb +111 -2
- data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +28 -11
- data/lib/rubocop/cop/layout/line_continuation_spacing.rb +9 -4
- data/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb +4 -2
- data/lib/rubocop/cop/layout/line_length.rb +271 -37
- data/lib/rubocop/cop/layout/multiline_array_brace_layout.rb +57 -57
- data/lib/rubocop/cop/layout/multiline_assignment_layout.rb +8 -2
- data/lib/rubocop/cop/layout/multiline_block_layout.rb +3 -0
- data/lib/rubocop/cop/layout/multiline_hash_brace_layout.rb +56 -56
- data/lib/rubocop/cop/layout/multiline_hash_key_line_breaks.rb +1 -1
- data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +25 -0
- data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +3 -2
- data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +252 -32
- data/lib/rubocop/cop/layout/multiline_method_definition_brace_layout.rb +1 -1
- data/lib/rubocop/cop/layout/multiline_method_parameter_line_breaks.rb +1 -0
- data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +11 -8
- data/lib/rubocop/cop/layout/parameter_alignment.rb +3 -4
- data/lib/rubocop/cop/layout/redundant_line_break.rb +117 -42
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +17 -9
- data/lib/rubocop/cop/layout/single_line_block_chain.rb +6 -1
- data/lib/rubocop/cop/layout/space_after_colon.rb +2 -2
- data/lib/rubocop/cop/layout/space_after_comma.rb +3 -3
- data/lib/rubocop/cop/layout/space_after_method_name.rb +1 -1
- data/lib/rubocop/cop/layout/space_after_not.rb +1 -1
- data/lib/rubocop/cop/layout/space_after_semicolon.rb +12 -2
- data/lib/rubocop/cop/layout/space_around_block_parameters.rb +1 -1
- data/lib/rubocop/cop/layout/space_around_keyword.rb +12 -4
- data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +3 -3
- data/lib/rubocop/cop/layout/space_around_operators.rb +94 -38
- data/lib/rubocop/cop/layout/space_before_block_braces.rb +20 -10
- data/lib/rubocop/cop/layout/space_before_brackets.rb +8 -41
- data/lib/rubocop/cop/layout/space_before_comma.rb +1 -1
- data/lib/rubocop/cop/layout/space_before_semicolon.rb +1 -1
- data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +9 -8
- data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +48 -36
- data/lib/rubocop/cop/layout/space_inside_block_braces.rb +5 -0
- data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +8 -1
- data/lib/rubocop/cop/layout/space_inside_parens.rb +1 -1
- data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +3 -5
- data/lib/rubocop/cop/layout/trailing_empty_lines.rb +5 -0
- data/lib/rubocop/cop/layout/trailing_whitespace.rb +6 -4
- data/lib/rubocop/cop/layout.rb +114 -0
- data/lib/rubocop/cop/lazy_loader.rb +41 -0
- data/lib/rubocop/cop/legacy/corrector.rb +12 -2
- data/lib/rubocop/cop/lint/ambiguous_assignment.rb +9 -17
- data/lib/rubocop/cop/lint/ambiguous_block_association.rb +73 -4
- data/lib/rubocop/cop/lint/ambiguous_operator.rb +0 -2
- data/lib/rubocop/cop/lint/ambiguous_operator_precedence.rb +1 -10
- data/lib/rubocop/cop/lint/ambiguous_range.rb +8 -1
- data/lib/rubocop/cop/lint/ambiguous_regexp_literal.rb +0 -2
- data/lib/rubocop/cop/lint/argument_mismatch.rb +89 -0
- data/lib/rubocop/cop/lint/array_literal_in_regexp.rb +118 -0
- data/lib/rubocop/cop/lint/assignment_in_condition.rb +20 -10
- data/lib/rubocop/cop/lint/big_decimal_new.rb +4 -7
- data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +11 -13
- data/lib/rubocop/cop/lint/boolean_symbol.rb +2 -4
- data/lib/rubocop/cop/lint/circular_argument_reference.rb +49 -17
- data/lib/rubocop/cop/lint/constant_definition_in_block.rb +3 -3
- data/lib/rubocop/cop/lint/constant_overwritten_in_rescue.rb +4 -3
- data/lib/rubocop/cop/lint/constant_reassignment.rb +227 -0
- data/lib/rubocop/cop/lint/constant_resolution.rb +31 -6
- data/lib/rubocop/cop/lint/cop_directive_syntax.rb +166 -0
- data/lib/rubocop/cop/lint/data_define_override.rb +63 -0
- data/lib/rubocop/cop/lint/debugger.rb +53 -9
- data/lib/rubocop/cop/lint/deprecated_class_methods.rb +2 -2
- data/lib/rubocop/cop/lint/deprecated_constants.rb +2 -8
- data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +7 -13
- data/lib/rubocop/cop/lint/deprecated_reference.rb +194 -0
- data/lib/rubocop/cop/lint/duplicate_branch.rb +39 -4
- data/lib/rubocop/cop/lint/duplicate_case_condition.rb +1 -5
- data/lib/rubocop/cop/lint/duplicate_hash_key.rb +0 -4
- data/lib/rubocop/cop/lint/duplicate_match_pattern.rb +5 -5
- data/lib/rubocop/cop/lint/duplicate_methods.rb +504 -49
- data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +6 -43
- data/lib/rubocop/cop/lint/duplicate_set_element.rb +87 -0
- data/lib/rubocop/cop/lint/each_with_object_argument.rb +0 -4
- data/lib/rubocop/cop/lint/else_layout.rb +19 -2
- data/lib/rubocop/cop/lint/empty_block.rb +5 -5
- data/lib/rubocop/cop/lint/empty_conditional_body.rb +33 -57
- data/lib/rubocop/cop/lint/empty_ensure.rb +2 -12
- data/lib/rubocop/cop/lint/empty_expression.rb +0 -2
- data/lib/rubocop/cop/lint/empty_file.rb +0 -2
- data/lib/rubocop/cop/lint/empty_in_pattern.rb +8 -1
- data/lib/rubocop/cop/lint/empty_interpolation.rb +14 -5
- data/lib/rubocop/cop/lint/empty_when.rb +9 -4
- data/lib/rubocop/cop/lint/ensure_return.rb +20 -10
- data/lib/rubocop/cop/lint/erb_new_arguments.rb +28 -25
- data/lib/rubocop/cop/lint/float_comparison.rb +59 -15
- data/lib/rubocop/cop/lint/float_out_of_range.rb +2 -8
- data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +2 -12
- data/lib/rubocop/cop/lint/hash_compare_by_identity.rb +2 -1
- data/lib/rubocop/cop/lint/hash_new_with_keyword_arguments_as_default.rb +55 -0
- data/lib/rubocop/cop/lint/identity_comparison.rb +19 -15
- data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +22 -12
- data/lib/rubocop/cop/lint/incompatible_io_select_with_fiber_scheduler.rb +5 -1
- data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +1 -9
- data/lib/rubocop/cop/lint/inherit_exception.rb +53 -7
- data/lib/rubocop/cop/lint/interpolation_check.rb +30 -6
- data/lib/rubocop/cop/lint/it_without_arguments_in_block.rb +50 -0
- data/lib/rubocop/cop/lint/lambda_without_literal_block.rb +1 -1
- data/lib/rubocop/cop/lint/literal_as_condition.rb +133 -12
- data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +95 -0
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +61 -30
- data/lib/rubocop/cop/lint/loop.rb +6 -12
- data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +44 -22
- data/lib/rubocop/cop/lint/missing_super.rb +33 -3
- data/lib/rubocop/cop/lint/mixed_case_range.rb +16 -12
- data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +1 -1
- 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 +10 -12
- data/lib/rubocop/cop/lint/next_without_accumulator.rb +8 -25
- data/lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +22 -7
- data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +22 -10
- data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +10 -10
- data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +4 -4
- data/lib/rubocop/cop/lint/number_conversion.rb +28 -15
- data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +2 -3
- data/lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +104 -0
- data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +2 -3
- data/lib/rubocop/cop/lint/ordered_magic_comments.rb +7 -7
- data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +18 -6
- data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +9 -24
- data/lib/rubocop/cop/lint/percent_string_array.rb +0 -4
- data/lib/rubocop/cop/lint/percent_symbol_array.rb +0 -4
- data/lib/rubocop/cop/lint/raise_exception.rb +30 -11
- data/lib/rubocop/cop/lint/rand_one.rb +1 -5
- data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +126 -30
- data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +57 -21
- data/lib/rubocop/cop/lint/redundant_dir_glob_sort.rb +15 -4
- data/lib/rubocop/cop/lint/redundant_regexp_quantifiers.rb +12 -2
- data/lib/rubocop/cop/lint/redundant_require_statement.rb +5 -21
- data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +206 -15
- data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +20 -10
- data/lib/rubocop/cop/lint/redundant_string_coercion.rb +2 -6
- data/lib/rubocop/cop/lint/redundant_type_conversion.rb +267 -0
- data/lib/rubocop/cop/lint/redundant_with_index.rb +9 -3
- data/lib/rubocop/cop/lint/redundant_with_object.rb +10 -2
- data/lib/rubocop/cop/lint/refinement_import_methods.rb +9 -2
- data/lib/rubocop/cop/lint/regexp_as_condition.rb +9 -2
- data/lib/rubocop/cop/lint/require_parentheses.rb +13 -8
- 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 +2 -9
- data/lib/rubocop/cop/lint/rescue_type.rb +6 -12
- data/lib/rubocop/cop/lint/return_in_void_context.rb +9 -13
- data/lib/rubocop/cop/lint/safe_navigation_chain.rb +55 -13
- data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +113 -41
- data/lib/rubocop/cop/lint/safe_navigation_with_empty.rb +1 -1
- data/lib/rubocop/cop/lint/script_permission.rb +7 -3
- data/lib/rubocop/cop/lint/self_assignment.rb +103 -10
- data/lib/rubocop/cop/lint/send_with_mixin_argument.rb +1 -1
- data/lib/rubocop/cop/lint/shadowed_argument.rb +8 -7
- data/lib/rubocop/cop/lint/shadowed_exception.rb +2 -2
- data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +40 -12
- data/lib/rubocop/cop/lint/shared_mutable_default.rb +78 -0
- data/lib/rubocop/cop/lint/struct_new_override.rb +29 -13
- data/lib/rubocop/cop/lint/super_argument_mismatch.rb +179 -0
- data/lib/rubocop/cop/lint/suppressed_exception.rb +2 -2
- data/lib/rubocop/cop/lint/suppressed_exception_in_number_conversion.rb +122 -0
- data/lib/rubocop/cop/lint/symbol_conversion.rb +26 -4
- data/lib/rubocop/cop/lint/syntax.rb +35 -5
- data/lib/rubocop/cop/lint/to_enum_arguments.rb +77 -9
- 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 +114 -0
- data/lib/rubocop/cop/lint/unexpected_block_arity.rb +3 -1
- data/lib/rubocop/cop/lint/unified_integer.rb +0 -4
- data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +5 -3
- data/lib/rubocop/cop/lint/unreachable_code.rb +68 -15
- data/lib/rubocop/cop/lint/unreachable_loop.rb +14 -8
- data/lib/rubocop/cop/lint/unreachable_pattern_branch.rb +113 -0
- data/lib/rubocop/cop/lint/unused_method_argument.rb +28 -2
- 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/uri_regexp.rb +25 -7
- data/lib/rubocop/cop/lint/useless_access_modifier.rb +37 -12
- data/lib/rubocop/cop/lint/useless_assignment.rb +92 -34
- 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_defined.rb +55 -0
- data/lib/rubocop/cop/lint/useless_else_without_rescue.rb +4 -4
- data/lib/rubocop/cop/lint/useless_method_definition.rb +1 -1
- data/lib/rubocop/cop/lint/useless_numeric_operation.rb +79 -0
- data/lib/rubocop/cop/lint/useless_or.rb +111 -0
- data/lib/rubocop/cop/lint/useless_rescue.rb +3 -4
- data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +14 -8
- data/lib/rubocop/cop/lint/useless_setter_call.rb +17 -29
- data/lib/rubocop/cop/lint/useless_times.rb +24 -3
- data/lib/rubocop/cop/lint/utils/nil_receiver_checker.rb +201 -0
- data/lib/rubocop/cop/lint/void.rb +127 -29
- data/lib/rubocop/cop/lint.rb +178 -0
- data/lib/rubocop/cop/message_annotator.rb +7 -3
- data/lib/rubocop/cop/metrics/abc_size.rb +4 -4
- data/lib/rubocop/cop/metrics/block_length.rb +9 -7
- data/lib/rubocop/cop/metrics/block_nesting.rb +43 -8
- data/lib/rubocop/cop/metrics/class_length.rb +23 -17
- data/lib/rubocop/cop/metrics/collection_literal_length.rb +8 -1
- data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +5 -2
- data/lib/rubocop/cop/metrics/method_length.rb +17 -8
- data/lib/rubocop/cop/metrics/module_length.rb +7 -6
- data/lib/rubocop/cop/metrics/perceived_complexity.rb +38 -8
- data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +5 -4
- data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +39 -12
- 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 +8 -4
- data/lib/rubocop/cop/mixin/allowed_methods.rb +12 -6
- data/lib/rubocop/cop/mixin/allowed_pattern.rb +20 -4
- data/lib/rubocop/cop/mixin/annotation_comment.rb +0 -2
- data/lib/rubocop/cop/mixin/check_assignment.rb +4 -12
- data/lib/rubocop/cop/mixin/check_line_breakable.rb +46 -18
- data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +47 -0
- data/lib/rubocop/cop/mixin/code_length.rb +12 -1
- data/lib/rubocop/cop/mixin/comments_help.rb +22 -14
- data/lib/rubocop/cop/mixin/configurable_enforced_style.rb +1 -2
- data/lib/rubocop/cop/mixin/configurable_formatting.rb +1 -0
- data/lib/rubocop/cop/mixin/configurable_max.rb +11 -6
- data/lib/rubocop/cop/mixin/def_node.rb +1 -1
- data/lib/rubocop/cop/mixin/dig_help.rb +27 -0
- data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +1 -1
- data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +1 -7
- data/lib/rubocop/cop/mixin/endless_method_rewriter.rb +32 -0
- 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 +23 -12
- data/lib/rubocop/cop/mixin/gemspec_help.rb +22 -0
- data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +33 -15
- data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +49 -40
- data/lib/rubocop/cop/mixin/hash_subset.rb +210 -0
- 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/heredoc.rb +6 -2
- data/lib/rubocop/cop/mixin/indexed_method_arity.rb +94 -0
- data/lib/rubocop/cop/mixin/line_length_help.rb +61 -14
- data/lib/rubocop/cop/mixin/method_complexity.rb +17 -7
- data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +11 -12
- data/lib/rubocop/cop/mixin/multiline_literal_brace_layout.rb +1 -1
- data/lib/rubocop/cop/mixin/ordered_gem_node.rb +1 -1
- data/lib/rubocop/cop/mixin/percent_array.rb +1 -1
- data/lib/rubocop/cop/mixin/percent_literal.rb +1 -1
- data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +120 -39
- data/lib/rubocop/cop/mixin/project_index_help.rb +188 -0
- data/lib/rubocop/cop/mixin/range_help.rb +16 -6
- data/lib/rubocop/cop/mixin/reparsed_equivalence.rb +171 -0
- data/lib/rubocop/cop/mixin/rescue_node.rb +4 -0
- data/lib/rubocop/cop/mixin/safe_assignment.rb +1 -1
- data/lib/rubocop/cop/mixin/space_after_punctuation.rb +5 -4
- data/lib/rubocop/cop/mixin/statement_modifier.rb +57 -15
- data/lib/rubocop/cop/mixin/string_help.rb +5 -3
- data/lib/rubocop/cop/mixin/string_literals_help.rb +12 -0
- data/lib/rubocop/cop/mixin/target_ruby_version.rb +17 -1
- data/lib/rubocop/cop/mixin/trailing_comma.rb +27 -10
- data/lib/rubocop/cop/mixin.rb +91 -0
- data/lib/rubocop/cop/naming/accessor_method_name.rb +35 -6
- data/lib/rubocop/cop/naming/binary_operator_parameter_name.rb +17 -1
- data/lib/rubocop/cop/naming/block_forwarding.rb +39 -8
- data/lib/rubocop/cop/naming/block_parameter_name.rb +1 -1
- data/lib/rubocop/cop/naming/constant_name.rb +7 -9
- data/lib/rubocop/cop/naming/file_name.rb +9 -10
- data/lib/rubocop/cop/naming/heredoc_delimiter_naming.rb +3 -1
- data/lib/rubocop/cop/naming/inclusive_language.rb +21 -7
- data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +25 -19
- 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_prefix.rb +232 -0
- data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +23 -17
- data/lib/rubocop/cop/naming/variable_name.rb +50 -6
- data/lib/rubocop/cop/naming/variable_number.rb +5 -4
- data/lib/rubocop/cop/naming.rb +31 -0
- data/lib/rubocop/cop/offense.rb +56 -14
- data/lib/rubocop/cop/registry.rb +225 -64
- data/lib/rubocop/cop/security/compound_hash.rb +4 -2
- 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 +33 -11
- data/lib/rubocop/cop/security/marshal_load.rb +1 -1
- data/lib/rubocop/cop/security/open.rb +3 -2
- data/lib/rubocop/cop/security/yaml_load.rb +3 -2
- data/lib/rubocop/cop/security.rb +19 -0
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +184 -33
- data/lib/rubocop/cop/style/accessor_grouping.rb +56 -11
- data/lib/rubocop/cop/style/alias.rb +26 -12
- data/lib/rubocop/cop/style/ambiguous_endless_method_definition.rb +79 -0
- data/lib/rubocop/cop/style/and_or.rb +3 -2
- data/lib/rubocop/cop/style/arguments_forwarding.rb +487 -63
- data/lib/rubocop/cop/style/array_first_last.rb +90 -0
- data/lib/rubocop/cop/style/array_intersect.rb +148 -41
- 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 +5 -2
- data/lib/rubocop/cop/style/auto_resource_cleanup.rb +21 -14
- 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/bisected_attr_accessor.rb +2 -2
- data/lib/rubocop/cop/style/bitwise_predicate.rb +106 -0
- data/lib/rubocop/cop/style/block_delimiters.rb +89 -53
- data/lib/rubocop/cop/style/case_equality.rb +29 -15
- data/lib/rubocop/cop/style/case_like_if.rb +16 -21
- data/lib/rubocop/cop/style/character_literal.rb +2 -2
- data/lib/rubocop/cop/style/class_and_module_children.rb +139 -22
- data/lib/rubocop/cop/style/class_check.rb +1 -0
- data/lib/rubocop/cop/style/class_equality_comparison.rb +29 -14
- data/lib/rubocop/cop/style/class_methods_definitions.rb +11 -5
- data/lib/rubocop/cop/style/class_vars.rb +3 -3
- data/lib/rubocop/cop/style/collection_compact.rb +53 -23
- data/lib/rubocop/cop/style/collection_methods.rb +4 -1
- 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_defined.rb +115 -0
- data/lib/rubocop/cop/style/combinable_loops.rb +29 -9
- data/lib/rubocop/cop/style/command_literal.rb +1 -1
- data/lib/rubocop/cop/style/commented_keyword.rb +30 -4
- 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 +11 -5
- data/lib/rubocop/cop/style/conditional_assignment.rb +85 -56
- data/lib/rubocop/cop/style/constant_visibility.rb +21 -23
- data/lib/rubocop/cop/style/copyright.rb +49 -24
- data/lib/rubocop/cop/style/data_inheritance.rb +12 -1
- data/lib/rubocop/cop/style/date_time.rb +8 -7
- data/lib/rubocop/cop/style/def_with_parentheses.rb +22 -7
- data/lib/rubocop/cop/style/dig_chain.rb +94 -0
- data/lib/rubocop/cop/style/dir_empty.rb +4 -0
- data/lib/rubocop/cop/style/directive_scope.rb +171 -0
- data/lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb +77 -13
- data/lib/rubocop/cop/style/document_dynamic_eval_definition.rb +6 -1
- data/lib/rubocop/cop/style/documentation.rb +76 -29
- data/lib/rubocop/cop/style/documentation_method.rb +24 -0
- data/lib/rubocop/cop/style/double_negation.rb +5 -5
- data/lib/rubocop/cop/style/each_for_simple_loop.rb +12 -16
- data/lib/rubocop/cop/style/each_with_object.rb +5 -4
- data/lib/rubocop/cop/style/empty_block_parameter.rb +1 -1
- data/lib/rubocop/cop/style/empty_case_condition.rb +16 -2
- data/lib/rubocop/cop/style/empty_class_definition.rb +126 -0
- data/lib/rubocop/cop/style/empty_else.rb +10 -7
- data/lib/rubocop/cop/style/empty_heredoc.rb +5 -14
- data/lib/rubocop/cop/style/empty_lambda_parameter.rb +1 -1
- data/lib/rubocop/cop/style/empty_literal.rb +43 -25
- data/lib/rubocop/cop/style/empty_method.rb +0 -6
- 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 +164 -24
- data/lib/rubocop/cop/style/env_home.rb +4 -0
- data/lib/rubocop/cop/style/eval_with_location.rb +23 -31
- data/lib/rubocop/cop/style/even_odd.rb +11 -1
- data/lib/rubocop/cop/style/exact_regexp_match.rb +13 -5
- data/lib/rubocop/cop/style/expand_path_arguments.rb +2 -7
- data/lib/rubocop/cop/style/explicit_block_argument.rb +19 -6
- data/lib/rubocop/cop/style/exponential_notation.rb +6 -5
- data/lib/rubocop/cop/style/fetch_env_var.rb +35 -8
- data/lib/rubocop/cop/style/file_null.rb +91 -0
- data/lib/rubocop/cop/style/file_open.rb +84 -0
- data/lib/rubocop/cop/style/file_read.rb +2 -5
- data/lib/rubocop/cop/style/file_touch.rb +75 -0
- data/lib/rubocop/cop/style/file_write.rb +23 -21
- data/lib/rubocop/cop/style/float_division.rb +23 -5
- data/lib/rubocop/cop/style/for.rb +7 -2
- data/lib/rubocop/cop/style/format_string.rb +47 -13
- data/lib/rubocop/cop/style/format_string_token.rb +86 -16
- data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +6 -3
- data/lib/rubocop/cop/style/global_std_stream.rb +10 -1
- data/lib/rubocop/cop/style/global_vars.rb +6 -5
- data/lib/rubocop/cop/style/guard_clause.rb +67 -21
- data/lib/rubocop/cop/style/hash_as_last_array_item.rb +27 -9
- data/lib/rubocop/cop/style/hash_conversion.rb +38 -13
- data/lib/rubocop/cop/style/hash_each_methods.rb +109 -12
- data/lib/rubocop/cop/style/hash_except.rb +38 -146
- data/lib/rubocop/cop/style/hash_fetch_chain.rb +104 -0
- data/lib/rubocop/cop/style/hash_lookup_method.rb +102 -0
- data/lib/rubocop/cop/style/hash_slice.rb +96 -0
- data/lib/rubocop/cop/style/hash_syntax.rb +36 -7
- 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 +62 -9
- data/lib/rubocop/cop/style/if_inside_else.rb +26 -22
- data/lib/rubocop/cop/style/if_unless_modifier.rb +72 -47
- data/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +15 -19
- data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +12 -9
- data/lib/rubocop/cop/style/if_with_semicolon.rb +75 -11
- data/lib/rubocop/cop/style/in_pattern_then.rb +6 -2
- 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 +22 -18
- data/lib/rubocop/cop/style/invertible_unless_condition.rb +71 -9
- data/lib/rubocop/cop/style/ip_addresses.rb +3 -4
- data/lib/rubocop/cop/style/it_assignment.rb +93 -0
- data/lib/rubocop/cop/style/it_block_parameter.rb +121 -0
- data/lib/rubocop/cop/style/keyword_arguments_merging.rb +71 -0
- data/lib/rubocop/cop/style/keyword_parameters_order.rb +20 -10
- data/lib/rubocop/cop/style/lambda.rb +16 -5
- data/lib/rubocop/cop/style/lambda_call.rb +33 -11
- 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 +93 -50
- data/lib/rubocop/cop/style/map_into_array.rb +236 -0
- data/lib/rubocop/cop/style/map_join.rb +123 -0
- data/lib/rubocop/cop/style/map_to_hash.rb +28 -10
- data/lib/rubocop/cop/style/map_to_set.rb +4 -5
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +77 -28
- 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 +38 -9
- data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +37 -15
- data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +3 -4
- data/lib/rubocop/cop/style/method_def_parentheses.rb +8 -6
- data/lib/rubocop/cop/style/min_max_comparison.rb +17 -6
- data/lib/rubocop/cop/style/missing_else.rb +2 -4
- data/lib/rubocop/cop/style/missing_respond_to_missing.rb +75 -12
- data/lib/rubocop/cop/style/mixin_grouping.rb +1 -1
- 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 +3 -2
- data/lib/rubocop/cop/style/multiline_if_modifier.rb +2 -0
- data/lib/rubocop/cop/style/multiline_if_then.rb +10 -4
- data/lib/rubocop/cop/style/multiline_memoization.rb +9 -3
- data/lib/rubocop/cop/style/multiline_method_signature.rb +18 -13
- data/lib/rubocop/cop/style/multiline_ternary_operator.rb +6 -4
- data/lib/rubocop/cop/style/multiline_when_then.rb +0 -4
- data/lib/rubocop/cop/style/multiple_comparison.rb +63 -59
- data/lib/rubocop/cop/style/mutable_constant.rb +117 -19
- data/lib/rubocop/cop/style/negated_if_else_condition.rb +6 -5
- data/lib/rubocop/cop/style/negative_array_index.rb +220 -0
- data/lib/rubocop/cop/style/nested_modifier.rb +1 -1
- data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +2 -2
- data/lib/rubocop/cop/style/nested_ternary_operator.rb +8 -15
- data/lib/rubocop/cop/style/next.rb +45 -1
- data/lib/rubocop/cop/style/nil_comparison.rb +12 -10
- data/lib/rubocop/cop/style/nil_lambda.rb +9 -1
- data/lib/rubocop/cop/style/non_nil_check.rb +5 -11
- data/lib/rubocop/cop/style/not.rb +3 -1
- data/lib/rubocop/cop/style/numeric_literal_prefix.rb +1 -1
- data/lib/rubocop/cop/style/numeric_literals.rb +3 -2
- data/lib/rubocop/cop/style/numeric_predicate.rb +13 -5
- data/lib/rubocop/cop/style/object_then.rb +16 -14
- data/lib/rubocop/cop/style/one_class_per_file.rb +115 -0
- data/lib/rubocop/cop/style/one_line_conditional.rb +50 -16
- data/lib/rubocop/cop/style/open_struct_use.rb +6 -6
- data/lib/rubocop/cop/style/operator_method_call.rb +40 -8
- 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/or_assignment.rb +3 -6
- data/lib/rubocop/cop/style/parallel_assignment.rb +69 -48
- data/lib/rubocop/cop/style/parentheses_around_condition.rb +8 -0
- data/lib/rubocop/cop/style/partition_instead_of_double_select.rb +270 -0
- data/lib/rubocop/cop/style/percent_literal_delimiters.rb +5 -1
- 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 +5 -4
- data/lib/rubocop/cop/style/quoted_symbols.rb +2 -4
- data/lib/rubocop/cop/style/raise_args.rb +19 -14
- data/lib/rubocop/cop/style/random_with_offset.rb +3 -3
- data/lib/rubocop/cop/style/reduce_to_hash.rb +200 -0
- data/lib/rubocop/cop/style/redundant_argument.rb +37 -4
- 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 +21 -3
- data/lib/rubocop/cop/style/redundant_begin.rb +53 -6
- data/lib/rubocop/cop/style/redundant_condition.rb +98 -25
- data/lib/rubocop/cop/style/redundant_conditional.rb +1 -9
- data/lib/rubocop/cop/style/redundant_constant_base.rb +42 -6
- data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +31 -7
- data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +88 -5
- data/lib/rubocop/cop/style/redundant_each.rb +11 -9
- data/lib/rubocop/cop/style/redundant_exception.rb +39 -13
- data/lib/rubocop/cop/style/redundant_fetch_block.rb +5 -13
- data/lib/rubocop/cop/style/redundant_file_extension_in_require.rb +10 -1
- data/lib/rubocop/cop/style/redundant_filter_chain.rb +23 -6
- data/lib/rubocop/cop/style/redundant_format.rb +319 -0
- data/lib/rubocop/cop/style/redundant_freeze.rb +4 -4
- data/lib/rubocop/cop/style/redundant_heredoc_delimiter_quotes.rb +6 -1
- data/lib/rubocop/cop/style/redundant_initialize.rb +12 -3
- data/lib/rubocop/cop/style/redundant_interpolation.rb +12 -3
- data/lib/rubocop/cop/style/redundant_interpolation_unfreeze.rb +62 -0
- data/lib/rubocop/cop/style/redundant_line_continuation.rb +92 -72
- data/lib/rubocop/cop/style/redundant_min_max_by.rb +93 -0
- data/lib/rubocop/cop/style/redundant_parentheses.rb +203 -84
- data/lib/rubocop/cop/style/redundant_percent_q.rb +6 -4
- data/lib/rubocop/cop/style/redundant_regexp_argument.rb +33 -4
- data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +1 -1
- data/lib/rubocop/cop/style/redundant_regexp_constructor.rb +2 -2
- data/lib/rubocop/cop/style/redundant_regexp_escape.rb +20 -24
- data/lib/rubocop/cop/style/redundant_return.rb +20 -8
- data/lib/rubocop/cop/style/redundant_self.rb +43 -22
- data/lib/rubocop/cop/style/redundant_self_assignment.rb +19 -32
- data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +9 -9
- data/lib/rubocop/cop/style/redundant_sort.rb +17 -16
- data/lib/rubocop/cop/style/redundant_sort_by.rb +19 -3
- data/lib/rubocop/cop/style/redundant_string_escape.rb +4 -5
- data/lib/rubocop/cop/style/redundant_struct_keyword_init.rb +133 -0
- data/lib/rubocop/cop/style/regexp_literal.rb +32 -3
- data/lib/rubocop/cop/style/require_order.rb +2 -2
- data/lib/rubocop/cop/style/rescue_modifier.rb +20 -7
- data/lib/rubocop/cop/style/return_nil.rb +8 -4
- data/lib/rubocop/cop/style/return_nil_in_predicate_method_definition.rb +67 -11
- data/lib/rubocop/cop/style/reverse_find.rb +51 -0
- data/lib/rubocop/cop/style/safe_navigation.rb +176 -66
- data/lib/rubocop/cop/style/safe_navigation_chain_length.rb +52 -0
- data/lib/rubocop/cop/style/sample.rb +14 -10
- 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 +62 -26
- data/lib/rubocop/cop/style/self_assignment.rb +13 -19
- data/lib/rubocop/cop/style/semicolon.rb +53 -17
- data/lib/rubocop/cop/style/send.rb +4 -4
- data/lib/rubocop/cop/style/send_with_literal_method_name.rb +105 -0
- data/lib/rubocop/cop/style/signal_exception.rb +2 -3
- data/lib/rubocop/cop/style/single_argument_dig.rb +16 -8
- data/lib/rubocop/cop/style/single_line_block_params.rb +3 -3
- data/lib/rubocop/cop/style/single_line_do_end_block.rb +90 -0
- data/lib/rubocop/cop/style/single_line_methods.rb +16 -12
- data/lib/rubocop/cop/style/slicing_with_range.rb +105 -10
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +103 -91
- data/lib/rubocop/cop/style/special_global_vars.rb +8 -4
- data/lib/rubocop/cop/style/stabby_lambda_parentheses.rb +3 -1
- data/lib/rubocop/cop/style/static_class.rb +21 -0
- data/lib/rubocop/cop/style/string_chars.rb +1 -0
- data/lib/rubocop/cop/style/string_concatenation.rb +34 -17
- data/lib/rubocop/cop/style/string_hash_keys.rb +1 -0
- data/lib/rubocop/cop/style/string_literals.rb +1 -1
- data/lib/rubocop/cop/style/string_literals_in_interpolation.rb +30 -5
- data/lib/rubocop/cop/style/string_methods.rb +1 -1
- data/lib/rubocop/cop/style/strip.rb +7 -4
- data/lib/rubocop/cop/style/struct_inheritance.rb +25 -3
- data/lib/rubocop/cop/style/super_arguments.rb +220 -0
- data/lib/rubocop/cop/style/super_with_args_parentheses.rb +35 -0
- data/lib/rubocop/cop/style/swap_values.rb +4 -15
- data/lib/rubocop/cop/style/symbol_array.rb +35 -15
- data/lib/rubocop/cop/style/symbol_proc.rb +86 -14
- data/lib/rubocop/cop/style/tally_method.rb +181 -0
- data/lib/rubocop/cop/style/ternary_parentheses.rb +37 -5
- data/lib/rubocop/cop/style/time_now.rb +41 -0
- data/lib/rubocop/cop/style/top_level_method_definition.rb +4 -3
- data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +56 -2
- 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 +21 -22
- data/lib/rubocop/cop/style/trivial_accessors.rb +3 -3
- 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/unpack_first.rb +11 -14
- data/lib/rubocop/cop/style/variable_interpolation.rb +1 -2
- data/lib/rubocop/cop/style/while_until_do.rb +7 -2
- data/lib/rubocop/cop/style/while_until_modifier.rb +16 -2
- data/lib/rubocop/cop/style/word_array.rb +1 -0
- data/lib/rubocop/cop/style/yoda_condition.rb +12 -7
- data/lib/rubocop/cop/style/yoda_expression.rb +11 -9
- data/lib/rubocop/cop/style/zero_length_predicate.rb +38 -27
- data/lib/rubocop/cop/style.rb +312 -0
- data/lib/rubocop/cop/team.rb +188 -46
- data/lib/rubocop/cop/util.rb +23 -13
- data/lib/rubocop/cop/utils/format_string.rb +20 -5
- data/lib/rubocop/cop/variable_force/assignment.rb +35 -7
- data/lib/rubocop/cop/variable_force/branch.rb +31 -7
- data/lib/rubocop/cop/variable_force/scope.rb +1 -1
- data/lib/rubocop/cop/variable_force/variable.rb +32 -10
- data/lib/rubocop/cop/variable_force/variable_table.rb +5 -5
- data/lib/rubocop/cop/variable_force.rb +43 -20
- data/lib/rubocop/cops_documentation_generator.rb +137 -63
- data/lib/rubocop/core_ext/string.rb +2 -6
- data/lib/rubocop/directive_comment.rb +135 -19
- data/lib/rubocop/ext/regexp_node.rb +17 -35
- data/lib/rubocop/ext/regexp_parser.rb +4 -21
- data/lib/rubocop/feature_loader.rb +0 -6
- data/lib/rubocop/file_finder.rb +11 -9
- data/lib/rubocop/file_patterns.rb +9 -1
- data/lib/rubocop/formatter/clang_style_formatter.rb +8 -9
- data/lib/rubocop/formatter/disabled_config_formatter.rb +62 -22
- data/lib/rubocop/formatter/emacs_style_formatter.rb +3 -1
- data/lib/rubocop/formatter/formatter_set.rb +10 -4
- data/lib/rubocop/formatter/fuubar_style_formatter.rb +1 -1
- data/lib/rubocop/formatter/html_formatter.rb +38 -17
- data/lib/rubocop/formatter/json_formatter.rb +11 -7
- data/lib/rubocop/formatter/junit_formatter.rb +94 -30
- data/lib/rubocop/formatter/markdown_formatter.rb +1 -0
- data/lib/rubocop/formatter/offense_count_formatter.rb +14 -5
- data/lib/rubocop/formatter/pacman_formatter.rb +2 -1
- data/lib/rubocop/formatter/simple_text_formatter.rb +4 -5
- data/lib/rubocop/formatter/tap_formatter.rb +11 -10
- data/lib/rubocop/formatter/worst_offenders_formatter.rb +2 -3
- data/lib/rubocop/formatter.rb +22 -21
- data/lib/rubocop/lockfile.rb +76 -7
- data/lib/rubocop/lsp/diagnostic.rb +170 -0
- data/lib/rubocop/lsp/disable_comment_edits.rb +135 -0
- data/lib/rubocop/lsp/logger.rb +3 -3
- data/lib/rubocop/lsp/routes.rb +163 -56
- data/lib/rubocop/lsp/runtime.rb +47 -44
- data/lib/rubocop/lsp/server.rb +18 -6
- data/lib/rubocop/lsp/severity.rb +1 -1
- data/lib/rubocop/lsp/stdin_runner.rb +96 -0
- data/lib/rubocop/lsp.rb +36 -0
- data/lib/rubocop/magic_comment.rb +44 -14
- data/lib/rubocop/mcp/server.rb +199 -0
- data/lib/rubocop/options.rb +88 -32
- data/lib/rubocop/path_util.rb +33 -11
- data/lib/rubocop/pending_cops_reporter.rb +51 -0
- data/lib/rubocop/plugin/configuration_integrator.rb +146 -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 +7 -5
- data/lib/rubocop/remote_config.rb +15 -9
- data/lib/rubocop/result_cache.rb +85 -61
- data/lib/rubocop/rspec/cop_helper.rb +28 -2
- data/lib/rubocop/rspec/expect_offense.rb +29 -12
- data/lib/rubocop/rspec/shared_contexts.rb +165 -24
- data/lib/rubocop/rspec/support.rb +8 -2
- data/lib/rubocop/runner.rb +273 -99
- data/lib/rubocop/server/cache.rb +76 -42
- 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 +4 -4
- data/lib/rubocop/server/client_command/start.rb +11 -1
- data/lib/rubocop/server/core.rb +13 -0
- data/lib/rubocop/server/server_command/exec.rb +0 -1
- data/lib/rubocop/server.rb +14 -0
- data/lib/rubocop/string_interpreter.rb +3 -3
- data/lib/rubocop/target_finder.rb +111 -86
- data/lib/rubocop/target_ruby.rb +131 -89
- data/lib/rubocop/todo_audit.rb +111 -0
- data/lib/rubocop/version.rb +84 -10
- data/lib/rubocop/yaml_duplication_checker.rb +20 -26
- data/lib/rubocop.rb +33 -648
- data/lib/ruby_lsp/rubocop/addon.rb +89 -0
- data/lib/ruby_lsp/rubocop/runtime_adapter.rb +99 -0
- metadata +169 -50
- data/lib/rubocop/cop/naming/predicate_name.rb +0 -134
- data/lib/rubocop/cop/utils/regexp_ranges.rb +0 -100
- data/lib/rubocop/rspec/host_environment_simulation_helper.rb +0 -28
- /data/lib/rubocop/formatter/{git_hub_actions_formatter.rb → github_actions_formatter.rb} +0 -0
|
@@ -8,7 +8,7 @@ module RuboCop
|
|
|
8
8
|
#
|
|
9
9
|
# * `scientific` which enforces a mantissa between 1 (inclusive) and 10 (exclusive).
|
|
10
10
|
# * `engineering` which enforces the exponent to be a multiple of 3 and the mantissa
|
|
11
|
-
# to be between 0.1 (inclusive) and
|
|
11
|
+
# to be between 0.1 (inclusive) and 1000 (exclusive).
|
|
12
12
|
# * `integral` which enforces the mantissa to always be a whole number without
|
|
13
13
|
# trailing zeroes.
|
|
14
14
|
#
|
|
@@ -59,9 +59,10 @@ module RuboCop
|
|
|
59
59
|
#
|
|
60
60
|
class ExponentialNotation < Base
|
|
61
61
|
include ConfigurableEnforcedStyle
|
|
62
|
+
|
|
62
63
|
MESSAGES = {
|
|
63
|
-
scientific: 'Use a mantissa
|
|
64
|
-
engineering: 'Use an exponent divisible by 3 and a mantissa
|
|
64
|
+
scientific: 'Use a mantissa >= 1 and < 10.',
|
|
65
|
+
engineering: 'Use an exponent divisible by 3 and a mantissa >= 0.1 and < 1000.',
|
|
65
66
|
integral: 'Use an integer as mantissa, without trailing zero.'
|
|
66
67
|
}.freeze
|
|
67
68
|
|
|
@@ -87,7 +88,7 @@ module RuboCop
|
|
|
87
88
|
true
|
|
88
89
|
end
|
|
89
90
|
|
|
90
|
-
def integral(node)
|
|
91
|
+
def integral?(node)
|
|
91
92
|
mantissa, = node.source.split('e')
|
|
92
93
|
/^-?[1-9](\d*[1-9])?$/.match?(mantissa)
|
|
93
94
|
end
|
|
@@ -101,7 +102,7 @@ module RuboCop
|
|
|
101
102
|
when :engineering
|
|
102
103
|
!engineering?(node)
|
|
103
104
|
when :integral
|
|
104
|
-
!integral(node)
|
|
105
|
+
!integral?(node)
|
|
105
106
|
else
|
|
106
107
|
false
|
|
107
108
|
end
|
|
@@ -6,10 +6,23 @@ module RuboCop
|
|
|
6
6
|
# Suggests `ENV.fetch` for the replacement of `ENV[]`.
|
|
7
7
|
# `ENV[]` silently fails and returns `nil` when the environment variable is unset,
|
|
8
8
|
# which may cause unexpected behaviors when the developer forgets to set it.
|
|
9
|
-
# On the other hand, `ENV.fetch` raises KeyError or returns the explicitly
|
|
9
|
+
# On the other hand, `ENV.fetch` raises `KeyError` or returns the explicitly
|
|
10
10
|
# specified default value.
|
|
11
11
|
#
|
|
12
|
-
# @example
|
|
12
|
+
# @example DefaultToNil: true (default)
|
|
13
|
+
# # bad
|
|
14
|
+
# ENV['X']
|
|
15
|
+
# x = ENV['X']
|
|
16
|
+
#
|
|
17
|
+
# # good
|
|
18
|
+
# ENV.fetch('X', nil)
|
|
19
|
+
# x = ENV.fetch('X', nil)
|
|
20
|
+
#
|
|
21
|
+
# # also good
|
|
22
|
+
# !ENV['X']
|
|
23
|
+
# ENV['X'].some_method # (e.g. `.nil?`)
|
|
24
|
+
#
|
|
25
|
+
# @example DefaultToNil: false
|
|
13
26
|
# # bad
|
|
14
27
|
# ENV['X']
|
|
15
28
|
# x = ENV['X']
|
|
@@ -25,7 +38,9 @@ module RuboCop
|
|
|
25
38
|
class FetchEnvVar < Base
|
|
26
39
|
extend AutoCorrector
|
|
27
40
|
|
|
28
|
-
|
|
41
|
+
MSG_WITH_NIL = 'Use `ENV.fetch(%<key>s, nil)` instead of `ENV[%<key>s]`.'
|
|
42
|
+
MSG_WITHOUT_NIL = 'Use `ENV.fetch(%<key>s)` instead of `ENV[%<key>s]`.'
|
|
43
|
+
RESTRICT_ON_SEND = [:[]].freeze
|
|
29
44
|
|
|
30
45
|
# @!method env_with_bracket?(node)
|
|
31
46
|
def_node_matcher :env_with_bracket?, <<~PATTERN
|
|
@@ -36,7 +51,7 @@ module RuboCop
|
|
|
36
51
|
env_with_bracket?(node) do |name_node|
|
|
37
52
|
break unless offensive?(node)
|
|
38
53
|
|
|
39
|
-
message = format(
|
|
54
|
+
message = format(offense_message, key: name_node.source)
|
|
40
55
|
add_offense(node, message: message) do |corrector|
|
|
41
56
|
corrector.replace(node, new_code(name_node))
|
|
42
57
|
end
|
|
@@ -45,19 +60,27 @@ module RuboCop
|
|
|
45
60
|
|
|
46
61
|
private
|
|
47
62
|
|
|
63
|
+
def default_to_nil?
|
|
64
|
+
cop_config.fetch('DefaultToNil', true)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def offense_message
|
|
68
|
+
default_to_nil? ? MSG_WITH_NIL : MSG_WITHOUT_NIL
|
|
69
|
+
end
|
|
70
|
+
|
|
48
71
|
def allowed_var?(node)
|
|
49
72
|
env_key_node = node.children.last
|
|
50
|
-
env_key_node.str_type? && cop_config['
|
|
73
|
+
env_key_node.str_type? && cop_config['AllowedVariables'].include?(env_key_node.value)
|
|
51
74
|
end
|
|
52
75
|
|
|
53
76
|
def used_as_flag?(node)
|
|
54
77
|
return false if node.root?
|
|
55
|
-
return true if used_if_condition_in_body(node)
|
|
78
|
+
return true if used_if_condition_in_body?(node)
|
|
56
79
|
|
|
57
80
|
node.parent.send_type? && (node.parent.prefix_bang? || node.parent.comparison_method?)
|
|
58
81
|
end
|
|
59
82
|
|
|
60
|
-
def used_if_condition_in_body(node)
|
|
83
|
+
def used_if_condition_in_body?(node)
|
|
61
84
|
if_node = node.ancestors.find(&:if_type?)
|
|
62
85
|
|
|
63
86
|
return false unless (condition = if_node&.condition)
|
|
@@ -124,7 +147,11 @@ module RuboCop
|
|
|
124
147
|
end
|
|
125
148
|
|
|
126
149
|
def new_code(name_node)
|
|
127
|
-
|
|
150
|
+
if default_to_nil?
|
|
151
|
+
"ENV.fetch(#{name_node.source}, nil)"
|
|
152
|
+
else
|
|
153
|
+
"ENV.fetch(#{name_node.source})"
|
|
154
|
+
end
|
|
128
155
|
end
|
|
129
156
|
end
|
|
130
157
|
end
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module Cop
|
|
5
|
+
module Style
|
|
6
|
+
# Use `File::NULL` instead of hardcoding the null device (`/dev/null` on Unix-like
|
|
7
|
+
# OSes, `NUL` or `NUL:` on Windows), so that code is platform independent.
|
|
8
|
+
# Only looks for full string matches, substrings within a longer string are not
|
|
9
|
+
# considered.
|
|
10
|
+
#
|
|
11
|
+
# However, only files that use the string `'/dev/null'` are targeted for detection.
|
|
12
|
+
# This is because the string `'NUL'` is not limited to the null device.
|
|
13
|
+
# This behavior results in false negatives when the `'/dev/null'` string is not used,
|
|
14
|
+
# but it is a trade-off to avoid false positives. `NULL:`
|
|
15
|
+
# Unlike `'NUL'`, `'NUL:'` is regarded as something like `C:` and is always detected.
|
|
16
|
+
#
|
|
17
|
+
# NOTE: Uses inside arrays and hashes are ignored.
|
|
18
|
+
#
|
|
19
|
+
# @safety
|
|
20
|
+
# It is possible for a string value to be changed if code is being run
|
|
21
|
+
# on multiple platforms and was previously hardcoded to a specific null device.
|
|
22
|
+
#
|
|
23
|
+
# For example, the following string will change on Windows when changed to
|
|
24
|
+
# `File::NULL`:
|
|
25
|
+
#
|
|
26
|
+
# [source,ruby]
|
|
27
|
+
# ----
|
|
28
|
+
# path = "/dev/null"
|
|
29
|
+
# ----
|
|
30
|
+
#
|
|
31
|
+
# @example
|
|
32
|
+
# # bad
|
|
33
|
+
# '/dev/null'
|
|
34
|
+
# 'NUL'
|
|
35
|
+
# 'NUL:'
|
|
36
|
+
#
|
|
37
|
+
# # good
|
|
38
|
+
# File::NULL
|
|
39
|
+
#
|
|
40
|
+
# # ok - inside an array
|
|
41
|
+
# null_devices = %w[/dev/null nul]
|
|
42
|
+
#
|
|
43
|
+
# # ok - inside a hash
|
|
44
|
+
# { unix: "/dev/null", windows: "nul" }
|
|
45
|
+
class FileNull < Base
|
|
46
|
+
extend AutoCorrector
|
|
47
|
+
|
|
48
|
+
REGEXP = %r{\A(/dev/null|NUL:?)\z}i.freeze
|
|
49
|
+
MSG = 'Use `File::NULL` instead of `%<source>s`.'
|
|
50
|
+
|
|
51
|
+
def on_new_investigation
|
|
52
|
+
return unless (ast = processed_source.ast)
|
|
53
|
+
|
|
54
|
+
@contain_dev_null_string_in_file = ast.each_descendant(:str).any? do |str|
|
|
55
|
+
content = str.str_content
|
|
56
|
+
|
|
57
|
+
valid_string?(content) && content.downcase == '/dev/null' # rubocop:disable Style/FileNull
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def on_str(node)
|
|
62
|
+
value = node.value
|
|
63
|
+
return unless valid_string?(value)
|
|
64
|
+
return if acceptable?(node)
|
|
65
|
+
return if value.downcase == 'nul' && !@contain_dev_null_string_in_file # rubocop:disable Style/FileNull
|
|
66
|
+
return unless REGEXP.match?(value)
|
|
67
|
+
|
|
68
|
+
add_offense(node, message: format(MSG, source: value)) do |corrector|
|
|
69
|
+
corrector.replace(node, 'File::NULL')
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
private
|
|
74
|
+
|
|
75
|
+
def valid_string?(value)
|
|
76
|
+
!value.empty? && value.valid_encoding?
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def acceptable?(node)
|
|
80
|
+
# Using a hardcoded null device is acceptable when inside an array or
|
|
81
|
+
# inside a hash to ensure behavior doesn't change. A `str` that is part of
|
|
82
|
+
# an interpolated or concatenated string (`dstr`) is not a standalone null
|
|
83
|
+
# device either, and replacing it would corrupt the surrounding string.
|
|
84
|
+
return false unless node.parent
|
|
85
|
+
|
|
86
|
+
node.parent.type?(:array, :pair, :dstr)
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module Cop
|
|
5
|
+
module Style
|
|
6
|
+
# Checks for `File.open` without a block, which can leak file descriptors.
|
|
7
|
+
#
|
|
8
|
+
# When `File.open` is called without a block, the caller is responsible
|
|
9
|
+
# for closing the file descriptor. If it is not explicitly closed, it
|
|
10
|
+
# will only be closed when the garbage collector runs, which may lead
|
|
11
|
+
# to resource exhaustion. Using the block form ensures the file is
|
|
12
|
+
# automatically closed when the block exits.
|
|
13
|
+
#
|
|
14
|
+
# This cop only registers an offense when the result of `File.open` is
|
|
15
|
+
# assigned to a variable or has a method chained on it, as those are the
|
|
16
|
+
# clearest indicators that the block form should be used instead. When
|
|
17
|
+
# `File.open` is used as a return value or passed as an argument, the
|
|
18
|
+
# caller is likely managing the file descriptor intentionally.
|
|
19
|
+
#
|
|
20
|
+
# @safety
|
|
21
|
+
# This cop is unsafe because it relies on syntax heuristics and cannot
|
|
22
|
+
# verify whether the file descriptor is safely managed. For example, it
|
|
23
|
+
# still flags intentional one-shot reads (`File.open("f").read`) where
|
|
24
|
+
# the file descriptor is closed by the garbage collector.
|
|
25
|
+
#
|
|
26
|
+
# @example
|
|
27
|
+
# # bad
|
|
28
|
+
# f = File.open('file')
|
|
29
|
+
#
|
|
30
|
+
# # bad
|
|
31
|
+
# File.open('file').read
|
|
32
|
+
#
|
|
33
|
+
# # good
|
|
34
|
+
# File.open('file') do |f|
|
|
35
|
+
# f.read
|
|
36
|
+
# end
|
|
37
|
+
#
|
|
38
|
+
# # good
|
|
39
|
+
# File.open('file', &:read)
|
|
40
|
+
#
|
|
41
|
+
# # good - pass an open file object to an API that manages its lifecycle
|
|
42
|
+
# process(io: File.open('file'))
|
|
43
|
+
#
|
|
44
|
+
# # good - return an open file object for the caller to manage
|
|
45
|
+
# def json_key_io
|
|
46
|
+
# File.open('file')
|
|
47
|
+
# end
|
|
48
|
+
#
|
|
49
|
+
# # good - use File.read for one-shot reads
|
|
50
|
+
# File.read('file')
|
|
51
|
+
#
|
|
52
|
+
class FileOpen < Base
|
|
53
|
+
MSG = '`File.open` without a block may leak a file descriptor; use the block form.'
|
|
54
|
+
RESTRICT_ON_SEND = %i[open].freeze
|
|
55
|
+
|
|
56
|
+
# @!method file_open?(node)
|
|
57
|
+
def_node_matcher :file_open?, <<~PATTERN
|
|
58
|
+
(send (const {nil? cbase} :File) :open ...)
|
|
59
|
+
PATTERN
|
|
60
|
+
|
|
61
|
+
def on_send(node)
|
|
62
|
+
return unless file_open?(node)
|
|
63
|
+
return if node.block_argument?
|
|
64
|
+
return unless offensive_usage?(node)
|
|
65
|
+
|
|
66
|
+
add_offense(node)
|
|
67
|
+
end
|
|
68
|
+
alias on_csend on_send
|
|
69
|
+
|
|
70
|
+
private
|
|
71
|
+
|
|
72
|
+
def offensive_usage?(node)
|
|
73
|
+
return true unless node.value_used?
|
|
74
|
+
|
|
75
|
+
node.parent.lvasgn_type? || receiver_of_chained_call?(node)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def receiver_of_chained_call?(node)
|
|
79
|
+
node.parent.receiver == node
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
@@ -6,8 +6,7 @@ module RuboCop
|
|
|
6
6
|
# Favor `File.(bin)read` convenience methods.
|
|
7
7
|
#
|
|
8
8
|
# @example
|
|
9
|
-
#
|
|
10
|
-
# # bad
|
|
9
|
+
# # bad - text mode
|
|
11
10
|
# File.open(filename).read
|
|
12
11
|
# File.open(filename, &:read)
|
|
13
12
|
# File.open(filename) { |f| f.read }
|
|
@@ -23,9 +22,7 @@ module RuboCop
|
|
|
23
22
|
# # good
|
|
24
23
|
# File.read(filename)
|
|
25
24
|
#
|
|
26
|
-
#
|
|
27
|
-
# ## binary mode
|
|
28
|
-
# # bad
|
|
25
|
+
# # bad - binary mode
|
|
29
26
|
# File.open(filename, 'rb').read
|
|
30
27
|
# File.open(filename, 'rb', &:read)
|
|
31
28
|
# File.open(filename, 'rb') do |f|
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module Cop
|
|
5
|
+
module Style
|
|
6
|
+
# Checks for usage of `File.open` in append mode with empty block.
|
|
7
|
+
#
|
|
8
|
+
# Such a usage only creates a new file, but it doesn't update
|
|
9
|
+
# timestamps for an existing file, which might have been the intention.
|
|
10
|
+
#
|
|
11
|
+
# For example, for an existing file `foo.txt`:
|
|
12
|
+
#
|
|
13
|
+
# ruby -e "puts File.mtime('foo.txt')"
|
|
14
|
+
# # 2024-11-26 12:17:23 +0100
|
|
15
|
+
#
|
|
16
|
+
# ruby -e "File.open('foo.txt', 'a') {}"
|
|
17
|
+
#
|
|
18
|
+
# ruby -e "puts File.mtime('foo.txt')"
|
|
19
|
+
# # 2024-11-26 12:17:23 +0100 -> unchanged
|
|
20
|
+
#
|
|
21
|
+
# If the intention was to update timestamps, `FileUtils.touch('foo.txt')`
|
|
22
|
+
# should be used instead.
|
|
23
|
+
#
|
|
24
|
+
# @safety
|
|
25
|
+
# Autocorrection is unsafe for this cop because unlike `File.open`,
|
|
26
|
+
# `FileUtils.touch` updates an existing file's timestamps.
|
|
27
|
+
#
|
|
28
|
+
# @example
|
|
29
|
+
# # bad
|
|
30
|
+
# File.open(filename, 'a') {}
|
|
31
|
+
# File.open(filename, 'a+') {}
|
|
32
|
+
#
|
|
33
|
+
# # good
|
|
34
|
+
# FileUtils.touch(filename)
|
|
35
|
+
#
|
|
36
|
+
class FileTouch < Base
|
|
37
|
+
extend AutoCorrector
|
|
38
|
+
|
|
39
|
+
MSG = 'Use `FileUtils.touch(%<argument>s)` instead of `File.open` in ' \
|
|
40
|
+
'append mode with empty block.'
|
|
41
|
+
|
|
42
|
+
RESTRICT_ON_SEND = %i[open].freeze
|
|
43
|
+
|
|
44
|
+
APPEND_FILE_MODES = %w[a a+ ab a+b at a+t].to_set.freeze
|
|
45
|
+
|
|
46
|
+
# @!method file_open?(node)
|
|
47
|
+
def_node_matcher :file_open?, <<~PATTERN
|
|
48
|
+
(send
|
|
49
|
+
(const {nil? cbase} :File) :open
|
|
50
|
+
$(...)
|
|
51
|
+
(str %APPEND_FILE_MODES))
|
|
52
|
+
PATTERN
|
|
53
|
+
|
|
54
|
+
def on_send(node)
|
|
55
|
+
filename = file_open?(node)
|
|
56
|
+
parent = node.parent
|
|
57
|
+
|
|
58
|
+
return unless filename
|
|
59
|
+
return unless parent && empty_block?(parent)
|
|
60
|
+
|
|
61
|
+
message = format(MSG, argument: filename.source)
|
|
62
|
+
add_offense(parent, message: message) do |corrector|
|
|
63
|
+
corrector.replace(parent, "FileUtils.touch(#{filename.source})")
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
private
|
|
68
|
+
|
|
69
|
+
def empty_block?(node)
|
|
70
|
+
node.block_type? && !node.body
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
@@ -17,8 +17,7 @@ module RuboCop
|
|
|
17
17
|
# ----
|
|
18
18
|
#
|
|
19
19
|
# @example
|
|
20
|
-
#
|
|
21
|
-
# # bad
|
|
20
|
+
# # bad - text mode
|
|
22
21
|
# File.open(filename, 'w').write(content)
|
|
23
22
|
# File.open(filename, 'w') do |f|
|
|
24
23
|
# f.write(content)
|
|
@@ -27,9 +26,7 @@ module RuboCop
|
|
|
27
26
|
# # good
|
|
28
27
|
# File.write(filename, content)
|
|
29
28
|
#
|
|
30
|
-
#
|
|
31
|
-
# ## binary mode
|
|
32
|
-
# # bad
|
|
29
|
+
# # bad - binary mode
|
|
33
30
|
# File.open(filename, 'wb').write(content)
|
|
34
31
|
# File.open(filename, 'wb') do |f|
|
|
35
32
|
# f.write(content)
|
|
@@ -107,28 +104,33 @@ module RuboCop
|
|
|
107
104
|
|
|
108
105
|
def replacement(mode, filename, content, write_node)
|
|
109
106
|
replacement = "#{write_method(mode)}(#{filename.source}, #{content.source})"
|
|
107
|
+
heredocs = removed_heredocs(filename, content, write_node)
|
|
108
|
+
return replacement if heredocs.empty?
|
|
110
109
|
|
|
111
|
-
|
|
112
|
-
|
|
110
|
+
[replacement, *heredocs.map { |heredoc| heredoc_range(heredoc).source }].join("\n")
|
|
111
|
+
end
|
|
113
112
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
113
|
+
# Heredocs opened in the arguments keep working in the replacement, but their
|
|
114
|
+
# bodies are lost when they lie within the replaced range, so they need to be
|
|
115
|
+
# restored after the replacement.
|
|
116
|
+
def removed_heredocs(filename, content, write_node)
|
|
117
|
+
[filename, content].flat_map { |argument| find_heredocs(argument) }
|
|
118
|
+
.select { |heredoc| removed?(heredoc, write_node) }
|
|
119
|
+
.sort_by { |heredoc| heredoc.loc.heredoc_body.begin_pos }
|
|
121
120
|
end
|
|
122
121
|
|
|
123
|
-
def heredoc
|
|
124
|
-
|
|
125
|
-
first_argument.respond_to?(:heredoc?) && first_argument.heredoc?
|
|
122
|
+
def heredoc_range(heredoc)
|
|
123
|
+
range_between(heredoc.loc.heredoc_body.begin_pos, heredoc.loc.heredoc_end.end_pos)
|
|
126
124
|
end
|
|
127
125
|
|
|
128
|
-
def
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
126
|
+
def find_heredocs(node)
|
|
127
|
+
[node, *node.each_descendant(:any_str)].select do |child|
|
|
128
|
+
child.respond_to?(:heredoc?) && child.heredoc?
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def removed?(heredoc, write_node)
|
|
133
|
+
heredoc.loc.heredoc_end.end_pos <= write_node.source_range.end_pos
|
|
132
134
|
end
|
|
133
135
|
end
|
|
134
136
|
end
|
|
@@ -7,9 +7,12 @@ module RuboCop
|
|
|
7
7
|
# It is recommended to either always use `fdiv` or coerce one side only.
|
|
8
8
|
# This cop also provides other options for code consistency.
|
|
9
9
|
#
|
|
10
|
+
# For `Regexp.last_match` and nth reference (e.g., `$1`), it assumes that the value
|
|
11
|
+
# is a string matched by a regular expression, and allows conversion with `#to_f`.
|
|
12
|
+
#
|
|
10
13
|
# @safety
|
|
11
14
|
# This cop is unsafe, because if the operand variable is a string object
|
|
12
|
-
# then
|
|
15
|
+
# then `#to_f` will be removed and an error will occur.
|
|
13
16
|
#
|
|
14
17
|
# [source,ruby]
|
|
15
18
|
# ----
|
|
@@ -65,19 +68,31 @@ module RuboCop
|
|
|
65
68
|
|
|
66
69
|
# @!method right_coerce?(node)
|
|
67
70
|
def_node_matcher :right_coerce?, <<~PATTERN
|
|
68
|
-
(send _ :/
|
|
71
|
+
(send _ :/ #to_f_method?)
|
|
69
72
|
PATTERN
|
|
70
73
|
# @!method left_coerce?(node)
|
|
71
74
|
def_node_matcher :left_coerce?, <<~PATTERN
|
|
72
|
-
(send
|
|
75
|
+
(send #to_f_method? :/ _)
|
|
73
76
|
PATTERN
|
|
74
77
|
# @!method both_coerce?(node)
|
|
75
78
|
def_node_matcher :both_coerce?, <<~PATTERN
|
|
76
|
-
(send
|
|
79
|
+
(send #to_f_method? :/ #to_f_method?)
|
|
77
80
|
PATTERN
|
|
78
81
|
# @!method any_coerce?(node)
|
|
79
82
|
def_node_matcher :any_coerce?, <<~PATTERN
|
|
80
|
-
{(send _ :/
|
|
83
|
+
{(send _ :/ #to_f_method?) (send #to_f_method? :/ _)}
|
|
84
|
+
PATTERN
|
|
85
|
+
# @!method to_f_method?(node)
|
|
86
|
+
def_node_matcher :to_f_method?, <<~PATTERN
|
|
87
|
+
(send !nil? :to_f)
|
|
88
|
+
PATTERN
|
|
89
|
+
|
|
90
|
+
# @!method regexp_last_match?(node)
|
|
91
|
+
def_node_matcher :regexp_last_match?, <<~PATTERN
|
|
92
|
+
{
|
|
93
|
+
(send (const {nil? cbase} :Regexp) :last_match int)
|
|
94
|
+
(:nth_ref _)
|
|
95
|
+
}
|
|
81
96
|
PATTERN
|
|
82
97
|
|
|
83
98
|
def on_send(node)
|
|
@@ -100,6 +115,9 @@ module RuboCop
|
|
|
100
115
|
private
|
|
101
116
|
|
|
102
117
|
def offense_condition?(node)
|
|
118
|
+
return false if regexp_last_match?(node.receiver.receiver) ||
|
|
119
|
+
regexp_last_match?(node.first_argument.receiver)
|
|
120
|
+
|
|
103
121
|
case style
|
|
104
122
|
when :left_coerce
|
|
105
123
|
right_coerce?(node)
|
|
@@ -8,6 +8,9 @@ module RuboCop
|
|
|
8
8
|
# parameter. An `each` call with a block on a single line is always
|
|
9
9
|
# allowed.
|
|
10
10
|
#
|
|
11
|
+
# NOTE: `each` is preferred in idiomatic Ruby because `for` leaks
|
|
12
|
+
# its loop variable into the surrounding scope.
|
|
13
|
+
#
|
|
11
14
|
# @example EnforcedStyle: each (default)
|
|
12
15
|
# # bad
|
|
13
16
|
# def foo
|
|
@@ -44,7 +47,6 @@ module RuboCop
|
|
|
44
47
|
#
|
|
45
48
|
class For < Base
|
|
46
49
|
include ConfigurableEnforcedStyle
|
|
47
|
-
include RangeHelp
|
|
48
50
|
extend AutoCorrector
|
|
49
51
|
|
|
50
52
|
EACH_LENGTH = 'each'.length
|
|
@@ -66,6 +68,8 @@ module RuboCop
|
|
|
66
68
|
return unless suspect_enumerable?(node)
|
|
67
69
|
|
|
68
70
|
if style == :for
|
|
71
|
+
return unless node.receiver
|
|
72
|
+
|
|
69
73
|
add_offense(node, message: PREFER_FOR) do |corrector|
|
|
70
74
|
EachToForCorrector.new(node).call(corrector)
|
|
71
75
|
opposite_style_detected
|
|
@@ -76,11 +80,12 @@ module RuboCop
|
|
|
76
80
|
end
|
|
77
81
|
|
|
78
82
|
alias on_numblock on_block
|
|
83
|
+
alias on_itblock on_block
|
|
79
84
|
|
|
80
85
|
private
|
|
81
86
|
|
|
82
87
|
def suspect_enumerable?(node)
|
|
83
|
-
node.multiline? && node.
|
|
88
|
+
node.multiline? && node.method?(:each) && !node.send_node.arguments?
|
|
84
89
|
end
|
|
85
90
|
end
|
|
86
91
|
end
|
|
@@ -4,36 +4,49 @@ module RuboCop
|
|
|
4
4
|
module Cop
|
|
5
5
|
module Style
|
|
6
6
|
# Enforces the use of a single string formatting utility.
|
|
7
|
-
# Valid options include Kernel#format
|
|
7
|
+
# Valid options include `Kernel#format`, `Kernel#sprintf`, and `String#%`.
|
|
8
8
|
#
|
|
9
|
-
# The detection of String
|
|
9
|
+
# The detection of `String#%` cannot be implemented in a reliable
|
|
10
10
|
# manner for all cases, so only two scenarios are considered -
|
|
11
11
|
# if the first argument is a string literal and if the second
|
|
12
12
|
# argument is an array literal.
|
|
13
13
|
#
|
|
14
|
+
# Autocorrection will be applied when the argument is a literal or uses a known
|
|
15
|
+
# built-in conversion method such as `to_d`, `to_f`, `to_h`, `to_i`, `to_r`, `to_s`,
|
|
16
|
+
# and `to_sym` on variables, provided that their return value is not an array.
|
|
17
|
+
# For example, when using `to_s`,
|
|
18
|
+
# `'%s' % [1, 2, 3].to_s` can be autocorrected without any incompatibility:
|
|
19
|
+
#
|
|
20
|
+
# [source,ruby]
|
|
21
|
+
# ----
|
|
22
|
+
# '%s' % [1, 2, 3] #=> '1'
|
|
23
|
+
# format('%s', [1, 2, 3]) #=> '[1, 2, 3]'
|
|
24
|
+
# '%s' % [1, 2, 3].to_s #=> '[1, 2, 3]'
|
|
25
|
+
# ----
|
|
26
|
+
#
|
|
14
27
|
# @example EnforcedStyle: format (default)
|
|
15
28
|
# # bad
|
|
16
|
-
# puts sprintf('%10s', '
|
|
17
|
-
# puts '%10s' % '
|
|
29
|
+
# puts sprintf('%10s', 'foo')
|
|
30
|
+
# puts '%10s' % 'foo'
|
|
18
31
|
#
|
|
19
32
|
# # good
|
|
20
|
-
# puts format('%10s', '
|
|
33
|
+
# puts format('%10s', 'foo')
|
|
21
34
|
#
|
|
22
35
|
# @example EnforcedStyle: sprintf
|
|
23
36
|
# # bad
|
|
24
|
-
# puts format('%10s', '
|
|
25
|
-
# puts '%10s' % '
|
|
37
|
+
# puts format('%10s', 'foo')
|
|
38
|
+
# puts '%10s' % 'foo'
|
|
26
39
|
#
|
|
27
40
|
# # good
|
|
28
|
-
# puts sprintf('%10s', '
|
|
41
|
+
# puts sprintf('%10s', 'foo')
|
|
29
42
|
#
|
|
30
43
|
# @example EnforcedStyle: percent
|
|
31
44
|
# # bad
|
|
32
|
-
# puts format('%10s', '
|
|
33
|
-
# puts sprintf('%10s', '
|
|
45
|
+
# puts format('%10s', 'foo')
|
|
46
|
+
# puts sprintf('%10s', 'foo')
|
|
34
47
|
#
|
|
35
48
|
# # good
|
|
36
|
-
# puts '%10s' % '
|
|
49
|
+
# puts '%10s' % 'foo'
|
|
37
50
|
#
|
|
38
51
|
class FormatString < Base
|
|
39
52
|
include ConfigurableEnforcedStyle
|
|
@@ -42,6 +55,9 @@ module RuboCop
|
|
|
42
55
|
MSG = 'Favor `%<prefer>s` over `%<current>s`.'
|
|
43
56
|
RESTRICT_ON_SEND = %i[format sprintf %].freeze
|
|
44
57
|
|
|
58
|
+
# Known conversion methods whose return value is not an array.
|
|
59
|
+
AUTOCORRECTABLE_METHODS = %i[to_d to_f to_h to_i to_r to_s to_sym].freeze
|
|
60
|
+
|
|
45
61
|
# @!method formatter(node)
|
|
46
62
|
def_node_matcher :formatter, <<~PATTERN
|
|
47
63
|
{
|
|
@@ -53,7 +69,7 @@ module RuboCop
|
|
|
53
69
|
|
|
54
70
|
# @!method variable_argument?(node)
|
|
55
71
|
def_node_matcher :variable_argument?, <<~PATTERN
|
|
56
|
-
(send {str dstr} :%
|
|
72
|
+
(send {str dstr} :% #autocorrectable?)
|
|
57
73
|
PATTERN
|
|
58
74
|
|
|
59
75
|
def on_send(node)
|
|
@@ -70,6 +86,12 @@ module RuboCop
|
|
|
70
86
|
|
|
71
87
|
private
|
|
72
88
|
|
|
89
|
+
def autocorrectable?(node)
|
|
90
|
+
return true if node.lvar_type?
|
|
91
|
+
|
|
92
|
+
node.send_type? && !AUTOCORRECTABLE_METHODS.include?(node.method_name)
|
|
93
|
+
end
|
|
94
|
+
|
|
73
95
|
def message(detected_style)
|
|
74
96
|
format(MSG, prefer: method_name(style), current: method_name(detected_style))
|
|
75
97
|
end
|
|
@@ -122,10 +144,22 @@ module RuboCop
|
|
|
122
144
|
end
|
|
123
145
|
|
|
124
146
|
def format_single_parameter(arg)
|
|
147
|
+
# `format(fmt, *args)` is equivalent to `fmt % args`, so unwrap the splat
|
|
148
|
+
# and render the argument it splats.
|
|
149
|
+
return format_single_parameter(arg.children.first) if arg.splat_type?
|
|
150
|
+
|
|
125
151
|
source = arg.source
|
|
126
152
|
return "{ #{source} }" if arg.hash_type?
|
|
127
153
|
|
|
128
|
-
|
|
154
|
+
requires_parentheses?(arg) ? "(#{source})" : source
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
# An argument that binds looser than `%` (a ternary, range, assignment, or
|
|
158
|
+
# operator call) must be parenthesized to keep its meaning.
|
|
159
|
+
def requires_parentheses?(arg)
|
|
160
|
+
return true if arg.assignment? || arg.type?(:if, :and, :or, :range)
|
|
161
|
+
|
|
162
|
+
arg.send_type? && arg.operator_method? && !arg.parenthesized?
|
|
129
163
|
end
|
|
130
164
|
end
|
|
131
165
|
end
|