rubocop 1.81.7 → 1.92.1
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 +2 -2
- data/config/default.yml +626 -111
- data/config/obsoletion.yml +39 -1
- data/exe/rubocop +1 -1
- data/lib/rubocop/cache_config.rb +29 -0
- data/lib/rubocop/cached_data.rb +50 -5
- data/lib/rubocop/changed_files.rb +134 -0
- data/lib/rubocop/cli/command/auto_generate_config.rb +34 -2
- data/lib/rubocop/cli/command/cop_names.rb +57 -0
- data/lib/rubocop/cli/command/execute_runner.rb +54 -3
- data/lib/rubocop/cli/command/explain.rb +34 -0
- data/lib/rubocop/cli/command/list_enabled_cops_for.rb +40 -0
- data/lib/rubocop/cli/command/lsp.rb +1 -1
- data/lib/rubocop/cli/command/mcp.rb +19 -0
- data/lib/rubocop/cli/command/show_cops.rb +8 -2
- data/lib/rubocop/cli/command/show_docs_url.rb +8 -10
- data/lib/rubocop/cli/command/suggest_extensions.rb +1 -1
- data/lib/rubocop/cli.rb +41 -14
- data/lib/rubocop/comment_config/directive_range.rb +34 -0
- data/lib/rubocop/comment_config/disable_next.rb +143 -0
- data/lib/rubocop/comment_config/push_pop.rb +55 -0
- data/lib/rubocop/comment_config.rb +97 -44
- data/lib/rubocop/config.rb +100 -15
- data/lib/rubocop/config_finder.rb +1 -1
- data/lib/rubocop/config_loader.rb +49 -27
- data/lib/rubocop/config_loader_resolver.rb +95 -20
- data/lib/rubocop/config_obsoletion/cop_rule.rb +2 -1
- data/lib/rubocop/config_obsoletion/extracted_cop.rb +4 -2
- data/lib/rubocop/config_obsoletion/removed_cop.rb +9 -1
- data/lib/rubocop/config_obsoletion.rb +1 -1
- data/lib/rubocop/config_store.rb +2 -2
- data/lib/rubocop/config_validator.rb +69 -7
- data/lib/rubocop/cop/autocorrect_logic.rb +24 -6
- data/lib/rubocop/cop/badge.rb +10 -2
- data/lib/rubocop/cop/base.rb +128 -35
- data/lib/rubocop/cop/bundler/gem_comment.rb +5 -4
- data/lib/rubocop/cop/bundler/gem_version.rb +28 -28
- data/lib/rubocop/cop/bundler/ordered_gems.rb +1 -10
- data/lib/rubocop/cop/bundler.rb +19 -0
- data/lib/rubocop/cop/commissioner.rb +13 -11
- data/lib/rubocop/cop/cop_documentation.rb +81 -0
- data/lib/rubocop/cop/cop_explanation.rb +140 -0
- data/lib/rubocop/cop/corrector.rb +4 -4
- data/lib/rubocop/cop/correctors/alignment_corrector.rb +87 -9
- data/lib/rubocop/cop/correctors/condition_corrector.rb +1 -1
- data/lib/rubocop/cop/correctors/each_to_for_corrector.rb +37 -7
- data/lib/rubocop/cop/correctors/empty_line_corrector.rb +1 -1
- data/lib/rubocop/cop/correctors/lambda_literal_to_method_corrector.rb +31 -4
- data/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +35 -5
- data/lib/rubocop/cop/correctors/ordered_gem_corrector.rb +8 -1
- data/lib/rubocop/cop/correctors/parentheses_corrector.rb +70 -2
- data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +2 -2
- data/lib/rubocop/cop/correctors.rb +28 -0
- data/lib/rubocop/cop/documentation.rb +3 -4
- data/lib/rubocop/cop/exclude_limit.rb +31 -5
- data/lib/rubocop/cop/gemspec/dependency_version.rb +0 -6
- data/lib/rubocop/cop/gemspec/development_dependencies.rb +1 -1
- data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +14 -4
- data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +1 -8
- data/lib/rubocop/cop/gemspec/require_mfa.rb +9 -6
- data/lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb +12 -7
- data/lib/rubocop/cop/gemspec.rb +22 -0
- data/lib/rubocop/cop/generator/registration_injector.rb +188 -0
- data/lib/rubocop/cop/generator.rb +5 -1
- data/lib/rubocop/cop/internal_affairs/example_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 +28 -2
- data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +1 -0
- data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +12 -16
- data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_processor.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_walker.rb +1 -2
- data/lib/rubocop/cop/internal_affairs/node_type_group.rb +0 -7
- data/lib/rubocop/cop/internal_affairs/on_send_without_on_csend.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/redundant_context_config_parameter.rb +1 -7
- data/lib/rubocop/cop/internal_affairs/redundant_let_rubocop_config_new.rb +5 -3
- data/lib/rubocop/cop/internal_affairs/style_detected_api_use.rb +1 -7
- data/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +4 -4
- data/lib/rubocop/cop/internal_affairs.rb +1 -0
- data/lib/rubocop/cop/layout/argument_alignment.rb +9 -3
- data/lib/rubocop/cop/layout/array_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/begin_end_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/block_alignment.rb +84 -4
- data/lib/rubocop/cop/layout/case_indentation.rb +28 -10
- data/lib/rubocop/cop/layout/class_structure.rb +156 -41
- data/lib/rubocop/cop/layout/comment_indentation.rb +17 -7
- data/lib/rubocop/cop/layout/condition_position.rb +13 -3
- data/lib/rubocop/cop/layout/def_end_alignment.rb +4 -0
- data/lib/rubocop/cop/layout/dot_position.rb +26 -16
- data/lib/rubocop/cop/layout/else_alignment.rb +2 -14
- data/lib/rubocop/cop/layout/empty_comment.rb +8 -10
- data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +25 -7
- data/lib/rubocop/cop/layout/empty_line_after_magic_comment.rb +63 -5
- data/lib/rubocop/cop/layout/empty_line_after_multiline_condition.rb +21 -8
- data/lib/rubocop/cop/layout/empty_line_between_defs.rb +15 -2
- data/lib/rubocop/cop/layout/empty_lines.rb +5 -2
- data/lib/rubocop/cop/layout/empty_lines_after_module_inclusion.rb +2 -2
- data/lib/rubocop/cop/layout/empty_lines_around_attribute_accessor.rb +2 -0
- data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +21 -5
- data/lib/rubocop/cop/layout/empty_lines_around_class_body.rb +16 -2
- data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +23 -1
- data/lib/rubocop/cop/layout/empty_lines_around_module_body.rb +16 -2
- data/lib/rubocop/cop/layout/end_alignment.rb +23 -15
- data/lib/rubocop/cop/layout/extra_spacing.rb +109 -3
- data/lib/rubocop/cop/layout/first_argument_indentation.rb +81 -2
- data/lib/rubocop/cop/layout/first_array_element_indentation.rb +18 -5
- data/lib/rubocop/cop/layout/first_array_element_line_break.rb +41 -0
- data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +36 -23
- data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +25 -25
- data/lib/rubocop/cop/layout/first_method_argument_line_break.rb +6 -0
- data/lib/rubocop/cop/layout/first_method_parameter_line_break.rb +4 -0
- data/lib/rubocop/cop/layout/first_parameter_indentation.rb +11 -0
- data/lib/rubocop/cop/layout/hash_alignment.rb +16 -11
- data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +8 -4
- data/lib/rubocop/cop/layout/heredoc_indentation.rb +48 -3
- data/lib/rubocop/cop/layout/indentation_consistency.rb +22 -5
- data/lib/rubocop/cop/layout/indentation_style.rb +5 -2
- data/lib/rubocop/cop/layout/indentation_width.rb +158 -12
- data/lib/rubocop/cop/layout/leading_comment_space.rb +27 -0
- data/lib/rubocop/cop/layout/line_continuation_spacing.rb +10 -4
- data/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb +25 -9
- data/lib/rubocop/cop/layout/line_length.rb +265 -29
- data/lib/rubocop/cop/layout/multiline_array_brace_layout.rb +69 -57
- data/lib/rubocop/cop/layout/multiline_assignment_layout.rb +8 -2
- data/lib/rubocop/cop/layout/multiline_block_layout.rb +10 -1
- data/lib/rubocop/cop/layout/multiline_hash_brace_layout.rb +65 -56
- data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +7 -1
- data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +268 -38
- data/lib/rubocop/cop/layout/multiline_method_definition_brace_layout.rb +4 -0
- data/lib/rubocop/cop/layout/parameter_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/redundant_line_break.rb +102 -2
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +19 -5
- data/lib/rubocop/cop/layout/single_line_block_chain.rb +10 -2
- data/lib/rubocop/cop/layout/space_after_comma.rb +2 -10
- data/lib/rubocop/cop/layout/space_after_not.rb +5 -0
- data/lib/rubocop/cop/layout/space_after_semicolon.rb +1 -1
- data/lib/rubocop/cop/layout/space_around_block_parameters.rb +10 -4
- data/lib/rubocop/cop/layout/space_around_keyword.rb +14 -2
- data/lib/rubocop/cop/layout/space_around_operators.rb +18 -3
- data/lib/rubocop/cop/layout/space_before_block_braces.rb +4 -1
- data/lib/rubocop/cop/layout/space_before_brackets.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 +44 -34
- data/lib/rubocop/cop/layout/space_inside_block_braces.rb +31 -8
- data/lib/rubocop/cop/layout/space_inside_reference_brackets.rb +2 -12
- data/lib/rubocop/cop/layout.rb +114 -0
- data/lib/rubocop/cop/lazy_loader.rb +41 -0
- data/lib/rubocop/cop/lint/ambiguous_assignment.rb +9 -17
- data/lib/rubocop/cop/lint/ambiguous_block_association.rb +72 -1
- data/lib/rubocop/cop/lint/ambiguous_operator.rb +1 -1
- data/lib/rubocop/cop/lint/ambiguous_operator_precedence.rb +3 -11
- data/lib/rubocop/cop/lint/ambiguous_range.rb +1 -2
- data/lib/rubocop/cop/lint/ambiguous_regexp_literal.rb +6 -1
- data/lib/rubocop/cop/lint/argument_mismatch.rb +99 -0
- data/lib/rubocop/cop/lint/assignment_in_condition.rb +15 -1
- data/lib/rubocop/cop/lint/circular_argument_reference.rb +45 -3
- data/lib/rubocop/cop/lint/constant_overwritten_in_rescue.rb +1 -1
- data/lib/rubocop/cop/lint/constant_reassignment.rb +94 -15
- data/lib/rubocop/cop/lint/constant_resolution.rb +31 -6
- data/lib/rubocop/cop/lint/cop_directive_syntax.rb +165 -15
- data/lib/rubocop/cop/lint/data_define_override.rb +63 -0
- data/lib/rubocop/cop/lint/debugger.rb +13 -2
- data/lib/rubocop/cop/lint/deprecated_constants.rb +2 -8
- data/lib/rubocop/cop/lint/deprecated_reference.rb +194 -0
- data/lib/rubocop/cop/lint/duplicate_match_pattern.rb +4 -4
- data/lib/rubocop/cop/lint/duplicate_methods.rb +405 -28
- data/lib/rubocop/cop/lint/else_layout.rb +19 -0
- data/lib/rubocop/cop/lint/empty_block.rb +4 -4
- data/lib/rubocop/cop/lint/empty_conditional_body.rb +9 -2
- data/lib/rubocop/cop/lint/empty_in_pattern.rb +8 -1
- data/lib/rubocop/cop/lint/empty_when.rb +8 -1
- data/lib/rubocop/cop/lint/ensure_return.rb +19 -1
- data/lib/rubocop/cop/lint/erb_new_arguments.rb +4 -2
- data/lib/rubocop/cop/lint/float_comparison.rb +2 -1
- data/lib/rubocop/cop/lint/heredoc_method_call_position.rb +4 -0
- data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +1 -2
- data/lib/rubocop/cop/lint/incompatible_io_select_with_fiber_scheduler.rb +5 -1
- data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +1 -2
- data/lib/rubocop/cop/lint/inherit_exception.rb +53 -7
- data/lib/rubocop/cop/lint/interpolation_check.rb +25 -6
- data/lib/rubocop/cop/lint/lambda_without_literal_block.rb +1 -1
- data/lib/rubocop/cop/lint/literal_as_condition.rb +36 -9
- data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +11 -1
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +75 -37
- data/lib/rubocop/cop/lint/loop.rb +24 -2
- data/lib/rubocop/cop/lint/misplaced_magic_comment.rb +245 -0
- data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +46 -18
- data/lib/rubocop/cop/lint/missing_super.rb +31 -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 +1 -1
- data/lib/rubocop/cop/lint/next_without_accumulator.rb +2 -0
- data/lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +20 -0
- data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +4 -2
- data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +1 -1
- data/lib/rubocop/cop/lint/number_conversion.rb +22 -11
- data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +1 -1
- data/lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +10 -0
- data/lib/rubocop/cop/lint/ordered_magic_comments.rb +7 -7
- data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +15 -4
- data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +20 -14
- data/lib/rubocop/cop/lint/raise_exception.rb +1 -1
- data/lib/rubocop/cop/lint/rand_one.rb +1 -1
- data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +160 -39
- data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +53 -19
- data/lib/rubocop/cop/lint/redundant_dir_glob_sort.rb +28 -6
- data/lib/rubocop/cop/lint/redundant_require_statement.rb +5 -4
- data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +37 -14
- data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +13 -4
- data/lib/rubocop/cop/lint/redundant_type_conversion.rb +11 -5
- data/lib/rubocop/cop/lint/redundant_with_index.rb +2 -3
- data/lib/rubocop/cop/lint/redundant_with_object.rb +5 -0
- data/lib/rubocop/cop/lint/refinement_import_methods.rb +8 -1
- data/lib/rubocop/cop/lint/regexp_as_condition.rb +9 -1
- data/lib/rubocop/cop/lint/require_parentheses.rb +13 -4
- data/lib/rubocop/cop/lint/require_range_parentheses.rb +2 -1
- data/lib/rubocop/cop/lint/require_relative_self_path.rb +7 -5
- data/lib/rubocop/cop/lint/rescue_type.rb +1 -1
- data/lib/rubocop/cop/lint/safe_navigation_chain.rb +24 -0
- data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +56 -6
- data/lib/rubocop/cop/lint/safe_navigation_with_empty.rb +1 -1
- data/lib/rubocop/cop/lint/script_permission.rb +5 -1
- data/lib/rubocop/cop/lint/self_assignment.rb +33 -2
- data/lib/rubocop/cop/lint/send_with_mixin_argument.rb +1 -1
- data/lib/rubocop/cop/lint/shadowed_exception.rb +1 -1
- data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +14 -0
- data/lib/rubocop/cop/lint/shared_mutable_default.rb +3 -1
- data/lib/rubocop/cop/lint/struct_new_override.rb +17 -1
- data/lib/rubocop/cop/lint/super_argument_mismatch.rb +179 -0
- data/lib/rubocop/cop/lint/suppressed_exception_in_number_conversion.rb +13 -2
- data/lib/rubocop/cop/lint/symbol_conversion.rb +22 -4
- data/lib/rubocop/cop/lint/syntax.rb +25 -1
- data/lib/rubocop/cop/lint/to_enum_arguments.rb +72 -4
- data/lib/rubocop/cop/lint/to_json.rb +20 -17
- data/lib/rubocop/cop/lint/top_level_return_with_argument.rb +1 -1
- data/lib/rubocop/cop/lint/trailing_comma_in_attribute_declaration.rb +5 -1
- data/lib/rubocop/cop/lint/unescaped_bracket_in_regexp.rb +54 -11
- data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +1 -0
- data/lib/rubocop/cop/lint/unreachable_code.rb +15 -9
- data/lib/rubocop/cop/lint/unreachable_pattern_branch.rb +113 -0
- data/lib/rubocop/cop/lint/unused_method_argument.rb +10 -0
- data/lib/rubocop/cop/lint/unused_private_method.rb +234 -0
- data/lib/rubocop/cop/lint/useless_access_modifier.rb +1 -2
- data/lib/rubocop/cop/lint/useless_assignment.rb +61 -27
- data/lib/rubocop/cop/lint/useless_constant_scoping.rb +40 -4
- data/lib/rubocop/cop/lint/useless_default_value_argument.rb +2 -0
- data/lib/rubocop/cop/lint/useless_method_definition.rb +1 -1
- data/lib/rubocop/cop/lint/useless_numeric_operation.rb +10 -10
- data/lib/rubocop/cop/lint/useless_or.rb +15 -2
- data/lib/rubocop/cop/lint/useless_rescue.rb +1 -2
- data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +10 -4
- data/lib/rubocop/cop/lint/useless_setter_call.rb +11 -5
- data/lib/rubocop/cop/lint/useless_times.rb +22 -1
- data/lib/rubocop/cop/lint/utils/nil_receiver_checker.rb +94 -14
- data/lib/rubocop/cop/lint/void.rb +59 -22
- data/lib/rubocop/cop/lint.rb +179 -0
- data/lib/rubocop/cop/metrics/block_length.rb +1 -1
- data/lib/rubocop/cop/metrics/block_nesting.rb +23 -0
- data/lib/rubocop/cop/metrics/class_length.rb +4 -2
- data/lib/rubocop/cop/metrics/collection_literal_length.rb +1 -1
- data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +0 -4
- data/lib/rubocop/cop/metrics/method_length.rb +2 -2
- data/lib/rubocop/cop/metrics/module_length.rb +4 -2
- data/lib/rubocop/cop/metrics/perceived_complexity.rb +37 -7
- data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +4 -3
- data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +1 -1
- data/lib/rubocop/cop/metrics/utils/iterating_block.rb +1 -1
- 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 +5 -1
- data/lib/rubocop/cop/mixin/allowed_methods.rb +5 -5
- data/lib/rubocop/cop/mixin/allowed_pattern.rb +5 -1
- data/lib/rubocop/cop/mixin/annotation_comment.rb +1 -1
- data/lib/rubocop/cop/mixin/check_line_breakable.rb +47 -25
- data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +12 -8
- data/lib/rubocop/cop/mixin/code_length.rb +10 -2
- data/lib/rubocop/cop/mixin/comments_help.rb +1 -2
- data/lib/rubocop/cop/mixin/configurable_enforced_style.rb +1 -2
- data/lib/rubocop/cop/mixin/configurable_max.rb +6 -5
- data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +12 -1
- data/lib/rubocop/cop/mixin/endless_method_body_help.rb +105 -0
- data/lib/rubocop/cop/mixin/endless_method_rewriter.rb +13 -5
- data/lib/rubocop/cop/mixin/forbidden_identifiers.rb +2 -2
- data/lib/rubocop/cop/mixin/forbidden_pattern.rb +5 -1
- data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +58 -12
- data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +37 -10
- data/lib/rubocop/cop/mixin/hash_subset.rb +9 -2
- data/lib/rubocop/cop/mixin/hash_transform_method/autocorrection.rb +63 -0
- data/lib/rubocop/cop/mixin/hash_transform_method.rb +14 -60
- data/lib/rubocop/cop/mixin/indexed_method_arity.rb +94 -0
- data/lib/rubocop/cop/mixin/line_length_help.rb +28 -3
- data/lib/rubocop/cop/mixin/method_complexity.rb +1 -1
- data/lib/rubocop/cop/mixin/min_branches_count.rb +3 -1
- data/lib/rubocop/cop/mixin/multiline_element_line_breaks.rb +11 -1
- data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +1 -1
- data/lib/rubocop/cop/mixin/multiline_literal_brace_layout.rb +10 -1
- data/lib/rubocop/cop/mixin/ordered_gem_node.rb +1 -1
- data/lib/rubocop/cop/mixin/pattern_matching_help.rb +35 -0
- data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +79 -8
- data/lib/rubocop/cop/mixin/project_index_help.rb +203 -0
- data/lib/rubocop/cop/mixin/range_help.rb +1 -2
- data/lib/rubocop/cop/mixin/reparsed_equivalence.rb +181 -0
- data/lib/rubocop/cop/mixin/space_after_punctuation.rb +5 -4
- data/lib/rubocop/cop/mixin/statement_modifier.rb +69 -12
- data/lib/rubocop/cop/mixin/trailing_comma.rb +7 -6
- data/lib/rubocop/cop/mixin/visibility_help.rb +2 -1
- data/lib/rubocop/cop/mixin.rb +93 -0
- data/lib/rubocop/cop/naming/accessor_method_name.rb +8 -0
- data/lib/rubocop/cop/naming/binary_operator_parameter_name.rb +17 -1
- data/lib/rubocop/cop/naming/block_forwarding.rb +4 -1
- data/lib/rubocop/cop/naming/block_parameter_name.rb +1 -1
- data/lib/rubocop/cop/naming/file_name.rb +4 -3
- data/lib/rubocop/cop/naming/heredoc_delimiter_case.rb +9 -2
- data/lib/rubocop/cop/naming/heredoc_delimiter_naming.rb +5 -3
- data/lib/rubocop/cop/naming/inclusive_language.rb +8 -2
- data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +12 -5
- data/lib/rubocop/cop/naming/method_name.rb +6 -3
- data/lib/rubocop/cop/naming/predicate_method.rb +13 -2
- data/lib/rubocop/cop/naming/predicate_prefix.rb +30 -17
- data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +12 -7
- data/lib/rubocop/cop/naming/variable_number.rb +3 -1
- data/lib/rubocop/cop/naming.rb +31 -0
- data/lib/rubocop/cop/offense.rb +108 -9
- data/lib/rubocop/cop/registry.rb +232 -66
- data/lib/rubocop/cop/security/eval.rb +15 -2
- data/lib/rubocop/cop/security/io_methods.rb +2 -2
- data/lib/rubocop/cop/security/json_load.rb +16 -4
- data/lib/rubocop/cop/security/marshal_load.rb +1 -1
- data/lib/rubocop/cop/security.rb +19 -0
- data/lib/rubocop/cop/severity.rb +12 -0
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +55 -8
- data/lib/rubocop/cop/style/accessor_grouping.rb +16 -5
- data/lib/rubocop/cop/style/alias.rb +33 -8
- data/lib/rubocop/cop/style/ambiguous_endless_method_definition.rb +4 -3
- data/lib/rubocop/cop/style/and_or.rb +8 -3
- data/lib/rubocop/cop/style/arguments_forwarding.rb +61 -17
- data/lib/rubocop/cop/style/array_first_last.rb +13 -3
- data/lib/rubocop/cop/style/array_intersect.rb +28 -5
- data/lib/rubocop/cop/style/array_intersect_with_single_element.rb +3 -0
- data/lib/rubocop/cop/style/array_join.rb +4 -2
- data/lib/rubocop/cop/style/ascii_comments.rb +6 -3
- data/lib/rubocop/cop/style/attr.rb +8 -6
- data/lib/rubocop/cop/style/bare_percent_literals.rb +4 -3
- data/lib/rubocop/cop/style/begin_block.rb +3 -1
- data/lib/rubocop/cop/style/bitwise_predicate.rb +7 -6
- data/lib/rubocop/cop/style/block_delimiters.rb +74 -38
- data/lib/rubocop/cop/style/case_equality.rb +29 -15
- data/lib/rubocop/cop/style/case_like_if.rb +11 -10
- data/lib/rubocop/cop/style/character_literal.rb +2 -2
- data/lib/rubocop/cop/style/class_and_module_children.rb +151 -35
- data/lib/rubocop/cop/style/class_equality_comparison.rb +21 -13
- data/lib/rubocop/cop/style/class_methods_definitions.rb +26 -5
- data/lib/rubocop/cop/style/collection_compact.rb +37 -17
- data/lib/rubocop/cop/style/collection_querying.rb +79 -46
- data/lib/rubocop/cop/style/colon_method_call.rb +16 -7
- data/lib/rubocop/cop/style/combinable_loops.rb +91 -9
- data/lib/rubocop/cop/style/comparable_clamp.rb +12 -1
- data/lib/rubocop/cop/style/concat_array_literals.rb +65 -9
- data/lib/rubocop/cop/style/conditional_assignment.rb +34 -18
- data/lib/rubocop/cop/style/constant_visibility.rb +13 -7
- data/lib/rubocop/cop/style/copyright.rb +27 -12
- data/lib/rubocop/cop/style/data_inheritance.rb +18 -0
- data/lib/rubocop/cop/style/date_time.rb +4 -4
- data/lib/rubocop/cop/style/def_with_parentheses.rb +6 -2
- data/lib/rubocop/cop/style/dig_chain.rb +5 -0
- data/lib/rubocop/cop/style/dir_empty.rb +4 -0
- data/lib/rubocop/cop/style/directive_scope.rb +304 -0
- data/lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb +184 -20
- data/lib/rubocop/cop/style/document_dynamic_eval_definition.rb +6 -1
- data/lib/rubocop/cop/style/documentation.rb +53 -6
- data/lib/rubocop/cop/style/documentation_method.rb +8 -12
- data/lib/rubocop/cop/style/double_negation.rb +11 -0
- data/lib/rubocop/cop/style/each_for_simple_loop.rb +1 -1
- data/lib/rubocop/cop/style/each_with_object.rb +2 -0
- data/lib/rubocop/cop/style/empty_block_parameter.rb +1 -1
- data/lib/rubocop/cop/style/empty_case_condition.rb +13 -4
- data/lib/rubocop/cop/style/empty_class_definition.rb +126 -0
- data/lib/rubocop/cop/style/empty_heredoc.rb +4 -0
- data/lib/rubocop/cop/style/empty_lambda_parameter.rb +1 -1
- data/lib/rubocop/cop/style/empty_literal.rb +8 -3
- data/lib/rubocop/cop/style/empty_method.rb +15 -9
- data/lib/rubocop/cop/style/empty_string_inside_interpolation.rb +74 -22
- 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 +100 -21
- data/lib/rubocop/cop/style/env_home.rb +4 -0
- data/lib/rubocop/cop/style/even_odd.rb +11 -1
- data/lib/rubocop/cop/style/exact_regexp_match.rb +52 -8
- data/lib/rubocop/cop/style/explicit_block_argument.rb +50 -10
- data/lib/rubocop/cop/style/fetch_env_var.rb +1 -1
- data/lib/rubocop/cop/style/file_null.rb +6 -4
- data/lib/rubocop/cop/style/file_open.rb +84 -0
- data/lib/rubocop/cop/style/file_write.rb +21 -16
- data/lib/rubocop/cop/style/float_division.rb +28 -14
- data/lib/rubocop/cop/style/for.rb +60 -1
- data/lib/rubocop/cop/style/format_string.rb +44 -9
- data/lib/rubocop/cop/style/format_string_token.rb +50 -7
- data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +2 -1
- data/lib/rubocop/cop/style/global_vars.rb +5 -2
- data/lib/rubocop/cop/style/guard_clause.rb +57 -40
- data/lib/rubocop/cop/style/hash_as_last_array_item.rb +31 -9
- data/lib/rubocop/cop/style/hash_conversion.rb +39 -11
- data/lib/rubocop/cop/style/hash_each_methods.rb +1 -2
- data/lib/rubocop/cop/style/hash_lookup_method.rb +128 -0
- data/lib/rubocop/cop/style/hash_slice.rb +16 -0
- data/lib/rubocop/cop/style/hash_syntax.rb +19 -5
- data/lib/rubocop/cop/style/hash_transform_keys.rb +17 -7
- data/lib/rubocop/cop/style/hash_transform_values.rb +17 -7
- data/lib/rubocop/cop/style/identical_conditional_branches.rb +38 -10
- data/lib/rubocop/cop/style/if_inside_else.rb +36 -8
- data/lib/rubocop/cop/style/if_unless_modifier.rb +80 -76
- data/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +17 -14
- data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +4 -1
- data/lib/rubocop/cop/style/if_with_semicolon.rb +61 -8
- data/lib/rubocop/cop/style/inline_comment.rb +5 -2
- data/lib/rubocop/cop/style/inverse_methods.rb +24 -2
- data/lib/rubocop/cop/style/invertible_unless_condition.rb +25 -5
- data/lib/rubocop/cop/style/ip_addresses.rb +1 -2
- data/lib/rubocop/cop/style/it_block_parameter.rb +94 -4
- data/lib/rubocop/cop/style/keyword_arguments_merging.rb +4 -0
- data/lib/rubocop/cop/style/keyword_parameters_order.rb +10 -4
- data/lib/rubocop/cop/style/lambda.rb +45 -2
- data/lib/rubocop/cop/style/lambda_call.rb +24 -8
- data/lib/rubocop/cop/style/magic_comment_format.rb +4 -4
- data/lib/rubocop/cop/style/map_compact_with_conditional_block.rb +11 -0
- data/lib/rubocop/cop/style/map_into_array.rb +2 -3
- data/lib/rubocop/cop/style/map_join.rb +123 -0
- data/lib/rubocop/cop/style/map_to_hash.rb +1 -2
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +102 -20
- 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 +42 -6
- data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +36 -8
- data/lib/rubocop/cop/style/method_def_parentheses.rb +36 -8
- data/lib/rubocop/cop/style/min_max_comparison.rb +4 -1
- data/lib/rubocop/cop/style/missing_else.rb +7 -1
- data/lib/rubocop/cop/style/missing_respond_to_missing.rb +40 -7
- data/lib/rubocop/cop/style/mixin_grouping.rb +12 -3
- 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_if_modifier.rb +45 -5
- data/lib/rubocop/cop/style/multiline_if_then.rb +10 -4
- data/lib/rubocop/cop/style/multiline_in_pattern_then.rb +7 -0
- data/lib/rubocop/cop/style/multiline_memoization.rb +7 -1
- data/lib/rubocop/cop/style/multiline_method_signature.rb +14 -13
- data/lib/rubocop/cop/style/multiline_ternary_operator.rb +7 -3
- data/lib/rubocop/cop/style/multiline_when_then.rb +7 -0
- data/lib/rubocop/cop/style/multiple_comparison.rb +33 -22
- data/lib/rubocop/cop/style/mutable_constant.rb +158 -14
- data/lib/rubocop/cop/style/negated_if_else_condition.rb +3 -3
- data/lib/rubocop/cop/style/negative_array_index.rb +228 -0
- data/lib/rubocop/cop/style/nested_modifier.rb +36 -12
- data/lib/rubocop/cop/style/nested_ternary_operator.rb +26 -8
- data/lib/rubocop/cop/style/next.rb +24 -10
- data/lib/rubocop/cop/style/nil_comparison.rb +50 -12
- data/lib/rubocop/cop/style/nil_lambda.rb +9 -1
- data/lib/rubocop/cop/style/non_nil_check.rb +21 -11
- data/lib/rubocop/cop/style/not.rb +12 -3
- data/lib/rubocop/cop/style/numeric_literal_prefix.rb +11 -1
- data/lib/rubocop/cop/style/numeric_literals.rb +3 -2
- data/lib/rubocop/cop/style/numeric_predicate.rb +22 -6
- data/lib/rubocop/cop/style/one_class_per_file.rb +115 -0
- data/lib/rubocop/cop/style/one_line_conditional.rb +18 -6
- data/lib/rubocop/cop/style/open_struct_use.rb +1 -1
- data/lib/rubocop/cop/style/operator_method_call.rb +10 -2
- data/lib/rubocop/cop/style/option_hash.rb +1 -1
- data/lib/rubocop/cop/style/optional_arguments.rb +1 -0
- data/lib/rubocop/cop/style/parallel_assignment.rb +26 -7
- data/lib/rubocop/cop/style/parentheses_around_condition.rb +7 -2
- data/lib/rubocop/cop/style/partition_instead_of_double_select.rb +270 -0
- data/lib/rubocop/cop/style/percent_literal_delimiters.rb +18 -3
- data/lib/rubocop/cop/style/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 +3 -2
- data/lib/rubocop/cop/style/raise_args.rb +20 -10
- data/lib/rubocop/cop/style/reduce_to_hash.rb +216 -0
- data/lib/rubocop/cop/style/redundant_argument.rb +2 -0
- data/lib/rubocop/cop/style/redundant_array_constructor.rb +2 -2
- data/lib/rubocop/cop/style/redundant_assignment.rb +12 -2
- data/lib/rubocop/cop/style/redundant_begin.rb +25 -7
- data/lib/rubocop/cop/style/redundant_condition.rb +41 -23
- data/lib/rubocop/cop/style/redundant_constant_base.rb +42 -6
- data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +13 -1
- data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +17 -3
- data/lib/rubocop/cop/style/redundant_each.rb +4 -5
- data/lib/rubocop/cop/style/redundant_exception.rb +21 -3
- data/lib/rubocop/cop/style/redundant_fetch_block.rb +10 -2
- data/lib/rubocop/cop/style/redundant_file_extension_in_require.rb +9 -0
- data/lib/rubocop/cop/style/redundant_filter_chain.rb +1 -1
- data/lib/rubocop/cop/style/redundant_format.rb +43 -7
- data/lib/rubocop/cop/style/redundant_freeze.rb +11 -3
- data/lib/rubocop/cop/style/redundant_heredoc_delimiter_quotes.rb +6 -1
- data/lib/rubocop/cop/style/redundant_interpolation_unfreeze.rb +49 -10
- data/lib/rubocop/cop/style/redundant_line_continuation.rb +82 -115
- data/lib/rubocop/cop/style/redundant_min_max_by.rb +93 -0
- data/lib/rubocop/cop/style/redundant_parentheses.rb +105 -83
- data/lib/rubocop/cop/style/redundant_percent_q.rb +5 -3
- data/lib/rubocop/cop/style/redundant_regexp_argument.rb +13 -2
- data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +6 -5
- data/lib/rubocop/cop/style/redundant_regexp_constructor.rb +27 -7
- data/lib/rubocop/cop/style/redundant_regexp_escape.rb +12 -4
- data/lib/rubocop/cop/style/redundant_return.rb +4 -3
- data/lib/rubocop/cop/style/redundant_self.rb +11 -2
- data/lib/rubocop/cop/style/redundant_self_assignment.rb +1 -2
- data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +27 -4
- data/lib/rubocop/cop/style/redundant_sort.rb +45 -11
- data/lib/rubocop/cop/style/redundant_string_escape.rb +1 -2
- data/lib/rubocop/cop/style/redundant_struct_keyword_init.rb +133 -0
- data/lib/rubocop/cop/style/regexp_literal.rb +106 -28
- data/lib/rubocop/cop/style/require_order.rb +25 -8
- data/lib/rubocop/cop/style/rescue_modifier.rb +15 -14
- data/lib/rubocop/cop/style/return_nil.rb +17 -2
- data/lib/rubocop/cop/style/return_nil_in_predicate_method_definition.rb +11 -1
- data/lib/rubocop/cop/style/reverse_find.rb +51 -0
- data/lib/rubocop/cop/style/safe_navigation.rb +18 -9
- data/lib/rubocop/cop/style/sample.rb +19 -13
- data/lib/rubocop/cop/style/select_by_kind.rb +158 -0
- data/lib/rubocop/cop/style/select_by_range.rb +197 -0
- data/lib/rubocop/cop/style/select_by_regexp.rb +52 -23
- data/lib/rubocop/cop/style/self_assignment.rb +13 -16
- data/lib/rubocop/cop/style/semicolon.rb +39 -13
- data/lib/rubocop/cop/style/send_with_literal_method_name.rb +4 -0
- data/lib/rubocop/cop/style/single_line_block_params.rb +2 -2
- data/lib/rubocop/cop/style/single_line_do_end_block.rb +19 -7
- data/lib/rubocop/cop/style/single_line_methods.rb +24 -5
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +25 -7
- data/lib/rubocop/cop/style/special_global_vars.rb +7 -2
- data/lib/rubocop/cop/style/stabby_lambda_parentheses.rb +31 -5
- data/lib/rubocop/cop/style/static_class.rb +21 -0
- data/lib/rubocop/cop/style/string_concatenation.rb +25 -6
- data/lib/rubocop/cop/style/string_hash_keys.rb +1 -0
- data/lib/rubocop/cop/style/struct_inheritance.rb +36 -1
- data/lib/rubocop/cop/style/super_arguments.rb +6 -4
- data/lib/rubocop/cop/style/symbol_proc.rb +32 -14
- data/lib/rubocop/cop/style/tally_method.rb +181 -0
- data/lib/rubocop/cop/style/ternary_parentheses.rb +34 -1
- data/lib/rubocop/cop/style/time_now.rb +41 -0
- data/lib/rubocop/cop/style/top_level_method_definition.rb +2 -2
- data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +1 -1
- data/lib/rubocop/cop/style/trailing_method_end_statement.rb +1 -0
- data/lib/rubocop/cop/style/trailing_underscore_variable.rb +35 -32
- data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
- data/lib/rubocop/cop/style/unless_logical_operators.rb +3 -3
- data/lib/rubocop/cop/style/while_until_do.rb +7 -0
- data/lib/rubocop/cop/style/while_until_modifier.rb +16 -0
- data/lib/rubocop/cop/style/word_array.rb +1 -0
- data/lib/rubocop/cop/style/yoda_condition.rb +26 -12
- data/lib/rubocop/cop/style/yoda_expression.rb +11 -2
- data/lib/rubocop/cop/style/zero_length_predicate.rb +6 -3
- data/lib/rubocop/cop/style.rb +311 -0
- data/lib/rubocop/cop/team.rb +171 -48
- data/lib/rubocop/cop/util.rb +5 -8
- data/lib/rubocop/cop/variable_force/assignment.rb +1 -1
- data/lib/rubocop/cop/variable_force/branch.rb +30 -6
- data/lib/rubocop/cop/variable_force/variable.rb +33 -9
- data/lib/rubocop/cops_documentation_generator.rb +27 -9
- data/lib/rubocop/directive_comment.rb +116 -7
- data/lib/rubocop/feature_loader.rb +0 -6
- data/lib/rubocop/file_patterns.rb +9 -1
- data/lib/rubocop/formatter/base_formatter.rb +22 -0
- data/lib/rubocop/formatter/clang_style_formatter.rb +5 -2
- data/lib/rubocop/formatter/disabled_config_formatter.rb +39 -10
- data/lib/rubocop/formatter/emacs_style_formatter.rb +3 -1
- data/lib/rubocop/formatter/formatter_set.rb +7 -2
- data/lib/rubocop/formatter/github_actions_formatter.rb +6 -5
- data/lib/rubocop/formatter/html_formatter.rb +2 -4
- data/lib/rubocop/formatter/json_formatter.rb +82 -7
- data/lib/rubocop/formatter/junit_formatter.rb +27 -10
- data/lib/rubocop/formatter/offense_count_formatter.rb +4 -3
- data/lib/rubocop/formatter/pacman_formatter.rb +3 -1
- data/lib/rubocop/formatter/sarif_formatter.rb +186 -0
- data/lib/rubocop/formatter/simple_text_formatter.rb +4 -5
- data/lib/rubocop/formatter/tap_formatter.rb +8 -3
- data/lib/rubocop/formatter/worst_offenders_formatter.rb +5 -4
- data/lib/rubocop/formatter.rb +23 -21
- data/lib/rubocop/lockfile.rb +18 -0
- data/lib/rubocop/lsp/diagnostic.rb +22 -42
- data/lib/rubocop/lsp/disable_comment_edits.rb +135 -0
- data/lib/rubocop/lsp/routes.rb +130 -83
- data/lib/rubocop/lsp/runtime.rb +64 -15
- data/lib/rubocop/lsp/server.rb +6 -2
- data/lib/rubocop/lsp/stdin_runner.rb +35 -2
- data/lib/rubocop/lsp.rb +5 -2
- data/lib/rubocop/magic_comment.rb +47 -0
- data/lib/rubocop/mcp/autocorrection_request.rb +52 -0
- data/lib/rubocop/mcp/explain_tool.rb +68 -0
- data/lib/rubocop/mcp/scope.rb +65 -0
- data/lib/rubocop/mcp/server.rb +307 -0
- data/lib/rubocop/mcp/source_files.rb +35 -0
- data/lib/rubocop/offense_limit.rb +30 -0
- data/lib/rubocop/options.rb +141 -13
- data/lib/rubocop/path_util.rb +16 -5
- data/lib/rubocop/pending_cops_reporter.rb +1 -6
- data/lib/rubocop/plugin/configuration_integrator.rb +13 -3
- data/lib/rubocop/plugin/loader.rb +2 -2
- data/lib/rubocop/project_index_loader.rb +82 -0
- data/lib/rubocop/rake_task.rb +2 -3
- data/lib/rubocop/remote_config.rb +18 -13
- data/lib/rubocop/result_cache.rb +102 -59
- data/lib/rubocop/rspec/cop_helper.rb +8 -0
- data/lib/rubocop/rspec/expect_offense.rb +2 -4
- data/lib/rubocop/rspec/shared_contexts.rb +53 -5
- data/lib/rubocop/rspec/support.rb +2 -1
- data/lib/rubocop/runner.rb +362 -106
- data/lib/rubocop/server/cache.rb +21 -40
- data/lib/rubocop/server/cli.rb +2 -4
- data/lib/rubocop/server/core.rb +8 -0
- data/lib/rubocop/server.rb +14 -0
- data/lib/rubocop/target_finder.rb +18 -8
- data/lib/rubocop/target_ruby.rb +42 -22
- data/lib/rubocop/todo_audit.rb +111 -0
- data/lib/rubocop/unified_diff.rb +257 -0
- data/lib/rubocop/util.rb +69 -0
- data/lib/rubocop/version.rb +23 -7
- data/lib/rubocop.rb +34 -701
- data/lib/ruby_lsp/rubocop/addon.rb +1 -2
- metadata +80 -14
- data/lib/rubocop/cop/style/double_cop_disable_directive.rb +0 -46
|
@@ -15,31 +15,24 @@ module RuboCop
|
|
|
15
15
|
# would yield false positives. For example, `String` implements `length`
|
|
16
16
|
# and `size`, but it doesn't include `Enumerable`.
|
|
17
17
|
#
|
|
18
|
+
# When `count` is used without a block, it measures the collection's
|
|
19
|
+
# size, so the offense is corrected to `empty?` or `!empty?`. The
|
|
20
|
+
# predicate methods `any?`, `none?` and `one?` test element truthiness
|
|
21
|
+
# instead and would return different results for collections with falsey
|
|
22
|
+
# elements (e.g. `[false].count.zero?` is `false`, but `[false].none?`
|
|
23
|
+
# is `true`). For the same reason, `count == 1` and `count > 1` without
|
|
24
|
+
# a block are not flagged.
|
|
25
|
+
#
|
|
18
26
|
# @safety
|
|
19
27
|
# The cop is unsafe because receiver might not include `Enumerable`, or
|
|
20
28
|
# it has nonstandard implementation of `count` or any replacement
|
|
21
29
|
# methods.
|
|
22
30
|
#
|
|
23
|
-
#
|
|
24
|
-
#
|
|
25
|
-
# `
|
|
26
|
-
#
|
|
27
|
-
#
|
|
28
|
-
# ----
|
|
29
|
-
# [nil, false].count.positive?
|
|
30
|
-
# [nil].count == 1
|
|
31
|
-
# # => true
|
|
32
|
-
#
|
|
33
|
-
# [nil, false].any?
|
|
34
|
-
# [nil].one?
|
|
35
|
-
# # => false
|
|
36
|
-
#
|
|
37
|
-
# [nil].count == 0
|
|
38
|
-
# # => false
|
|
39
|
-
#
|
|
40
|
-
# [nil].none?
|
|
41
|
-
# # => true
|
|
42
|
-
# ----
|
|
31
|
+
# Blockless `count` is corrected to `empty?`, which `Enumerable` doesn't
|
|
32
|
+
# define. `Range`, `Enumerator` (including lazy ones), `Struct`, `StringIO`
|
|
33
|
+
# and any class that just includes `Enumerable` respond to `count` but not
|
|
34
|
+
# to `empty?`, so `(1...1).count.zero?` is `true` while `(1...1).empty?`
|
|
35
|
+
# raises `NoMethodError`.
|
|
43
36
|
#
|
|
44
37
|
# Autocorrection is unsafe when replacement methods don't iterate over
|
|
45
38
|
# every element in collection and the given block runs side effects:
|
|
@@ -60,12 +53,14 @@ module RuboCop
|
|
|
60
53
|
# x.count > 0
|
|
61
54
|
# x.count != 0
|
|
62
55
|
#
|
|
56
|
+
# # good
|
|
57
|
+
# !x.empty?
|
|
58
|
+
#
|
|
59
|
+
# # bad
|
|
63
60
|
# x.count(&:foo?).positive?
|
|
64
61
|
# x.count { |item| item.foo? }.positive?
|
|
65
62
|
#
|
|
66
63
|
# # good
|
|
67
|
-
# x.any?
|
|
68
|
-
#
|
|
69
64
|
# x.any?(&:foo?)
|
|
70
65
|
# x.any? { |item| item.foo? }
|
|
71
66
|
#
|
|
@@ -74,24 +69,33 @@ module RuboCop
|
|
|
74
69
|
# x.count == 0
|
|
75
70
|
#
|
|
76
71
|
# # good
|
|
77
|
-
# x.
|
|
72
|
+
# x.empty?
|
|
78
73
|
#
|
|
79
74
|
# # bad
|
|
80
|
-
# x.count
|
|
81
|
-
# x.
|
|
75
|
+
# x.count(&:foo?).zero?
|
|
76
|
+
# x.count(&:foo?) == 0
|
|
77
|
+
#
|
|
78
|
+
# # good
|
|
79
|
+
# x.none?(&:foo?)
|
|
80
|
+
#
|
|
81
|
+
# # bad
|
|
82
|
+
# x.count(&:foo?) == 1
|
|
83
|
+
#
|
|
84
|
+
# # good
|
|
85
|
+
# x.one?(&:foo?)
|
|
82
86
|
#
|
|
83
87
|
# @example AllCops:ActiveSupportExtensionsEnabled: false (default)
|
|
84
88
|
#
|
|
85
89
|
# # good
|
|
86
|
-
# x.count > 1
|
|
90
|
+
# x.count(&:foo?) > 1
|
|
87
91
|
#
|
|
88
92
|
# @example AllCops:ActiveSupportExtensionsEnabled: true
|
|
89
93
|
#
|
|
90
94
|
# # bad
|
|
91
|
-
# x.count > 1
|
|
95
|
+
# x.count(&:foo?) > 1
|
|
92
96
|
#
|
|
93
97
|
# # good
|
|
94
|
-
# x.many?
|
|
98
|
+
# x.many?(&:foo?)
|
|
95
99
|
#
|
|
96
100
|
class CollectionQuerying < Base
|
|
97
101
|
include RangeHelp
|
|
@@ -102,13 +106,21 @@ module RuboCop
|
|
|
102
106
|
RESTRICT_ON_SEND = %i[positive? > != zero? ==].freeze
|
|
103
107
|
|
|
104
108
|
REPLACEMENTS = {
|
|
105
|
-
[:positive?, nil] =>
|
|
106
|
-
[:>, 0] =>
|
|
107
|
-
[:!=, 0] =>
|
|
108
|
-
[:zero?, nil] =>
|
|
109
|
-
[:==, 0] =>
|
|
110
|
-
[:==, 1] =>
|
|
111
|
-
[:>, 1] =>
|
|
109
|
+
[:positive?, nil] => 'any?',
|
|
110
|
+
[:>, 0] => 'any?',
|
|
111
|
+
[:!=, 0] => 'any?',
|
|
112
|
+
[:zero?, nil] => 'none?',
|
|
113
|
+
[:==, 0] => 'none?',
|
|
114
|
+
[:==, 1] => 'one?',
|
|
115
|
+
[:>, 1] => 'many?'
|
|
116
|
+
}.freeze
|
|
117
|
+
|
|
118
|
+
NO_BLOCK_REPLACEMENTS = {
|
|
119
|
+
[:positive?, nil] => '!empty?',
|
|
120
|
+
[:>, 0] => '!empty?',
|
|
121
|
+
[:!=, 0] => '!empty?',
|
|
122
|
+
[:zero?, nil] => 'empty?',
|
|
123
|
+
[:==, 0] => 'empty?'
|
|
112
124
|
}.freeze
|
|
113
125
|
|
|
114
126
|
# @!method count_predicate(node)
|
|
@@ -132,28 +144,49 @@ module RuboCop
|
|
|
132
144
|
def on_send(node)
|
|
133
145
|
return unless (count_node = count_predicate(node))
|
|
134
146
|
|
|
135
|
-
|
|
147
|
+
replacement = replacement_method(node, count_node)
|
|
136
148
|
|
|
137
|
-
return unless replacement_supported?(
|
|
149
|
+
return unless replacement_supported?(node, replacement)
|
|
138
150
|
|
|
139
151
|
offense_range = count_node.loc.selector.join(node.source_range.end)
|
|
140
|
-
add_offense(offense_range,
|
|
141
|
-
|
|
142
|
-
corrector.replace(count_node.loc.selector, replacement_method)
|
|
143
|
-
corrector.remove(removal_range(node))
|
|
152
|
+
add_offense(offense_range, message: format(MSG, prefer: replacement)) do |corrector|
|
|
153
|
+
autocorrect(corrector, node, count_node, replacement)
|
|
144
154
|
end
|
|
145
155
|
end
|
|
146
156
|
|
|
147
157
|
private
|
|
148
158
|
|
|
149
|
-
def replacement_method(node)
|
|
150
|
-
|
|
159
|
+
def replacement_method(node, count_node)
|
|
160
|
+
key = [node.method_name, node.first_argument&.value]
|
|
161
|
+
return REPLACEMENTS.fetch(key) if block_given_to_count?(count_node)
|
|
162
|
+
|
|
163
|
+
NO_BLOCK_REPLACEMENTS[key]
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
def block_given_to_count?(count_node)
|
|
167
|
+
count_node.parent&.any_block_type? || count_node.last_argument&.block_pass_type?
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
def replacement_supported?(node, replacement)
|
|
171
|
+
return false unless replacement
|
|
172
|
+
return false if replacement == 'many?' && !active_support_extensions_enabled?
|
|
173
|
+
|
|
174
|
+
!(replacement.start_with?('!') && receiver_of_call?(node))
|
|
151
175
|
end
|
|
152
176
|
|
|
153
|
-
def
|
|
154
|
-
|
|
177
|
+
def receiver_of_call?(node)
|
|
178
|
+
node.parent&.call_type? && node.parent.receiver == node && node.parent.loc.dot
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
def autocorrect(corrector, node, count_node, replacement)
|
|
182
|
+
if replacement.start_with?('!')
|
|
183
|
+
corrector.insert_before(count_node, '!')
|
|
184
|
+
corrector.replace(count_node.loc.selector, 'empty?')
|
|
185
|
+
else
|
|
186
|
+
corrector.replace(count_node.loc.selector, replacement)
|
|
187
|
+
end
|
|
155
188
|
|
|
156
|
-
|
|
189
|
+
corrector.remove(removal_range(node))
|
|
157
190
|
end
|
|
158
191
|
|
|
159
192
|
def removal_range(node)
|
|
@@ -4,7 +4,9 @@ module RuboCop
|
|
|
4
4
|
module Cop
|
|
5
5
|
module Style
|
|
6
6
|
# Checks for methods invoked via the `::` operator instead
|
|
7
|
-
# of the `.` operator (like `FileUtils::rmdir` instead of
|
|
7
|
+
# of the `.` operator (like `FileUtils::rmdir` instead of
|
|
8
|
+
# `FileUtils.rmdir`). The `::` operator is conventionally used to
|
|
9
|
+
# reference constants, so using it for method calls can be misleading.
|
|
8
10
|
#
|
|
9
11
|
# @example
|
|
10
12
|
# # bad
|
|
@@ -22,10 +24,9 @@ module RuboCop
|
|
|
22
24
|
|
|
23
25
|
MSG = 'Do not use `::` for method calls.'
|
|
24
26
|
|
|
25
|
-
# @!method
|
|
26
|
-
def_node_matcher :
|
|
27
|
-
(
|
|
28
|
-
(const nil? :Java) _)
|
|
27
|
+
# @!method java_root?(node)
|
|
28
|
+
def_node_matcher :java_root?, <<~PATTERN
|
|
29
|
+
(const nil? :Java)
|
|
29
30
|
PATTERN
|
|
30
31
|
|
|
31
32
|
def self.autocorrect_incompatible_with
|
|
@@ -35,11 +36,19 @@ module RuboCop
|
|
|
35
36
|
def on_send(node)
|
|
36
37
|
return unless node.receiver && node.double_colon?
|
|
37
38
|
return if node.camel_case_method?
|
|
38
|
-
# ignore Java interop code like Java::int
|
|
39
|
-
return if
|
|
39
|
+
# ignore Java interop code like `Java::int` or `Java::com::method`
|
|
40
|
+
return if java_interop?(node)
|
|
40
41
|
|
|
41
42
|
add_offense(node.loc.dot) { |corrector| corrector.replace(node.loc.dot, '.') }
|
|
42
43
|
end
|
|
44
|
+
|
|
45
|
+
private
|
|
46
|
+
|
|
47
|
+
def java_interop?(node)
|
|
48
|
+
receiver = node.receiver
|
|
49
|
+
receiver = receiver.receiver while receiver.respond_to?(:receiver) && receiver.receiver
|
|
50
|
+
java_root?(receiver)
|
|
51
|
+
end
|
|
43
52
|
end
|
|
44
53
|
end
|
|
45
54
|
end
|
|
@@ -60,24 +60,26 @@ module RuboCop
|
|
|
60
60
|
# end
|
|
61
61
|
#
|
|
62
62
|
class CombinableLoops < Base
|
|
63
|
+
include RangeHelp
|
|
63
64
|
extend AutoCorrector
|
|
64
65
|
|
|
65
66
|
MSG = 'Combine this loop with the previous loop.'
|
|
66
67
|
|
|
67
|
-
|
|
68
|
+
def self.autocorrect_incompatible_with
|
|
69
|
+
[Layout::BlockEndNewline, Layout::RedundantLineBreak]
|
|
70
|
+
end
|
|
71
|
+
|
|
68
72
|
def on_block(node)
|
|
69
73
|
return unless node.parent&.begin_type?
|
|
70
74
|
return unless collection_looping_method?(node)
|
|
71
|
-
return unless
|
|
72
|
-
return unless node.body && node.left_sibling.body
|
|
75
|
+
return unless combinable_looping_blocks?(node, node.left_sibling)
|
|
73
76
|
|
|
74
77
|
add_offense(node) do |corrector|
|
|
75
|
-
next unless node
|
|
78
|
+
next unless combinable_blocks?(node, node.left_sibling)
|
|
76
79
|
|
|
77
80
|
combine_with_left_sibling(corrector, node)
|
|
78
81
|
end
|
|
79
82
|
end
|
|
80
|
-
# rubocop:enable Metrics/CyclomaticComplexity
|
|
81
83
|
|
|
82
84
|
alias on_numblock on_block
|
|
83
85
|
alias on_itblock on_block
|
|
@@ -85,8 +87,11 @@ module RuboCop
|
|
|
85
87
|
def on_for(node)
|
|
86
88
|
return unless node.parent&.begin_type?
|
|
87
89
|
return unless same_collection_looping_for?(node, node.left_sibling)
|
|
90
|
+
return unless node.body && node.left_sibling.body
|
|
88
91
|
|
|
89
92
|
add_offense(node) do |corrector|
|
|
93
|
+
next unless combinable_fors?(node, node.left_sibling)
|
|
94
|
+
|
|
90
95
|
combine_with_left_sibling(corrector, node)
|
|
91
96
|
end
|
|
92
97
|
end
|
|
@@ -106,25 +111,102 @@ module RuboCop
|
|
|
106
111
|
sibling.send_node.arguments == node.send_node.arguments
|
|
107
112
|
end
|
|
108
113
|
|
|
114
|
+
def combinable_looping_blocks?(node, sibling)
|
|
115
|
+
same_collection_looping_block?(node, sibling) && node.body && sibling.body
|
|
116
|
+
end
|
|
117
|
+
|
|
109
118
|
def same_collection_looping_for?(node, sibling)
|
|
110
119
|
sibling&.for_type? && node.collection == sibling.collection
|
|
111
120
|
end
|
|
112
121
|
|
|
122
|
+
def combinable_blocks?(node, sibling)
|
|
123
|
+
return false unless node.arguments == sibling.arguments
|
|
124
|
+
# Numbered and `it` parameters are implicit, so `arguments` is empty for both.
|
|
125
|
+
return false unless node.argument_list == sibling.argument_list
|
|
126
|
+
return false if directive_after_opening?(node)
|
|
127
|
+
|
|
128
|
+
!node.body.type?(:rescue, :ensure) && !sibling.body.type?(:rescue, :ensure)
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
# Combining loops with different iteration variables would leave the second
|
|
132
|
+
# body referencing an undefined variable, so only autocorrect when they match.
|
|
133
|
+
def combinable_fors?(node, sibling)
|
|
134
|
+
node.variable == sibling.variable && !directive_after_opening?(node)
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
# The opening is removed, so a directive after it would end up on a line of
|
|
138
|
+
# its own, where it covers the rest of the file instead of a single line.
|
|
139
|
+
def directive_after_opening?(node)
|
|
140
|
+
opening_line = loop_opening(node).line
|
|
141
|
+
return false if opening_line == node.body.first_line
|
|
142
|
+
|
|
143
|
+
comment = processed_source.comment_at_line(opening_line)
|
|
144
|
+
comment && DirectiveComment.new(comment).start_with_marker?
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
# The block arguments or `{`/`do` of a block, or the `do` or collection of a `for` loop.
|
|
148
|
+
def loop_opening(node)
|
|
149
|
+
if node.for_type?
|
|
150
|
+
node.loc.begin || node.collection.source_range
|
|
151
|
+
else
|
|
152
|
+
(node.block_type? && node.arguments.source_range) || node.loc.begin
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
|
|
113
156
|
def combine_with_left_sibling(corrector, node)
|
|
114
|
-
corrector.remove(node.left_sibling
|
|
115
|
-
corrector.remove(
|
|
157
|
+
corrector.remove(closing_with_preceding_space(node.left_sibling, node))
|
|
158
|
+
corrector.remove(opening_with_following_space(node))
|
|
116
159
|
|
|
117
160
|
correct_end_of_block(corrector, node)
|
|
118
161
|
end
|
|
119
162
|
|
|
163
|
+
# Comments and heredoc bodies before the closing delimiter are kept. When
|
|
164
|
+
# the next loop starts on the delimiter's line, the line break before the
|
|
165
|
+
# delimiter is kept too, so that a comment doesn't swallow the next loop.
|
|
166
|
+
def closing_with_preceding_space(loop, next_loop)
|
|
167
|
+
separate_lines = !same_line?(loop.loc.end, next_loop)
|
|
168
|
+
|
|
169
|
+
range_with_surrounding_space(
|
|
170
|
+
loop.loc.end, side: :left, newlines: separate_lines, whitespace: separate_lines
|
|
171
|
+
)
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
# Comments between the opening and the body are kept.
|
|
175
|
+
def opening_with_following_space(node)
|
|
176
|
+
opening = node.source_range.begin.join(loop_opening(node))
|
|
177
|
+
|
|
178
|
+
range_with_surrounding_space(opening, side: :right, whitespace: true)
|
|
179
|
+
end
|
|
180
|
+
|
|
120
181
|
def correct_end_of_block(corrector, node)
|
|
121
182
|
return unless node.left_sibling.respond_to?(:braces?)
|
|
122
|
-
return if node
|
|
183
|
+
return if combined_with_right_sibling?(node)
|
|
123
184
|
|
|
124
|
-
end_of_block = node.
|
|
185
|
+
end_of_block = first_combined_block(node).braces? ? '}' : ' end'
|
|
125
186
|
corrector.remove(node.loc.end)
|
|
126
187
|
corrector.insert_before(node.source_range.end, end_of_block)
|
|
127
188
|
end
|
|
189
|
+
|
|
190
|
+
def combined_with_right_sibling?(node)
|
|
191
|
+
sibling = node.right_sibling
|
|
192
|
+
return false unless sibling&.any_block_type?
|
|
193
|
+
# A disabled loop isn't corrected, so it doesn't get merged into this one.
|
|
194
|
+
return false unless enabled_lines?(sibling.source_range)
|
|
195
|
+
|
|
196
|
+
same_collection_looping_block?(sibling, node) && sibling.body &&
|
|
197
|
+
combinable_blocks?(sibling, node)
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
def first_combined_block(node)
|
|
201
|
+
first = node.left_sibling
|
|
202
|
+
|
|
203
|
+
while (previous = first.left_sibling) && enabled_lines?(first.source_range) &&
|
|
204
|
+
combinable_looping_blocks?(first, previous) && combinable_blocks?(first, previous)
|
|
205
|
+
first = previous
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
first
|
|
209
|
+
end
|
|
128
210
|
end
|
|
129
211
|
end
|
|
130
212
|
end
|
|
@@ -90,7 +90,7 @@ module RuboCop
|
|
|
90
90
|
max = if_body.source
|
|
91
91
|
end
|
|
92
92
|
|
|
93
|
-
prefer = "#{
|
|
93
|
+
prefer = "#{parenthesize_if_needed(else_body)}.clamp(#{min}, #{max})"
|
|
94
94
|
|
|
95
95
|
add_offense(node, message: format(MSG, prefer: prefer)) do |corrector|
|
|
96
96
|
autocorrect(corrector, node, prefer)
|
|
@@ -119,6 +119,17 @@ module RuboCop
|
|
|
119
119
|
|
|
120
120
|
(lhs.source == else_body && op == :<) || (rhs.source == else_body && op == :>)
|
|
121
121
|
end
|
|
122
|
+
|
|
123
|
+
# `a + b` must become `(a + b).clamp(low, high)`, not `a + b.clamp(low, high)`
|
|
124
|
+
# (which parses as `a + (b.clamp(low, high))`).
|
|
125
|
+
def parenthesize_if_needed(node)
|
|
126
|
+
if node.type?(:and, :or, :if, :range) || node.assignment? ||
|
|
127
|
+
(node.send_type? && (node.operator_method? || node.unary_operation?))
|
|
128
|
+
"(#{node.source})"
|
|
129
|
+
else
|
|
130
|
+
node.source
|
|
131
|
+
end
|
|
132
|
+
end
|
|
122
133
|
end
|
|
123
134
|
end
|
|
124
135
|
end
|
|
@@ -23,6 +23,7 @@ module RuboCop
|
|
|
23
23
|
# list.push(qux, quux, corge)
|
|
24
24
|
#
|
|
25
25
|
class ConcatArrayLiterals < Base
|
|
26
|
+
include RangeHelp
|
|
26
27
|
extend AutoCorrector
|
|
27
28
|
|
|
28
29
|
MSG = 'Use `%<prefer>s` instead of `%<current>s`.'
|
|
@@ -30,7 +31,15 @@ module RuboCop
|
|
|
30
31
|
'Use `push` with elements as arguments without array brackets instead of `%<current>s`.'
|
|
31
32
|
RESTRICT_ON_SEND = %i[concat].freeze
|
|
32
33
|
|
|
33
|
-
#
|
|
34
|
+
# `Style/MethodCallWithArgsParentheses` removing the parentheses of the `push(...)`
|
|
35
|
+
# this cop writes in the same pass drops the line continuation a multiline call needs.
|
|
36
|
+
# `Style/TrailingCommaInArguments` adds a comma after the array literal this cop
|
|
37
|
+
# replaces with its elements in the same pass.
|
|
38
|
+
def self.autocorrect_incompatible_with
|
|
39
|
+
[Style::MethodCallWithArgsParentheses, Style::TrailingCommaInArguments]
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# rubocop:disable-next Metrics
|
|
34
43
|
def on_send(node)
|
|
35
44
|
return if node.arguments.empty?
|
|
36
45
|
return unless node.arguments.all?(&:array_type?)
|
|
@@ -52,17 +61,18 @@ module RuboCop
|
|
|
52
61
|
|
|
53
62
|
add_offense(offense, message: message) do |corrector|
|
|
54
63
|
if use_percent_literal
|
|
55
|
-
|
|
64
|
+
next unless prefer
|
|
65
|
+
|
|
66
|
+
rebuild_call(corrector, offense, prefer)
|
|
67
|
+
elsif node.arguments.any? { |argument| argument.children.empty? }
|
|
68
|
+
# In-place bracket removal would leave dangling commas (e.g.
|
|
69
|
+
# `concat([], [b])` -> `push(, b)`), so rebuild the call instead.
|
|
70
|
+
rebuild_call(corrector, offense, preferred_method(node))
|
|
56
71
|
else
|
|
57
|
-
corrector
|
|
58
|
-
node.arguments.each do |argument|
|
|
59
|
-
corrector.remove(argument.loc.begin)
|
|
60
|
-
corrector.remove(argument.loc.end)
|
|
61
|
-
end
|
|
72
|
+
remove_brackets(corrector, node)
|
|
62
73
|
end
|
|
63
74
|
end
|
|
64
75
|
end
|
|
65
|
-
# rubocop:enable Metrics
|
|
66
76
|
alias on_csend on_send
|
|
67
77
|
|
|
68
78
|
private
|
|
@@ -73,7 +83,7 @@ module RuboCop
|
|
|
73
83
|
|
|
74
84
|
def preferred_method(node)
|
|
75
85
|
new_arguments =
|
|
76
|
-
node.arguments.
|
|
86
|
+
node.arguments.flat_map do |arg|
|
|
77
87
|
if arg.percent_literal?
|
|
78
88
|
arg.children.map { |child| child.value.inspect }
|
|
79
89
|
else
|
|
@@ -89,6 +99,52 @@ module RuboCop
|
|
|
89
99
|
arg.children.all? { |child| child.type?(:str, :sym) }
|
|
90
100
|
end
|
|
91
101
|
end
|
|
102
|
+
|
|
103
|
+
def rebuild_call(corrector, offense, replacement)
|
|
104
|
+
# The comments inside the call would be lost.
|
|
105
|
+
return if comment_in?(offense)
|
|
106
|
+
|
|
107
|
+
corrector.replace(offense, replacement)
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def comment_in?(range)
|
|
111
|
+
processed_source.each_comment_in_lines(range.line..range.last_line).any? do |comment|
|
|
112
|
+
range.contains?(comment.source_range)
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def remove_brackets(corrector, node)
|
|
117
|
+
closing_ranges = node.arguments.map { |argument| closing_bracket_range(node, argument) }
|
|
118
|
+
# A comment or a heredoc body there can't be moved out of the way.
|
|
119
|
+
return unless closing_ranges.all? { |range| range.source.match?(/\A[\s,]*\]\z/) }
|
|
120
|
+
|
|
121
|
+
replace_selector(corrector, node)
|
|
122
|
+
|
|
123
|
+
node.arguments.zip(closing_ranges) do |argument, closing_range|
|
|
124
|
+
corrector.remove(argument.loc.begin)
|
|
125
|
+
corrector.remove(closing_range)
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
# Whatever sits between the last element and the `]` of an array that isn't the
|
|
130
|
+
# last argument would end up before the following comma (a newline before it is a
|
|
131
|
+
# syntax error), so it's removed along with the `]`.
|
|
132
|
+
def closing_bracket_range(node, argument)
|
|
133
|
+
return argument.loc.end if argument.equal?(node.last_argument)
|
|
134
|
+
|
|
135
|
+
range_between(argument.children.last.source_range.end_pos, argument.loc.end.end_pos)
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def replace_selector(corrector, node)
|
|
139
|
+
if node.parenthesized? || node.single_line?
|
|
140
|
+
corrector.replace(node.loc.selector, 'push')
|
|
141
|
+
else
|
|
142
|
+
range = node.loc.selector.join(node.first_argument.source_range.begin)
|
|
143
|
+
|
|
144
|
+
corrector.replace(range, 'push(')
|
|
145
|
+
corrector.insert_after(node.last_argument.loc.end, ')')
|
|
146
|
+
end
|
|
147
|
+
end
|
|
92
148
|
end
|
|
93
149
|
end
|
|
94
150
|
end
|
|
@@ -99,10 +99,6 @@ module RuboCop
|
|
|
99
99
|
end
|
|
100
100
|
end
|
|
101
101
|
|
|
102
|
-
def setter_method?(method_name)
|
|
103
|
-
method_name.to_s.end_with?(EQUAL) && !%i[!= == === >= <=].include?(method_name)
|
|
104
|
-
end
|
|
105
|
-
|
|
106
102
|
def assignment_rhs_exist?(node)
|
|
107
103
|
parent = node.parent
|
|
108
104
|
return true unless parent
|
|
@@ -207,15 +203,14 @@ module RuboCop
|
|
|
207
203
|
class ConditionalAssignment < Base
|
|
208
204
|
include ConditionalAssignmentHelper
|
|
209
205
|
include ConfigurableEnforcedStyle
|
|
206
|
+
include ReparsedEquivalence
|
|
210
207
|
extend AutoCorrector
|
|
211
208
|
|
|
212
209
|
MSG = 'Use the return of the conditional for variable assignment and comparison.'
|
|
213
210
|
ASSIGN_TO_CONDITION_MSG = 'Assign variables inside of conditionals.'
|
|
214
211
|
VARIABLE_ASSIGNMENT_TYPES = %i[casgn cvasgn gvasgn ivasgn lvasgn].freeze
|
|
215
212
|
ASSIGNMENT_TYPES = VARIABLE_ASSIGNMENT_TYPES + %i[and_asgn or_asgn op_asgn masgn].freeze
|
|
216
|
-
LINE_LENGTH = 'Layout/LineLength'
|
|
217
213
|
ENABLED = 'Enabled'
|
|
218
|
-
MAX = 'Max'
|
|
219
214
|
SINGLE_LINE_CONDITIONS_ONLY = 'SingleLineConditionsOnly'
|
|
220
215
|
|
|
221
216
|
# The shovel operator `<<` does not have its own type. It is a `send`
|
|
@@ -228,6 +223,10 @@ module RuboCop
|
|
|
228
223
|
}
|
|
229
224
|
PATTERN
|
|
230
225
|
|
|
226
|
+
def self.autocorrect_incompatible_with
|
|
227
|
+
[Style::MethodCallWithArgsParentheses]
|
|
228
|
+
end
|
|
229
|
+
|
|
231
230
|
ASSIGNMENT_TYPES.each do |type|
|
|
232
231
|
define_method :"on_#{type}" do |node|
|
|
233
232
|
return if part_of_ignored_node?(node)
|
|
@@ -289,8 +288,12 @@ module RuboCop
|
|
|
289
288
|
|
|
290
289
|
_condition, *branches, else_branch = *assignment
|
|
291
290
|
|
|
292
|
-
|
|
291
|
+
# Use the node accessor rather than the raw destructured branch: for
|
|
292
|
+
# `x = unless cond; body; end` (no `else`) the parser puts `body` in the
|
|
293
|
+
# else slot, but `else_branch` correctly reports there is no `else` clause.
|
|
294
|
+
return unless assignment.else_branch
|
|
293
295
|
return if allowed_single_line?([*branches, else_branch])
|
|
296
|
+
return unless safe_to_correct?(node)
|
|
294
297
|
|
|
295
298
|
add_offense(node, message: ASSIGN_TO_CONDITION_MSG) do |corrector|
|
|
296
299
|
autocorrect(corrector, node)
|
|
@@ -370,6 +373,7 @@ module RuboCop
|
|
|
370
373
|
return unless allowed_statements?(branches)
|
|
371
374
|
return if allowed_single_line?(branches)
|
|
372
375
|
return if correction_exceeds_line_limit?(node, branches)
|
|
376
|
+
return unless safe_to_correct?(node)
|
|
373
377
|
|
|
374
378
|
add_offense(node) { |corrector| autocorrect(corrector, node) }
|
|
375
379
|
end
|
|
@@ -382,6 +386,25 @@ module RuboCop
|
|
|
382
386
|
end
|
|
383
387
|
end
|
|
384
388
|
|
|
389
|
+
# The correction rewrites the conditional structurally, so full AST
|
|
390
|
+
# equivalence cannot be asserted, but the result must at least reparse
|
|
391
|
+
# to valid Ruby. Applying the correction to a throwaway buffer here
|
|
392
|
+
# also exercises the branch-shape handling before an offense is even
|
|
393
|
+
# reported, so unusual branches that the corrector cannot handle are
|
|
394
|
+
# left alone instead of crashing or emitting invalid code - the bug
|
|
395
|
+
# class behind most of this cop's history.
|
|
396
|
+
def safe_to_correct?(node)
|
|
397
|
+
correction_parses?(node)
|
|
398
|
+
rescue StandardError
|
|
399
|
+
false
|
|
400
|
+
end
|
|
401
|
+
|
|
402
|
+
# `ReparsedEquivalence#correction_parses?` contract: apply the exact
|
|
403
|
+
# correction this cop would perform.
|
|
404
|
+
def apply_reparse_correction(corrector, node)
|
|
405
|
+
autocorrect(corrector, node)
|
|
406
|
+
end
|
|
407
|
+
|
|
385
408
|
def allowed_statements?(branches)
|
|
386
409
|
return false unless branches.all?
|
|
387
410
|
|
|
@@ -399,7 +422,7 @@ module RuboCop
|
|
|
399
422
|
# of the longest line + the length of the corrected assignment is
|
|
400
423
|
# greater than the max configured line length
|
|
401
424
|
def correction_exceeds_line_limit?(node, branches)
|
|
402
|
-
return false unless
|
|
425
|
+
return false unless config.cop_enabled?('Layout/LineLength')
|
|
403
426
|
|
|
404
427
|
assignment = lhs(tail(branches[0]))
|
|
405
428
|
|
|
@@ -417,14 +440,6 @@ module RuboCop
|
|
|
417
440
|
assignment + longest_line
|
|
418
441
|
end
|
|
419
442
|
|
|
420
|
-
def line_length_cop_enabled?
|
|
421
|
-
config.for_cop(LINE_LENGTH)[ENABLED]
|
|
422
|
-
end
|
|
423
|
-
|
|
424
|
-
def max_line_length
|
|
425
|
-
config.for_cop(LINE_LENGTH)[MAX]
|
|
426
|
-
end
|
|
427
|
-
|
|
428
443
|
def single_line_conditions_only?
|
|
429
444
|
cop_config[SINGLE_LINE_CONDITIONS_ONLY]
|
|
430
445
|
end
|
|
@@ -437,7 +452,7 @@ module RuboCop
|
|
|
437
452
|
# Helper module to provide common methods to ConditionalAssignment
|
|
438
453
|
# correctors
|
|
439
454
|
module ConditionalCorrectorHelper
|
|
440
|
-
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity
|
|
455
|
+
# rubocop:disable-next Metrics/AbcSize, Metrics/CyclomaticComplexity
|
|
441
456
|
def remove_whitespace_in_branches(corrector, branch, condition, column)
|
|
442
457
|
branch.each_node do |child|
|
|
443
458
|
next if child.source_range.nil?
|
|
@@ -457,7 +472,6 @@ module RuboCop
|
|
|
457
472
|
|
|
458
473
|
corrector.remove_preceding(condition.loc.end, condition.loc.end.column - column)
|
|
459
474
|
end
|
|
460
|
-
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity
|
|
461
475
|
|
|
462
476
|
def same_line?(node1, node2)
|
|
463
477
|
RuboCop::Cop::Util.same_line?(node1, node2)
|
|
@@ -671,6 +685,8 @@ module RuboCop
|
|
|
671
685
|
remove_whitespace_in_branches(corrector, branch, condition, column)
|
|
672
686
|
|
|
673
687
|
parent_keyword = branch.parent.loc.keyword
|
|
688
|
+
return if same_line?(parent_keyword, condition)
|
|
689
|
+
|
|
674
690
|
corrector.remove_preceding(parent_keyword, parent_keyword.column - column)
|
|
675
691
|
end
|
|
676
692
|
end
|