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
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module Cop
|
|
5
|
+
module Lint
|
|
6
|
+
# Checks for constant reassignments.
|
|
7
|
+
#
|
|
8
|
+
# Emulates Ruby's runtime warning "already initialized constant X"
|
|
9
|
+
# when a constant is reassigned in the same file and namespace.
|
|
10
|
+
#
|
|
11
|
+
# The cop tracks constants defined via `NAME = value` syntax as well as
|
|
12
|
+
# class/module keyword definitions. It detects reassignment when a constant
|
|
13
|
+
# is first defined one way and then redefined using the `NAME = value` syntax.
|
|
14
|
+
#
|
|
15
|
+
# The cop cannot catch all offenses, like, for example, when using metaprogramming
|
|
16
|
+
# (`Module#const_set`).
|
|
17
|
+
#
|
|
18
|
+
# By default the cop also cannot detect reassignment across files.
|
|
19
|
+
# When `AllCops/UseProjectIndex` is enabled and the `rubydex` gem is installed,
|
|
20
|
+
# the cop additionally consults the project-wide index and reports reassignments
|
|
21
|
+
# whose previous definition lives in another file.
|
|
22
|
+
#
|
|
23
|
+
# The cop only takes into account constants assigned in a "simple" way: directly
|
|
24
|
+
# inside class/module definition, or within another constant. Other type of assignments
|
|
25
|
+
# (e.g., inside a conditional) are disregarded.
|
|
26
|
+
#
|
|
27
|
+
# The cop also tracks constant removal using `Module#remove_const` with symbol
|
|
28
|
+
# or string argument.
|
|
29
|
+
#
|
|
30
|
+
# @example
|
|
31
|
+
# # bad
|
|
32
|
+
# X = :foo
|
|
33
|
+
# X = :bar
|
|
34
|
+
#
|
|
35
|
+
# # bad
|
|
36
|
+
# class A
|
|
37
|
+
# X = :foo
|
|
38
|
+
# X = :bar
|
|
39
|
+
# end
|
|
40
|
+
#
|
|
41
|
+
# # bad
|
|
42
|
+
# module A
|
|
43
|
+
# X = :foo
|
|
44
|
+
# X = :bar
|
|
45
|
+
# end
|
|
46
|
+
#
|
|
47
|
+
# # bad
|
|
48
|
+
# class FooError < StandardError; end
|
|
49
|
+
# FooError = Class.new(RuntimeError)
|
|
50
|
+
#
|
|
51
|
+
# # bad
|
|
52
|
+
# module M; end
|
|
53
|
+
# M = 1
|
|
54
|
+
#
|
|
55
|
+
# # good - keep only one assignment
|
|
56
|
+
# X = :bar
|
|
57
|
+
#
|
|
58
|
+
# class A
|
|
59
|
+
# X = :bar
|
|
60
|
+
# end
|
|
61
|
+
#
|
|
62
|
+
# module A
|
|
63
|
+
# X = :bar
|
|
64
|
+
# end
|
|
65
|
+
#
|
|
66
|
+
# # good - use OR assignment
|
|
67
|
+
# X = :foo
|
|
68
|
+
# X ||= :bar
|
|
69
|
+
#
|
|
70
|
+
# # good - use conditional assignment
|
|
71
|
+
# X = :foo
|
|
72
|
+
# X = :bar unless defined?(X)
|
|
73
|
+
#
|
|
74
|
+
# # good - remove the assigned constant first
|
|
75
|
+
# class A
|
|
76
|
+
# X = :foo
|
|
77
|
+
# remove_const :X
|
|
78
|
+
# X = :bar
|
|
79
|
+
# end
|
|
80
|
+
#
|
|
81
|
+
class ConstantReassignment < Base
|
|
82
|
+
include ProjectIndexHelp
|
|
83
|
+
|
|
84
|
+
MSG = 'Constant `%<constant>s` is already assigned in this namespace.'
|
|
85
|
+
CROSS_FILE_MSG = 'Constant `%<constant>s` is already assigned in `%<path>s`.'
|
|
86
|
+
|
|
87
|
+
RESTRICT_ON_SEND = %i[remove_const].freeze
|
|
88
|
+
|
|
89
|
+
# @!method remove_constant(node)
|
|
90
|
+
def_node_matcher :remove_constant, <<~PATTERN
|
|
91
|
+
(send {nil? self} :remove_const
|
|
92
|
+
({sym str} $_))
|
|
93
|
+
PATTERN
|
|
94
|
+
|
|
95
|
+
def on_class(node)
|
|
96
|
+
return unless unconditional_definition?(node)
|
|
97
|
+
|
|
98
|
+
constant_definitions[definition_name(node)] ||= :class
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def on_module(node)
|
|
102
|
+
return unless unconditional_definition?(node)
|
|
103
|
+
|
|
104
|
+
constant_definitions[definition_name(node)] ||= :module
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def on_casgn(node)
|
|
108
|
+
return unless fixed_constant_path?(node)
|
|
109
|
+
return unless simple_assignment?(node)
|
|
110
|
+
|
|
111
|
+
name = fully_qualified_constant_name(node)
|
|
112
|
+
|
|
113
|
+
if constant_definitions.key?(name)
|
|
114
|
+
add_offense(node, message: format(MSG, constant: constant_display_name(node)))
|
|
115
|
+
return
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
constant_definitions[name] = :casgn
|
|
119
|
+
report_cross_file_collision(node, name, constant_display_name(node))
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def on_send(node)
|
|
123
|
+
constant = remove_constant(node)
|
|
124
|
+
|
|
125
|
+
return unless constant
|
|
126
|
+
|
|
127
|
+
namespaces = ancestor_namespaces(node)
|
|
128
|
+
|
|
129
|
+
return if namespaces.none?
|
|
130
|
+
|
|
131
|
+
constant_definitions.delete(fully_qualified_name_for(namespaces, constant))
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
private
|
|
135
|
+
|
|
136
|
+
def fixed_constant_path?(node)
|
|
137
|
+
node.each_path.all? { |path| path.type?(:cbase, :const, :self) }
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def simple_assignment?(node)
|
|
141
|
+
node.ancestors.all? do |ancestor|
|
|
142
|
+
return true if ancestor.type?(:module, :class)
|
|
143
|
+
|
|
144
|
+
ancestor.begin_type? || ancestor.literal? || ancestor.casgn_type? ||
|
|
145
|
+
ancestor.type?(:masgn, :mlhs) || freeze_method?(ancestor)
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
def freeze_method?(node)
|
|
150
|
+
node.send_type? && node.method?(:freeze)
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def fully_qualified_constant_name(node)
|
|
154
|
+
if node.absolute?
|
|
155
|
+
namespace = node.namespace.const_type? ? node.namespace.source : nil
|
|
156
|
+
|
|
157
|
+
"#{namespace}::#{node.name}"
|
|
158
|
+
else
|
|
159
|
+
constant_namespaces = ancestor_namespaces(node) + constant_namespaces(node)
|
|
160
|
+
|
|
161
|
+
fully_qualified_name_for(constant_namespaces, node.name)
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
def fully_qualified_name_for(namespaces, constant)
|
|
166
|
+
['', *namespaces, constant].join('::')
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
def constant_display_name(node)
|
|
170
|
+
[*constant_namespaces(node), node.name].join('::')
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
def constant_namespaces(node)
|
|
174
|
+
node.each_path.select(&:const_type?).map(&:short_name)
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
def ancestor_namespaces(node)
|
|
178
|
+
ancestors = node.each_ancestor(:class, :module).reverse_each
|
|
179
|
+
|
|
180
|
+
ancestors.with_object([]) do |ancestor, namespaces|
|
|
181
|
+
append_namespaces(namespaces, ancestor.identifier)
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
# Compact definitions (e.g. `module A::B`) contribute every path segment,
|
|
186
|
+
# and an absolute one (e.g. `module ::A::B`) discards the enclosing namespaces.
|
|
187
|
+
def append_namespaces(namespaces, identifier)
|
|
188
|
+
namespaces.clear if identifier.absolute?
|
|
189
|
+
namespaces.concat(identifier_namespaces(identifier))
|
|
190
|
+
namespaces << identifier.short_name
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
def unconditional_definition?(node)
|
|
194
|
+
node.each_ancestor.all? do |ancestor|
|
|
195
|
+
ancestor.type?(:begin, :module, :class)
|
|
196
|
+
end
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
def definition_name(node)
|
|
200
|
+
namespaces = ancestor_namespaces(node)
|
|
201
|
+
append_namespaces(namespaces, node.identifier)
|
|
202
|
+
constant = namespaces.pop
|
|
203
|
+
|
|
204
|
+
fully_qualified_name_for(namespaces, constant)
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
def identifier_namespaces(identifier)
|
|
208
|
+
identifier.each_path.select(&:const_type?).map(&:short_name)
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
def constant_definitions
|
|
212
|
+
@constant_definitions ||= {}
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
def report_cross_file_collision(node, fully_qualified_name, display_name)
|
|
216
|
+
return unless project_index
|
|
217
|
+
return unless (declaration = project_index[fully_qualified_name.delete_prefix('::')])
|
|
218
|
+
return unless (prior = prior_definition_in_other_file(declaration.definitions))
|
|
219
|
+
|
|
220
|
+
msg = format(CROSS_FILE_MSG, constant: display_name, path: prior.location.to_file_path)
|
|
221
|
+
|
|
222
|
+
add_offense(node, message: msg)
|
|
223
|
+
end
|
|
224
|
+
end
|
|
225
|
+
end
|
|
226
|
+
end
|
|
227
|
+
end
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
module RuboCop
|
|
4
4
|
module Cop
|
|
5
5
|
module Lint
|
|
6
|
-
#
|
|
6
|
+
# Checks that certain constants are fully qualified.
|
|
7
7
|
#
|
|
8
8
|
# This is not enabled by default because it would mark a lot of offenses
|
|
9
9
|
# unnecessarily.
|
|
@@ -13,12 +13,18 @@ module RuboCop
|
|
|
13
13
|
#
|
|
14
14
|
# Large projects will over time end up with one or two constant names that
|
|
15
15
|
# are problematic because of a conflict with a library or just internally
|
|
16
|
-
# using the same name a namespace and a class. To avoid too many unnecessary
|
|
17
|
-
# offenses,
|
|
16
|
+
# using the same name for a namespace and a class. To avoid too many unnecessary
|
|
17
|
+
# offenses, enable this cop with `Only: [The, Constant, Names, Causing, Issues]`
|
|
18
18
|
#
|
|
19
|
-
# NOTE: `Style/RedundantConstantBase` cop is disabled if this cop is enabled
|
|
20
|
-
# conflicting rules.
|
|
21
|
-
# this cop which is disabled by default.
|
|
19
|
+
# NOTE: `Style/RedundantConstantBase` cop is disabled if this cop is enabled,
|
|
20
|
+
# to prevent conflicting rules. This is because it respects user configurations
|
|
21
|
+
# that want to enable this cop which is disabled by default.
|
|
22
|
+
#
|
|
23
|
+
# When `AllCops/UseProjectIndex` is enabled and the `rubydex` gem is
|
|
24
|
+
# installed, only genuinely ambiguous constants are reported: those
|
|
25
|
+
# that resolve to a different declaration through the surrounding
|
|
26
|
+
# nesting than they would fully qualified. This makes the cop practical
|
|
27
|
+
# to enable without `Only`/`Ignore` lists.
|
|
22
28
|
#
|
|
23
29
|
# @example
|
|
24
30
|
# # By default checks every constant
|
|
@@ -60,6 +66,8 @@ module RuboCop
|
|
|
60
66
|
# Login
|
|
61
67
|
#
|
|
62
68
|
class ConstantResolution < Base
|
|
69
|
+
include ProjectIndexHelp
|
|
70
|
+
|
|
63
71
|
MSG = 'Fully qualify this constant to avoid possibly ambiguous resolution.'
|
|
64
72
|
|
|
65
73
|
# @!method unqualified_const?(node)
|
|
@@ -69,12 +77,29 @@ module RuboCop
|
|
|
69
77
|
|
|
70
78
|
def on_const(node)
|
|
71
79
|
return if !unqualified_const?(node) || node.parent&.defined_module || node.loc.nil?
|
|
80
|
+
return if project_index && !ambiguous_resolution?(node)
|
|
72
81
|
|
|
73
82
|
add_offense(node)
|
|
74
83
|
end
|
|
75
84
|
|
|
76
85
|
private
|
|
77
86
|
|
|
87
|
+
# When `AllCops/UseProjectIndex` is enabled, only genuinely ambiguous
|
|
88
|
+
# references are reported: the constant resolves to a different
|
|
89
|
+
# declaration through the lexical nesting than it would fully
|
|
90
|
+
# qualified. Names that resolve identically either way, or that the
|
|
91
|
+
# index cannot resolve at all (e.g. constants from gems), are not
|
|
92
|
+
# reported.
|
|
93
|
+
def ambiguous_resolution?(node)
|
|
94
|
+
name = node.short_name.to_s
|
|
95
|
+
relative = project_index.resolve_constant(name, lexical_nesting_of(node))
|
|
96
|
+
absolute = project_index.resolve_constant(name, [])
|
|
97
|
+
|
|
98
|
+
!relative.nil? && !absolute.nil? && relative.name != absolute.name
|
|
99
|
+
rescue StandardError
|
|
100
|
+
false
|
|
101
|
+
end
|
|
102
|
+
|
|
78
103
|
def const_name?(name)
|
|
79
104
|
name = name.to_s
|
|
80
105
|
(allowed_names.empty? || allowed_names.include?(name)) && !ignored_names.include?(name)
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# rubocop:disable Lint/RedundantCopDisableDirective
|
|
4
|
+
# rubocop:disable Style/DoubleCopDisableDirective
|
|
5
|
+
module RuboCop
|
|
6
|
+
module Cop
|
|
7
|
+
module Lint
|
|
8
|
+
# Checks that `# rubocop:enable ...` and `# rubocop:disable ...` statements
|
|
9
|
+
# are strictly formatted.
|
|
10
|
+
#
|
|
11
|
+
# A comment can be added to the directive by prefixing it with `--`.
|
|
12
|
+
#
|
|
13
|
+
# @example
|
|
14
|
+
# # bad
|
|
15
|
+
# # rubocop:disable Layout/LineLength Style/Encoding
|
|
16
|
+
#
|
|
17
|
+
# # good
|
|
18
|
+
# # rubocop:disable Layout/LineLength, Style/Encoding
|
|
19
|
+
#
|
|
20
|
+
# # bad
|
|
21
|
+
# # rubocop:disable
|
|
22
|
+
#
|
|
23
|
+
# # good
|
|
24
|
+
# # rubocop:disable all
|
|
25
|
+
#
|
|
26
|
+
# # bad
|
|
27
|
+
# # rubocop:disable Layout/LineLength # rubocop:disable Style/Encoding
|
|
28
|
+
#
|
|
29
|
+
# # good
|
|
30
|
+
# # rubocop:disable Layout/LineLength
|
|
31
|
+
# # rubocop:disable Style/Encoding
|
|
32
|
+
#
|
|
33
|
+
# # bad
|
|
34
|
+
# # rubocop:wrongmode Layout/LineLength
|
|
35
|
+
#
|
|
36
|
+
# # good
|
|
37
|
+
# # rubocop:disable Layout/LineLength
|
|
38
|
+
#
|
|
39
|
+
# # bad
|
|
40
|
+
# # rubocop:disable Layout/LineLength comment
|
|
41
|
+
#
|
|
42
|
+
# # good
|
|
43
|
+
# # rubocop:disable Layout/LineLength -- comment
|
|
44
|
+
#
|
|
45
|
+
# # bad
|
|
46
|
+
# # rucocop:disable Layout/LineLength
|
|
47
|
+
#
|
|
48
|
+
# # good
|
|
49
|
+
# # rubocop:disable Layout/LineLength
|
|
50
|
+
#
|
|
51
|
+
# # bad
|
|
52
|
+
# # rubocop:disable Layout/LineLenght
|
|
53
|
+
#
|
|
54
|
+
# # good
|
|
55
|
+
# # rubocop:disable Layout/LineLength
|
|
56
|
+
#
|
|
57
|
+
class CopDirectiveSyntax < Base
|
|
58
|
+
COMMON_MSG = 'Malformed directive comment detected.'
|
|
59
|
+
|
|
60
|
+
MISSING_MODE_NAME_MSG = 'The mode name is missing.'
|
|
61
|
+
INVALID_MODE_NAME_MSG = 'The mode name must be one of `enable`, `disable`, `disable-next`, `todo`, `todo-next`, `push`, or `pop`.' # rubocop:disable Layout/LineLength
|
|
62
|
+
MISSING_COP_NAME_MSG = 'The cop name is missing.'
|
|
63
|
+
MALFORMED_COP_NAMES_MSG = 'Cop names must be separated by commas. ' \
|
|
64
|
+
'Comment in the directive must start with `--`.'
|
|
65
|
+
NEXT_DIRECTIVE_AT_EOL_MSG = 'A `-next` directive must be on its own line, above the ' \
|
|
66
|
+
'statement it applies to.'
|
|
67
|
+
INVALID_KEYWORD_MSG = 'The directive keyword must be `rubocop`, not `%<keyword>s`.'
|
|
68
|
+
UNKNOWN_COP_MSG = 'Unknown cop name `%<name>s`%<suggestion>s.'
|
|
69
|
+
|
|
70
|
+
# A comment that looks like an attempted directive: any keyword
|
|
71
|
+
# followed by a colon and a valid mode name.
|
|
72
|
+
NEAR_MISS_KEYWORD_REGEXP = /
|
|
73
|
+
\A\#+\s*(?<keyword>[A-Za-z][\w-]*)\s*:\s*
|
|
74
|
+
(?:#{DirectiveComment::MODES_PATTERN})\b
|
|
75
|
+
/x.freeze
|
|
76
|
+
|
|
77
|
+
def on_new_investigation
|
|
78
|
+
processed_source.comments.each do |comment|
|
|
79
|
+
directive_comment = DirectiveComment.new(comment)
|
|
80
|
+
if directive_comment.start_with_marker?
|
|
81
|
+
check_directive(comment, directive_comment)
|
|
82
|
+
elsif (keyword = near_miss_keyword(comment))
|
|
83
|
+
message = format("#{COMMON_MSG} #{INVALID_KEYWORD_MSG}", keyword: keyword)
|
|
84
|
+
add_offense(comment, message: message)
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
private
|
|
90
|
+
|
|
91
|
+
def check_directive(comment, directive_comment)
|
|
92
|
+
if directive_comment.malformed?
|
|
93
|
+
add_offense(comment, message: offense_message(directive_comment))
|
|
94
|
+
elsif misplaced_next_directive?(directive_comment)
|
|
95
|
+
add_offense(comment, message: NEXT_DIRECTIVE_AT_EOL_MSG)
|
|
96
|
+
elsif (name = unknown_cop_name(directive_comment))
|
|
97
|
+
add_offense(comment, message: unknown_cop_message(directive_comment, name))
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
# An EOL `disable-next` is not honored - it must fail loudly instead
|
|
102
|
+
# of silently doing nothing.
|
|
103
|
+
def misplaced_next_directive?(directive_comment)
|
|
104
|
+
directive_comment.disable_next? &&
|
|
105
|
+
!processed_source.comment_config.comment_only_line?(directive_comment.line_number)
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
# rubocop:disable-next Metrics/MethodLength
|
|
109
|
+
def offense_message(directive_comment)
|
|
110
|
+
comment = directive_comment.comment
|
|
111
|
+
after_marker = comment.text.sub(DirectiveComment::DIRECTIVE_MARKER_REGEXP, '')
|
|
112
|
+
mode = after_marker.split(' ', 2).first
|
|
113
|
+
additional_msg = if mode.nil?
|
|
114
|
+
MISSING_MODE_NAME_MSG
|
|
115
|
+
elsif !DirectiveComment::AVAILABLE_MODES.include?(mode)
|
|
116
|
+
INVALID_MODE_NAME_MSG
|
|
117
|
+
elsif directive_comment.missing_cop_name?
|
|
118
|
+
MISSING_COP_NAME_MSG
|
|
119
|
+
else
|
|
120
|
+
MALFORMED_COP_NAMES_MSG
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
"#{COMMON_MSG} #{additional_msg}"
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def near_miss_keyword(comment)
|
|
127
|
+
match = comment.text.match(NEAR_MISS_KEYWORD_REGEXP)
|
|
128
|
+
return unless match
|
|
129
|
+
|
|
130
|
+
keyword = match[:keyword]
|
|
131
|
+
return if keyword == 'rubocop'
|
|
132
|
+
|
|
133
|
+
keyword if similar_to_rubocop?(keyword)
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def similar_to_rubocop?(keyword)
|
|
137
|
+
return true if keyword.casecmp?('rubocop')
|
|
138
|
+
# `DidYouMean` is not always available - see `NameSimilarity`.
|
|
139
|
+
return false unless defined?(DidYouMean::Levenshtein)
|
|
140
|
+
|
|
141
|
+
DidYouMean::Levenshtein.distance(keyword.downcase, 'rubocop') <= 2
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def unknown_cop_name(directive_comment)
|
|
145
|
+
return if directive_comment.push? || directive_comment.pop? || directive_comment.all_cops?
|
|
146
|
+
|
|
147
|
+
registry = directive_comment.cop_registry
|
|
148
|
+
directive_comment.raw_cop_names.find do |name|
|
|
149
|
+
next false if registry.department?(name)
|
|
150
|
+
|
|
151
|
+
qualified = registry.qualified_cop_name(name, nil, warn: false)
|
|
152
|
+
!registry.contains_cop_matching?([qualified])
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
def unknown_cop_message(directive_comment, name)
|
|
157
|
+
similar = NameSimilarity.find_similar_name(name, directive_comment.cop_registry.names)
|
|
158
|
+
suggestion = similar ? " (did you mean `#{similar}`?)" : ''
|
|
159
|
+
format(UNKNOWN_COP_MSG, name: name, suggestion: suggestion)
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
# rubocop:enable Lint/RedundantCopDisableDirective
|
|
166
|
+
# rubocop:enable Style/DoubleCopDisableDirective
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module Cop
|
|
5
|
+
module Lint
|
|
6
|
+
# Checks unexpected overrides of the `Data` built-in methods
|
|
7
|
+
# via `Data.define`.
|
|
8
|
+
#
|
|
9
|
+
# @example
|
|
10
|
+
# # bad
|
|
11
|
+
# Bad = Data.define(:members, :clone, :to_s)
|
|
12
|
+
# b = Bad.new(members: [], clone: true, to_s: 'bad')
|
|
13
|
+
# b.members #=> [] (overriding `Data#members`)
|
|
14
|
+
# b.clone #=> true (overriding `Object#clone`)
|
|
15
|
+
# b.to_s #=> "bad" (overriding `Data#to_s`)
|
|
16
|
+
#
|
|
17
|
+
# # good
|
|
18
|
+
# Good = Data.define(:id, :name)
|
|
19
|
+
# g = Good.new(id: 1, name: "foo")
|
|
20
|
+
# g.members #=> [:id, :name]
|
|
21
|
+
# g.clone #=> #<data Good id=1, name="foo">
|
|
22
|
+
#
|
|
23
|
+
class DataDefineOverride < Base
|
|
24
|
+
MSG = '`%<member_name>s` member overrides `Data#%<method_name>s` and it may be unexpected.'
|
|
25
|
+
RESTRICT_ON_SEND = %i[define].freeze
|
|
26
|
+
|
|
27
|
+
# This is based on `Data.define.instance_methods.sort` in Ruby 4.0.0.
|
|
28
|
+
DATA_METHOD_NAMES = %i[
|
|
29
|
+
! != !~ <=> == === __id__ __send__ class clone deconstruct deconstruct_keys
|
|
30
|
+
define_singleton_method display dup enum_for eql? equal? extend freeze frozen? hash
|
|
31
|
+
inspect instance_eval instance_exec instance_of? instance_variable_defined?
|
|
32
|
+
instance_variable_get instance_variable_set instance_variables is_a? itself kind_of?
|
|
33
|
+
members method methods nil? object_id private_methods protected_methods
|
|
34
|
+
public_method public_methods public_send remove_instance_variable respond_to? send
|
|
35
|
+
singleton_class singleton_method singleton_methods tap then to_enum to_h to_s with
|
|
36
|
+
yield_self
|
|
37
|
+
].freeze
|
|
38
|
+
MEMBER_NAME_TYPES = %i[sym str].freeze
|
|
39
|
+
|
|
40
|
+
# @!method data_define(node)
|
|
41
|
+
def_node_matcher :data_define, <<~PATTERN
|
|
42
|
+
(send
|
|
43
|
+
(const {nil? cbase} :Data) :define ...)
|
|
44
|
+
PATTERN
|
|
45
|
+
|
|
46
|
+
def on_send(node)
|
|
47
|
+
return unless data_define(node)
|
|
48
|
+
|
|
49
|
+
node.arguments.each do |arg|
|
|
50
|
+
next unless MEMBER_NAME_TYPES.include?(arg.type)
|
|
51
|
+
|
|
52
|
+
member_name = arg.value
|
|
53
|
+
|
|
54
|
+
next unless DATA_METHOD_NAMES.include?(member_name.to_sym)
|
|
55
|
+
|
|
56
|
+
message = format(MSG, member_name: member_name.inspect, method_name: member_name.to_s)
|
|
57
|
+
add_offense(arg, message: message)
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
@@ -29,6 +29,11 @@ module RuboCop
|
|
|
29
29
|
# MyDebugger.debug_this
|
|
30
30
|
# ----
|
|
31
31
|
#
|
|
32
|
+
# Some gems also ship files that will start a debugging session when required,
|
|
33
|
+
# for example `require 'debug/start'` from `ruby/debug`. These requires can
|
|
34
|
+
# be configured through `DebuggerRequires`. It has the same structure as
|
|
35
|
+
# `DebuggerMethods`, which you can read about above.
|
|
36
|
+
#
|
|
32
37
|
# @example
|
|
33
38
|
#
|
|
34
39
|
# # bad (ok during development)
|
|
@@ -39,8 +44,6 @@ module RuboCop
|
|
|
39
44
|
# do_something
|
|
40
45
|
# end
|
|
41
46
|
#
|
|
42
|
-
# @example
|
|
43
|
-
#
|
|
44
47
|
# # bad (ok during development)
|
|
45
48
|
#
|
|
46
49
|
# # using byebug
|
|
@@ -49,8 +52,6 @@ module RuboCop
|
|
|
49
52
|
# do_something
|
|
50
53
|
# end
|
|
51
54
|
#
|
|
52
|
-
# @example
|
|
53
|
-
#
|
|
54
55
|
# # good
|
|
55
56
|
#
|
|
56
57
|
# def some_method
|
|
@@ -64,14 +65,18 @@ module RuboCop
|
|
|
64
65
|
# def some_method
|
|
65
66
|
# my_debugger
|
|
66
67
|
# end
|
|
68
|
+
#
|
|
69
|
+
# @example DebuggerRequires: [my_debugger/start]
|
|
70
|
+
#
|
|
71
|
+
# # bad (ok during development)
|
|
72
|
+
#
|
|
73
|
+
# require 'my_debugger/start'
|
|
67
74
|
class Debugger < Base
|
|
68
75
|
MSG = 'Remove debugger entry point `%<source>s`.'
|
|
69
76
|
|
|
70
77
|
def on_send(node)
|
|
71
|
-
return unless debugger_method?(node)
|
|
72
|
-
|
|
73
|
-
# Basically, debugger methods are not used as a method argument without arguments.
|
|
74
|
-
return if node.arguments.empty? && node.each_ancestor(:send, :csend).any?
|
|
78
|
+
return unless debugger_method?(node) || debugger_require?(node)
|
|
79
|
+
return if assumed_usage_context?(node)
|
|
75
80
|
|
|
76
81
|
add_offense(node)
|
|
77
82
|
end
|
|
@@ -89,12 +94,45 @@ module RuboCop
|
|
|
89
94
|
end
|
|
90
95
|
end
|
|
91
96
|
|
|
97
|
+
def debugger_requires
|
|
98
|
+
@debugger_requires ||= begin
|
|
99
|
+
config = cop_config.fetch('DebuggerRequires', [])
|
|
100
|
+
config.is_a?(Array) ? config : config.values.flatten
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
92
104
|
def debugger_method?(send_node)
|
|
93
|
-
return false
|
|
105
|
+
return false unless debugger_method_names.include?(send_node.method_name)
|
|
94
106
|
|
|
95
107
|
debugger_methods.include?(chained_method_name(send_node))
|
|
96
108
|
end
|
|
97
109
|
|
|
110
|
+
# The last segment of each configured debugger method, used to cheaply
|
|
111
|
+
# rule out the vast majority of `send` nodes before building the
|
|
112
|
+
# chained method name.
|
|
113
|
+
def debugger_method_names
|
|
114
|
+
@debugger_method_names ||= debugger_methods.to_set do |method|
|
|
115
|
+
method.to_s.split('.').last&.to_sym
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def debugger_require?(send_node)
|
|
120
|
+
return false unless send_node.method?(:require) && send_node.arguments.one?
|
|
121
|
+
return false unless (argument = send_node.first_argument).str_type?
|
|
122
|
+
|
|
123
|
+
debugger_requires.include?(argument.value)
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def assumed_usage_context?(node)
|
|
127
|
+
# Basically, debugger methods are not used as a method argument without arguments.
|
|
128
|
+
return false unless node.arguments.empty? && node.each_ancestor(:call).any?
|
|
129
|
+
return true if assumed_argument?(node)
|
|
130
|
+
|
|
131
|
+
node.each_ancestor.none? do |ancestor|
|
|
132
|
+
ancestor.type?(:any_block, :kwbegin) || ancestor.lambda_or_proc?
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
|
|
98
136
|
def chained_method_name(send_node)
|
|
99
137
|
chained_method_name = send_node.method_name.to_s
|
|
100
138
|
receiver = send_node.receiver
|
|
@@ -105,6 +143,12 @@ module RuboCop
|
|
|
105
143
|
end
|
|
106
144
|
chained_method_name
|
|
107
145
|
end
|
|
146
|
+
|
|
147
|
+
def assumed_argument?(node)
|
|
148
|
+
parent = node.parent
|
|
149
|
+
|
|
150
|
+
parent.call_type? || parent.literal? || parent.pair_type?
|
|
151
|
+
end
|
|
108
152
|
end
|
|
109
153
|
end
|
|
110
154
|
end
|
|
@@ -43,7 +43,7 @@ module RuboCop
|
|
|
43
43
|
dup: 'to_h',
|
|
44
44
|
exists?: 'exist?',
|
|
45
45
|
gethostbyaddr: 'Addrinfo#getnameinfo',
|
|
46
|
-
gethostbyname: 'Addrinfo
|
|
46
|
+
gethostbyname: 'Addrinfo.getaddrinfo',
|
|
47
47
|
iterator?: 'block_given?'
|
|
48
48
|
}.freeze
|
|
49
49
|
|
|
@@ -52,7 +52,7 @@ module RuboCop
|
|
|
52
52
|
# @!method deprecated_class_method?(node)
|
|
53
53
|
def_node_matcher :deprecated_class_method?, <<~PATTERN
|
|
54
54
|
{
|
|
55
|
-
(send (const {cbase nil?}
|
|
55
|
+
(send (const {cbase nil?} :ENV) {:clone :dup :freeze})
|
|
56
56
|
(send (const {cbase nil?} {:File :Dir}) :exists? _)
|
|
57
57
|
(send (const {cbase nil?} :Socket) {:gethostbyaddr :gethostbyname} ...)
|
|
58
58
|
(send nil? :attr _ boolean)
|
|
@@ -14,7 +14,7 @@ module RuboCop
|
|
|
14
14
|
# Alternative: 'alternative_value'
|
|
15
15
|
# DeprecatedVersion: 'deprecated_version'
|
|
16
16
|
#
|
|
17
|
-
# By default, `NIL`, `TRUE`, `FALSE`, `Net::HTTPServerException
|
|
17
|
+
# By default, `NIL`, `TRUE`, `FALSE`, `Net::HTTPServerException`, `Random::DEFAULT`,
|
|
18
18
|
# `Struct::Group`, and `Struct::Passwd` are configured.
|
|
19
19
|
#
|
|
20
20
|
# @example
|
|
@@ -49,7 +49,7 @@ module RuboCop
|
|
|
49
49
|
# Maybe further investigation of RuboCop AST will lead to an essential solution.
|
|
50
50
|
return unless node.loc
|
|
51
51
|
|
|
52
|
-
constant = node.
|
|
52
|
+
constant = node.source.delete_prefix('::')
|
|
53
53
|
return unless (deprecated_constant = deprecated_constants[constant])
|
|
54
54
|
|
|
55
55
|
alternative = deprecated_constant['Alternative']
|
|
@@ -63,12 +63,6 @@ module RuboCop
|
|
|
63
63
|
|
|
64
64
|
private
|
|
65
65
|
|
|
66
|
-
def constant_name(node, nested_constant_name)
|
|
67
|
-
return nested_constant_name.to_s unless node.namespace.const_type?
|
|
68
|
-
|
|
69
|
-
constant_name(node.namespace, "#{node.namespace.short_name}::#{nested_constant_name}")
|
|
70
|
-
end
|
|
71
|
-
|
|
72
66
|
def message(good, bad, deprecated_version)
|
|
73
67
|
deprecated_message = ", deprecated since Ruby #{deprecated_version}" if deprecated_version
|
|
74
68
|
|