rubocop 1.65.1 → 1.75.6
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 +72 -72
- data/config/default.yml +299 -55
- data/config/internal_affairs.yml +31 -0
- data/config/obsoletion.yml +3 -1
- data/exe/rubocop +4 -3
- data/lib/rubocop/cached_data.rb +12 -4
- data/lib/rubocop/cli/command/auto_generate_config.rb +6 -7
- data/lib/rubocop/cli/command/execute_runner.rb +4 -4
- data/lib/rubocop/cli/command/lsp.rb +2 -2
- data/lib/rubocop/cli/command/show_cops.rb +24 -2
- data/lib/rubocop/cli/command/suggest_extensions.rb +7 -1
- data/lib/rubocop/cli/command/version.rb +2 -2
- data/lib/rubocop/cli.rb +1 -1
- data/lib/rubocop/comment_config.rb +3 -3
- data/lib/rubocop/config.rb +57 -11
- data/lib/rubocop/config_loader.rb +66 -17
- data/lib/rubocop/config_loader_resolver.rb +39 -14
- data/lib/rubocop/config_obsoletion/extracted_cop.rb +4 -3
- data/lib/rubocop/config_obsoletion/renamed_cop.rb +18 -3
- data/lib/rubocop/config_obsoletion.rb +46 -2
- data/lib/rubocop/config_validator.rb +27 -15
- data/lib/rubocop/cop/autocorrect_logic.rb +36 -19
- data/lib/rubocop/cop/base.rb +17 -3
- data/lib/rubocop/cop/bundler/duplicated_gem.rb +2 -2
- data/lib/rubocop/cop/bundler/gem_comment.rb +1 -1
- data/lib/rubocop/cop/bundler/gem_filename.rb +0 -1
- data/lib/rubocop/cop/bundler/gem_version.rb +1 -0
- data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +0 -1
- data/lib/rubocop/cop/cop.rb +8 -0
- data/lib/rubocop/cop/correctors/alignment_corrector.rb +1 -12
- data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +1 -1
- data/lib/rubocop/cop/correctors/line_break_corrector.rb +2 -0
- data/lib/rubocop/cop/correctors/parentheses_corrector.rb +1 -1
- data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +10 -0
- data/lib/rubocop/cop/documentation.rb +18 -1
- data/lib/rubocop/cop/gemspec/deprecated_attribute_assignment.rb +1 -2
- data/lib/rubocop/cop/gemspec/required_ruby_version.rb +0 -2
- data/lib/rubocop/cop/generator.rb +6 -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 +8 -4
- data/lib/rubocop/cop/internal_affairs/location_exists.rb +116 -0
- data/lib/rubocop/cop/internal_affairs/location_expression.rb +2 -1
- data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +3 -4
- data/lib/rubocop/cop/internal_affairs/node_first_or_last_argument.rb +3 -2
- data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +2 -2
- 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 +131 -0
- data/lib/rubocop/cop/internal_affairs/node_pattern_groups.rb +230 -0
- data/lib/rubocop/cop/internal_affairs/node_type_group.rb +91 -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_message_argument.rb +6 -21
- 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 +0 -5
- data/lib/rubocop/cop/internal_affairs.rb +7 -0
- data/lib/rubocop/cop/layout/access_modifier_indentation.rb +6 -2
- data/lib/rubocop/cop/layout/argument_alignment.rb +2 -9
- data/lib/rubocop/cop/layout/array_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/begin_end_alignment.rb +0 -1
- data/lib/rubocop/cop/layout/block_alignment.rb +32 -13
- data/lib/rubocop/cop/layout/block_end_newline.rb +1 -0
- data/lib/rubocop/cop/layout/class_structure.rb +9 -9
- data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +4 -4
- data/lib/rubocop/cop/layout/def_end_alignment.rb +2 -2
- data/lib/rubocop/cop/layout/dot_position.rb +1 -1
- data/lib/rubocop/cop/layout/else_alignment.rb +2 -2
- data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +4 -4
- data/lib/rubocop/cop/layout/empty_line_between_defs.rb +9 -12
- data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +30 -4
- data/lib/rubocop/cop/layout/empty_lines_around_begin_body.rb +5 -6
- data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +1 -0
- 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/end_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/extra_spacing.rb +1 -1
- data/lib/rubocop/cop/layout/first_argument_indentation.rb +3 -8
- data/lib/rubocop/cop/layout/first_array_element_indentation.rb +2 -10
- data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +2 -7
- data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +1 -1
- data/lib/rubocop/cop/layout/first_method_argument_line_break.rb +8 -0
- data/lib/rubocop/cop/layout/first_parameter_indentation.rb +2 -2
- data/lib/rubocop/cop/layout/hash_alignment.rb +8 -6
- data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +2 -1
- data/lib/rubocop/cop/layout/indentation_width.rb +12 -12
- data/lib/rubocop/cop/layout/leading_comment_space.rb +83 -1
- data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +11 -2
- data/lib/rubocop/cop/layout/line_continuation_spacing.rb +7 -1
- data/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb +2 -2
- data/lib/rubocop/cop/layout/line_length.rb +135 -16
- data/lib/rubocop/cop/layout/multiline_block_layout.rb +1 -0
- 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 +2 -1
- data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +4 -4
- 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 +3 -4
- data/lib/rubocop/cop/layout/parameter_alignment.rb +3 -4
- data/lib/rubocop/cop/layout/redundant_line_break.rb +19 -46
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +6 -7
- data/lib/rubocop/cop/layout/single_line_block_chain.rb +1 -1
- data/lib/rubocop/cop/layout/space_after_colon.rb +2 -2
- data/lib/rubocop/cop/layout/space_after_comma.rb +1 -1
- data/lib/rubocop/cop/layout/space_after_method_name.rb +1 -1
- data/lib/rubocop/cop/layout/space_after_semicolon.rb +11 -1
- data/lib/rubocop/cop/layout/space_around_keyword.rb +2 -1
- data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +1 -1
- data/lib/rubocop/cop/layout/space_around_operators.rb +23 -21
- data/lib/rubocop/cop/layout/space_before_block_braces.rb +1 -0
- data/lib/rubocop/cop/layout/space_before_brackets.rb +5 -5
- 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_inside_array_literal_brackets.rb +11 -1
- data/lib/rubocop/cop/layout/space_inside_block_braces.rb +5 -0
- data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +7 -0
- data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +0 -1
- data/lib/rubocop/cop/layout/trailing_whitespace.rb +5 -3
- data/lib/rubocop/cop/lint/ambiguous_block_association.rb +1 -1
- data/lib/rubocop/cop/lint/ambiguous_range.rb +4 -1
- data/lib/rubocop/cop/lint/array_literal_in_regexp.rb +118 -0
- data/lib/rubocop/cop/lint/assignment_in_condition.rb +1 -3
- data/lib/rubocop/cop/lint/big_decimal_new.rb +4 -7
- data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +10 -12
- data/lib/rubocop/cop/lint/boolean_symbol.rb +2 -2
- data/lib/rubocop/cop/lint/circular_argument_reference.rb +4 -1
- data/lib/rubocop/cop/lint/constant_definition_in_block.rb +3 -3
- data/lib/rubocop/cop/lint/constant_reassignment.rb +148 -0
- data/lib/rubocop/cop/lint/cop_directive_syntax.rb +84 -0
- data/lib/rubocop/cop/lint/debugger.rb +3 -3
- data/lib/rubocop/cop/lint/deprecated_class_methods.rb +1 -1
- data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +3 -2
- data/lib/rubocop/cop/lint/duplicate_branch.rb +39 -4
- data/lib/rubocop/cop/lint/duplicate_match_pattern.rb +1 -1
- data/lib/rubocop/cop/lint/duplicate_methods.rb +46 -19
- data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +1 -1
- data/lib/rubocop/cop/lint/duplicate_set_element.rb +87 -0
- data/lib/rubocop/cop/lint/empty_conditional_body.rb +29 -58
- data/lib/rubocop/cop/lint/empty_ensure.rb +1 -1
- 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/ensure_return.rb +1 -4
- data/lib/rubocop/cop/lint/erb_new_arguments.rb +1 -7
- data/lib/rubocop/cop/lint/float_comparison.rb +21 -17
- data/lib/rubocop/cop/lint/float_out_of_range.rb +2 -4
- data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +2 -2
- data/lib/rubocop/cop/lint/hash_new_with_keyword_arguments_as_default.rb +55 -0
- data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +13 -5
- data/lib/rubocop/cop/lint/interpolation_check.rb +9 -0
- data/lib/rubocop/cop/lint/it_without_arguments_in_block.rb +8 -14
- data/lib/rubocop/cop/lint/literal_as_condition.rb +118 -9
- data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +1 -1
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +49 -8
- data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +1 -1
- data/lib/rubocop/cop/lint/missing_super.rb +2 -2
- data/lib/rubocop/cop/lint/mixed_case_range.rb +5 -8
- data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +1 -1
- data/lib/rubocop/cop/lint/nested_method_definition.rb +10 -6
- data/lib/rubocop/cop/lint/next_without_accumulator.rb +1 -1
- data/lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +2 -2
- data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +12 -3
- data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +3 -3
- data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +3 -3
- data/lib/rubocop/cop/lint/number_conversion.rb +0 -1
- data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +1 -2
- data/lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +93 -0
- data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +2 -3
- data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +3 -2
- data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +6 -11
- data/lib/rubocop/cop/lint/raise_exception.rb +29 -10
- data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +1 -1
- data/lib/rubocop/cop/lint/redundant_regexp_quantifiers.rb +1 -1
- data/lib/rubocop/cop/lint/redundant_require_statement.rb +0 -21
- data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +13 -8
- data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +8 -7
- data/lib/rubocop/cop/lint/redundant_string_coercion.rb +2 -2
- data/lib/rubocop/cop/lint/redundant_type_conversion.rb +261 -0
- data/lib/rubocop/cop/lint/redundant_with_index.rb +3 -0
- data/lib/rubocop/cop/lint/redundant_with_object.rb +3 -0
- data/lib/rubocop/cop/lint/refinement_import_methods.rb +1 -1
- data/lib/rubocop/cop/lint/regexp_as_condition.rb +0 -1
- data/lib/rubocop/cop/lint/rescue_exception.rb +1 -1
- data/lib/rubocop/cop/lint/rescue_type.rb +3 -7
- data/lib/rubocop/cop/lint/return_in_void_context.rb +9 -11
- data/lib/rubocop/cop/lint/safe_navigation_chain.rb +17 -1
- data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +109 -41
- data/lib/rubocop/cop/lint/self_assignment.rb +8 -10
- data/lib/rubocop/cop/lint/shadowed_exception.rb +1 -1
- data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +8 -1
- data/lib/rubocop/cop/lint/shared_mutable_default.rb +76 -0
- data/lib/rubocop/cop/lint/suppressed_exception.rb +1 -1
- data/lib/rubocop/cop/lint/suppressed_exception_in_number_conversion.rb +111 -0
- data/lib/rubocop/cop/lint/symbol_conversion.rb +2 -2
- data/lib/rubocop/cop/lint/syntax.rb +4 -1
- data/lib/rubocop/cop/lint/to_enum_arguments.rb +1 -1
- data/lib/rubocop/cop/lint/top_level_return_with_argument.rb +1 -1
- data/lib/rubocop/cop/lint/unescaped_bracket_in_regexp.rb +88 -0
- data/lib/rubocop/cop/lint/unexpected_block_arity.rb +3 -1
- data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +1 -1
- data/lib/rubocop/cop/lint/unreachable_code.rb +52 -2
- data/lib/rubocop/cop/lint/unreachable_loop.rb +6 -6
- data/lib/rubocop/cop/lint/unused_method_argument.rb +18 -2
- data/lib/rubocop/cop/lint/uri_regexp.rb +25 -7
- data/lib/rubocop/cop/lint/useless_access_modifier.rb +5 -4
- data/lib/rubocop/cop/lint/useless_assignment.rb +20 -11
- data/lib/rubocop/cop/lint/useless_constant_scoping.rb +71 -0
- data/lib/rubocop/cop/lint/useless_defined.rb +55 -0
- data/lib/rubocop/cop/lint/useless_else_without_rescue.rb +4 -0
- data/lib/rubocop/cop/lint/useless_method_definition.rb +1 -1
- data/lib/rubocop/cop/lint/useless_numeric_operation.rb +78 -0
- data/lib/rubocop/cop/lint/useless_rescue.rb +2 -2
- data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +2 -2
- data/lib/rubocop/cop/lint/useless_setter_call.rb +14 -25
- data/lib/rubocop/cop/lint/void.rb +40 -14
- data/lib/rubocop/cop/message_annotator.rb +7 -3
- data/lib/rubocop/cop/metrics/block_length.rb +7 -5
- data/lib/rubocop/cop/metrics/block_nesting.rb +1 -1
- data/lib/rubocop/cop/metrics/class_length.rb +15 -14
- data/lib/rubocop/cop/metrics/collection_literal_length.rb +7 -0
- data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +5 -2
- data/lib/rubocop/cop/metrics/method_length.rb +15 -6
- data/lib/rubocop/cop/metrics/module_length.rb +7 -6
- data/lib/rubocop/cop/metrics/perceived_complexity.rb +1 -1
- data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +1 -1
- data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +3 -4
- data/lib/rubocop/cop/metrics/utils/repeated_attribute_discount.rb +7 -7
- data/lib/rubocop/cop/mixin/alignment.rb +2 -2
- data/lib/rubocop/cop/mixin/allowed_pattern.rb +4 -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 +22 -12
- data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +49 -0
- data/lib/rubocop/cop/mixin/comments_help.rb +8 -3
- 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/endless_method_rewriter.rb +24 -0
- data/lib/rubocop/cop/mixin/forbidden_identifiers.rb +20 -0
- data/lib/rubocop/cop/mixin/forbidden_pattern.rb +16 -0
- data/lib/rubocop/cop/mixin/frozen_string_literal.rb +22 -11
- data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +15 -14
- data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +22 -22
- data/lib/rubocop/cop/mixin/hash_subset.rb +203 -0
- data/lib/rubocop/cop/mixin/hash_transform_method.rb +74 -74
- data/lib/rubocop/cop/mixin/line_length_help.rb +12 -6
- data/lib/rubocop/cop/mixin/method_complexity.rb +2 -1
- data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +7 -9
- 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 +68 -30
- data/lib/rubocop/cop/mixin/range_help.rb +15 -4
- data/lib/rubocop/cop/mixin/space_before_punctuation.rb +1 -1
- data/lib/rubocop/cop/mixin/statement_modifier.rb +11 -5
- data/lib/rubocop/cop/mixin/string_help.rb +2 -2
- 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 +21 -5
- data/lib/rubocop/cop/naming/accessor_method_name.rb +11 -6
- data/lib/rubocop/cop/naming/block_forwarding.rb +20 -16
- data/lib/rubocop/cop/naming/constant_name.rb +6 -7
- data/lib/rubocop/cop/naming/file_name.rb +0 -2
- data/lib/rubocop/cop/naming/inclusive_language.rb +12 -3
- data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +12 -13
- data/lib/rubocop/cop/naming/method_name.rb +64 -8
- data/lib/rubocop/cop/naming/predicate_name.rb +46 -2
- data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +6 -14
- data/lib/rubocop/cop/naming/variable_name.rb +50 -6
- data/lib/rubocop/cop/naming/variable_number.rb +2 -3
- data/lib/rubocop/cop/offense.rb +4 -5
- data/lib/rubocop/cop/registry.rb +9 -6
- data/lib/rubocop/cop/security/compound_hash.rb +2 -0
- data/lib/rubocop/cop/security/yaml_load.rb +3 -2
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +96 -28
- data/lib/rubocop/cop/style/accessor_grouping.rb +29 -7
- data/lib/rubocop/cop/style/alias.rb +1 -1
- data/lib/rubocop/cop/style/ambiguous_endless_method_definition.rb +79 -0
- data/lib/rubocop/cop/style/and_or.rb +1 -1
- data/lib/rubocop/cop/style/arguments_forwarding.rb +94 -30
- data/lib/rubocop/cop/style/array_first_last.rb +18 -2
- data/lib/rubocop/cop/style/array_intersect.rb +42 -30
- data/lib/rubocop/cop/style/bitwise_predicate.rb +100 -0
- data/lib/rubocop/cop/style/block_delimiters.rb +51 -20
- data/lib/rubocop/cop/style/case_like_if.rb +8 -11
- data/lib/rubocop/cop/style/class_and_module_children.rb +52 -11
- data/lib/rubocop/cop/style/class_equality_comparison.rb +1 -1
- data/lib/rubocop/cop/style/collection_compact.rb +10 -10
- data/lib/rubocop/cop/style/collection_methods.rb +2 -1
- data/lib/rubocop/cop/style/combinable_defined.rb +115 -0
- data/lib/rubocop/cop/style/combinable_loops.rb +10 -2
- data/lib/rubocop/cop/style/commented_keyword.rb +25 -2
- data/lib/rubocop/cop/style/comparable_between.rb +78 -0
- data/lib/rubocop/cop/style/concat_array_literals.rb +1 -1
- data/lib/rubocop/cop/style/conditional_assignment.rb +40 -28
- data/lib/rubocop/cop/style/constant_visibility.rb +3 -12
- data/lib/rubocop/cop/style/data_inheritance.rb +8 -1
- data/lib/rubocop/cop/style/dig_chain.rb +89 -0
- data/lib/rubocop/cop/style/documentation.rb +1 -1
- data/lib/rubocop/cop/style/double_negation.rb +4 -4
- data/lib/rubocop/cop/style/each_for_simple_loop.rb +4 -7
- data/lib/rubocop/cop/style/each_with_object.rb +2 -3
- data/lib/rubocop/cop/style/empty_else.rb +10 -7
- data/lib/rubocop/cop/style/empty_heredoc.rb +1 -14
- data/lib/rubocop/cop/style/empty_literal.rb +35 -22
- data/lib/rubocop/cop/style/empty_method.rb +1 -1
- data/lib/rubocop/cop/style/endless_method.rb +150 -18
- data/lib/rubocop/cop/style/eval_with_location.rb +5 -5
- data/lib/rubocop/cop/style/exact_regexp_match.rb +2 -3
- data/lib/rubocop/cop/style/expand_path_arguments.rb +2 -7
- data/lib/rubocop/cop/style/explicit_block_argument.rb +16 -3
- data/lib/rubocop/cop/style/exponential_notation.rb +3 -3
- data/lib/rubocop/cop/style/fetch_env_var.rb +2 -1
- data/lib/rubocop/cop/style/file_null.rb +89 -0
- data/lib/rubocop/cop/style/file_touch.rb +75 -0
- data/lib/rubocop/cop/style/float_division.rb +8 -4
- data/lib/rubocop/cop/style/for.rb +1 -1
- data/lib/rubocop/cop/style/format_string_token.rb +38 -11
- data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +3 -2
- data/lib/rubocop/cop/style/global_std_stream.rb +3 -0
- data/lib/rubocop/cop/style/global_vars.rb +1 -3
- data/lib/rubocop/cop/style/guard_clause.rb +20 -4
- data/lib/rubocop/cop/style/hash_conversion.rb +1 -2
- data/lib/rubocop/cop/style/hash_each_methods.rb +12 -8
- data/lib/rubocop/cop/style/hash_except.rb +35 -147
- data/lib/rubocop/cop/style/hash_fetch_chain.rb +104 -0
- data/lib/rubocop/cop/style/hash_slice.rb +80 -0
- data/lib/rubocop/cop/style/hash_syntax.rb +11 -5
- data/lib/rubocop/cop/style/hash_transform_keys.rb +2 -2
- data/lib/rubocop/cop/style/hash_transform_values.rb +2 -2
- data/lib/rubocop/cop/style/identical_conditional_branches.rb +26 -7
- data/lib/rubocop/cop/style/if_inside_else.rb +11 -15
- data/lib/rubocop/cop/style/if_unless_modifier.rb +25 -5
- data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +3 -4
- data/lib/rubocop/cop/style/if_with_semicolon.rb +60 -6
- 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/inverse_methods.rb +15 -12
- data/lib/rubocop/cop/style/invertible_unless_condition.rb +2 -2
- data/lib/rubocop/cop/style/ip_addresses.rb +2 -2
- data/lib/rubocop/cop/style/it_assignment.rb +36 -0
- data/lib/rubocop/cop/style/it_block_parameter.rb +100 -0
- data/lib/rubocop/cop/style/keyword_arguments_merging.rb +67 -0
- data/lib/rubocop/cop/style/keyword_parameters_order.rb +14 -8
- data/lib/rubocop/cop/style/lambda.rb +2 -1
- data/lib/rubocop/cop/style/lambda_call.rb +10 -4
- data/lib/rubocop/cop/style/line_end_concatenation.rb +10 -4
- data/lib/rubocop/cop/style/magic_comment_format.rb +1 -1
- data/lib/rubocop/cop/style/map_into_array.rb +75 -14
- data/lib/rubocop/cop/style/map_to_hash.rb +1 -1
- data/lib/rubocop/cop/style/map_to_set.rb +3 -2
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +38 -23
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +2 -0
- data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +10 -13
- data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +3 -4
- data/lib/rubocop/cop/style/method_def_parentheses.rb +1 -1
- data/lib/rubocop/cop/style/missing_else.rb +2 -0
- data/lib/rubocop/cop/style/missing_respond_to_missing.rb +33 -3
- 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_memoization.rb +2 -2
- data/lib/rubocop/cop/style/multiline_method_signature.rb +1 -9
- data/lib/rubocop/cop/style/multiple_comparison.rb +53 -60
- data/lib/rubocop/cop/style/mutable_constant.rb +7 -8
- data/lib/rubocop/cop/style/negated_if_else_condition.rb +7 -5
- 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 +5 -4
- data/lib/rubocop/cop/style/next.rb +44 -0
- data/lib/rubocop/cop/style/not.rb +1 -1
- data/lib/rubocop/cop/style/numeric_predicate.rb +2 -2
- data/lib/rubocop/cop/style/object_then.rb +15 -15
- data/lib/rubocop/cop/style/one_line_conditional.rb +30 -5
- data/lib/rubocop/cop/style/open_struct_use.rb +5 -5
- data/lib/rubocop/cop/style/operator_method_call.rb +25 -7
- data/lib/rubocop/cop/style/or_assignment.rb +3 -6
- data/lib/rubocop/cop/style/parallel_assignment.rb +14 -22
- data/lib/rubocop/cop/style/parentheses_around_condition.rb +2 -2
- data/lib/rubocop/cop/style/percent_literal_delimiters.rb +1 -1
- data/lib/rubocop/cop/style/percent_q_literals.rb +1 -1
- data/lib/rubocop/cop/style/proc.rb +2 -2
- data/lib/rubocop/cop/style/quoted_symbols.rb +1 -3
- data/lib/rubocop/cop/style/raise_args.rb +15 -13
- data/lib/rubocop/cop/style/random_with_offset.rb +3 -3
- data/lib/rubocop/cop/style/redundant_argument.rb +3 -1
- data/lib/rubocop/cop/style/redundant_assignment.rb +1 -1
- data/lib/rubocop/cop/style/redundant_begin.rb +6 -1
- data/lib/rubocop/cop/style/redundant_condition.rb +97 -24
- data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +16 -5
- data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +6 -10
- data/lib/rubocop/cop/style/redundant_each.rb +1 -1
- data/lib/rubocop/cop/style/redundant_exception.rb +2 -2
- data/lib/rubocop/cop/style/redundant_format.rb +257 -0
- data/lib/rubocop/cop/style/redundant_freeze.rb +3 -3
- data/lib/rubocop/cop/style/redundant_initialize.rb +12 -3
- data/lib/rubocop/cop/style/redundant_interpolation_unfreeze.rb +46 -0
- data/lib/rubocop/cop/style/redundant_line_continuation.rb +56 -20
- data/lib/rubocop/cop/style/redundant_parentheses.rb +57 -27
- data/lib/rubocop/cop/style/redundant_regexp_argument.rb +8 -1
- data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +1 -1
- data/lib/rubocop/cop/style/redundant_regexp_escape.rb +1 -1
- data/lib/rubocop/cop/style/redundant_return.rb +2 -2
- data/lib/rubocop/cop/style/redundant_self.rb +9 -15
- data/lib/rubocop/cop/style/redundant_self_assignment.rb +20 -32
- data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +4 -4
- data/lib/rubocop/cop/style/redundant_sort.rb +3 -3
- data/lib/rubocop/cop/style/redundant_sort_by.rb +17 -1
- data/lib/rubocop/cop/style/redundant_string_escape.rb +2 -2
- data/lib/rubocop/cop/style/require_order.rb +1 -1
- data/lib/rubocop/cop/style/rescue_modifier.rb +18 -4
- data/lib/rubocop/cop/style/return_nil.rb +2 -2
- data/lib/rubocop/cop/style/return_nil_in_predicate_method_definition.rb +54 -12
- data/lib/rubocop/cop/style/safe_navigation.rb +123 -54
- data/lib/rubocop/cop/style/safe_navigation_chain_length.rb +52 -0
- data/lib/rubocop/cop/style/select_by_regexp.rb +14 -8
- data/lib/rubocop/cop/style/self_assignment.rb +11 -17
- data/lib/rubocop/cop/style/semicolon.rb +2 -2
- data/lib/rubocop/cop/style/send_with_literal_method_name.rb +2 -1
- data/lib/rubocop/cop/style/signal_exception.rb +2 -3
- data/lib/rubocop/cop/style/single_argument_dig.rb +9 -5
- data/lib/rubocop/cop/style/single_line_block_params.rb +1 -1
- data/lib/rubocop/cop/style/single_line_do_end_block.rb +15 -4
- data/lib/rubocop/cop/style/single_line_methods.rb +6 -7
- data/lib/rubocop/cop/style/slicing_with_range.rb +40 -11
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +42 -106
- data/lib/rubocop/cop/style/special_global_vars.rb +1 -1
- data/lib/rubocop/cop/style/string_concatenation.rb +15 -15
- data/lib/rubocop/cop/style/string_literals.rb +1 -1
- data/lib/rubocop/cop/style/string_methods.rb +1 -1
- data/lib/rubocop/cop/style/struct_inheritance.rb +9 -2
- data/lib/rubocop/cop/style/super_arguments.rb +66 -19
- data/lib/rubocop/cop/style/swap_values.rb +4 -15
- data/lib/rubocop/cop/style/symbol_proc.rb +2 -0
- data/lib/rubocop/cop/style/ternary_parentheses.rb +26 -5
- data/lib/rubocop/cop/style/top_level_method_definition.rb +2 -1
- data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +11 -2
- data/lib/rubocop/cop/style/trailing_comma_in_array_literal.rb +47 -6
- data/lib/rubocop/cop/style/trailing_comma_in_hash_literal.rb +48 -6
- data/lib/rubocop/cop/style/trailing_underscore_variable.rb +4 -4
- data/lib/rubocop/cop/style/trivial_accessors.rb +2 -2
- data/lib/rubocop/cop/style/variable_interpolation.rb +1 -2
- data/lib/rubocop/cop/style/while_until_modifier.rb +0 -1
- data/lib/rubocop/cop/style/yoda_condition.rb +8 -4
- data/lib/rubocop/cop/style/yoda_expression.rb +2 -1
- data/lib/rubocop/cop/team.rb +14 -3
- data/lib/rubocop/cop/util.rb +12 -5
- data/lib/rubocop/cop/utils/format_string.rb +10 -5
- data/lib/rubocop/cop/variable_force/assignment.rb +18 -3
- data/lib/rubocop/cop/variable_force/branch.rb +1 -1
- data/lib/rubocop/cop/variable_force/scope.rb +1 -1
- data/lib/rubocop/cop/variable_force/variable.rb +14 -3
- data/lib/rubocop/cop/variable_force/variable_table.rb +5 -5
- data/lib/rubocop/cop/variable_force.rb +5 -11
- data/lib/rubocop/cops_documentation_generator.rb +117 -53
- data/lib/rubocop/directive_comment.rb +45 -11
- data/lib/rubocop/ext/regexp_node.rb +0 -1
- data/lib/rubocop/file_finder.rb +9 -4
- data/lib/rubocop/formatter/disabled_config_formatter.rb +3 -2
- data/lib/rubocop/formatter/formatter_set.rb +1 -1
- data/lib/rubocop/formatter/html_formatter.rb +1 -1
- data/lib/rubocop/formatter/junit_formatter.rb +70 -23
- data/lib/rubocop/formatter/pacman_formatter.rb +1 -1
- data/lib/rubocop/lockfile.rb +6 -4
- data/lib/rubocop/lsp/diagnostic.rb +189 -0
- data/lib/rubocop/lsp/logger.rb +2 -2
- data/lib/rubocop/lsp/routes.rb +7 -23
- data/lib/rubocop/lsp/runtime.rb +19 -49
- data/lib/rubocop/lsp/server.rb +0 -3
- data/lib/rubocop/lsp/stdin_runner.rb +85 -0
- data/lib/rubocop/magic_comment.rb +11 -3
- data/lib/rubocop/options.rb +28 -12
- data/lib/rubocop/path_util.rb +15 -8
- data/lib/rubocop/plugin/configuration_integrator.rb +143 -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/rake_task.rb +4 -1
- data/lib/rubocop/remote_config.rb +5 -1
- data/lib/rubocop/result_cache.rb +15 -21
- data/lib/rubocop/rspec/cop_helper.rb +13 -1
- data/lib/rubocop/rspec/expect_offense.rb +7 -2
- data/lib/rubocop/rspec/shared_contexts.rb +40 -3
- data/lib/rubocop/rspec/support.rb +4 -2
- data/lib/rubocop/runner.rb +27 -13
- data/lib/rubocop/server/cache.rb +52 -11
- data/lib/rubocop/server/cli.rb +2 -2
- data/lib/rubocop/server/core.rb +1 -0
- data/lib/rubocop/target_finder.rb +7 -2
- data/lib/rubocop/target_ruby.rb +36 -17
- data/lib/rubocop/version.rb +54 -11
- data/lib/rubocop/yaml_duplication_checker.rb +20 -26
- data/lib/rubocop.rb +36 -2
- data/lib/ruby_lsp/rubocop/addon.rb +75 -0
- data/lib/ruby_lsp/rubocop/runtime_adapter.rb +65 -0
- metadata +83 -40
- data/lib/rubocop/cop/utils/regexp_ranges.rb +0 -113
- data/lib/rubocop/rspec/host_environment_simulation_helper.rb +0 -28
@@ -16,21 +16,35 @@ module RuboCop
|
|
16
16
|
#
|
17
17
|
# In Ruby 3.2, anonymous args/kwargs forwarding has been added.
|
18
18
|
#
|
19
|
-
# This cop also identifies places where
|
20
|
-
# replaced by
|
21
|
-
# by setting `UseAnonymousForwarding: false`.
|
19
|
+
# This cop also identifies places where `+use_args(*args)+`/`+use_kwargs(**kwargs)+` can be
|
20
|
+
# replaced by `+use_args(*)+`/`+use_kwargs(**)+`; if desired, this functionality can be
|
21
|
+
# disabled by setting `UseAnonymousForwarding: false`.
|
22
22
|
#
|
23
23
|
# And this cop has `RedundantRestArgumentNames`, `RedundantKeywordRestArgumentNames`,
|
24
24
|
# and `RedundantBlockArgumentNames` options. This configuration is a list of redundant names
|
25
25
|
# that are sufficient for anonymizing meaningless naming.
|
26
26
|
#
|
27
27
|
# Meaningless names that are commonly used can be anonymized by default:
|
28
|
-
# e.g.,
|
28
|
+
# e.g., `+*args+`, `+**options+`, `&block`, and so on.
|
29
29
|
#
|
30
30
|
# Names not on this list are likely to be meaningful and are allowed by default.
|
31
31
|
#
|
32
32
|
# This cop handles not only method forwarding but also forwarding to `super`.
|
33
33
|
#
|
34
|
+
# [NOTE]
|
35
|
+
# ====
|
36
|
+
# Because of a bug in Ruby 3.3.0, when a block is referenced inside of another block,
|
37
|
+
# no offense will be registered until Ruby 3.4:
|
38
|
+
#
|
39
|
+
# [source,ruby]
|
40
|
+
# ----
|
41
|
+
# def foo(&block)
|
42
|
+
# # Using an anonymous block would be a syntax error on Ruby 3.3.0
|
43
|
+
# block_method { bar(&block) }
|
44
|
+
# end
|
45
|
+
# ----
|
46
|
+
# ====
|
47
|
+
#
|
34
48
|
# @example
|
35
49
|
# # bad
|
36
50
|
# def foo(*args, &block)
|
@@ -132,7 +146,7 @@ module RuboCop
|
|
132
146
|
minimum_target_ruby_version 2.7
|
133
147
|
|
134
148
|
FORWARDING_LVAR_TYPES = %i[splat kwsplat block_pass].freeze
|
135
|
-
ADDITIONAL_ARG_TYPES = %i[lvar arg].freeze
|
149
|
+
ADDITIONAL_ARG_TYPES = %i[lvar arg optarg].freeze
|
136
150
|
|
137
151
|
FORWARDING_MSG = 'Use shorthand syntax `...` for arguments forwarding.'
|
138
152
|
ARGS_MSG = 'Use anonymous positional arguments forwarding (`*`).'
|
@@ -148,7 +162,7 @@ module RuboCop
|
|
148
162
|
|
149
163
|
restarg, kwrestarg, blockarg = extract_forwardable_args(node.arguments)
|
150
164
|
forwardable_args = redundant_forwardable_named_args(restarg, kwrestarg, blockarg)
|
151
|
-
send_nodes = node.each_descendant(:
|
165
|
+
send_nodes = node.each_descendant(:call, :super, :yield).to_a
|
152
166
|
|
153
167
|
send_classifications = classify_send_nodes(
|
154
168
|
node, send_nodes, non_splat_or_block_pass_lvar_references(node.body), forwardable_args
|
@@ -180,7 +194,8 @@ module RuboCop
|
|
180
194
|
end
|
181
195
|
|
182
196
|
def only_forwards_all?(send_classifications)
|
183
|
-
|
197
|
+
all_classifications = %i[all all_anonymous].freeze
|
198
|
+
send_classifications.all? { |_, c, _, _| all_classifications.include?(c) }
|
184
199
|
end
|
185
200
|
|
186
201
|
# rubocop:disable Metrics/MethodLength
|
@@ -188,11 +203,9 @@ module RuboCop
|
|
188
203
|
_rest_arg, _kwrest_arg, block_arg = *forwardable_args
|
189
204
|
registered_block_arg_offense = false
|
190
205
|
|
191
|
-
send_classifications.each do |send_node,
|
192
|
-
if !forward_rest && !forward_kwrest
|
193
|
-
|
194
|
-
# in Ruby 3.3.0.
|
195
|
-
if outside_block?(forward_block_arg)
|
206
|
+
send_classifications.each do |send_node, c, forward_rest, forward_kwrest, forward_block_arg| # rubocop:disable Layout/LineLength
|
207
|
+
if !forward_rest && !forward_kwrest && c != :all_anonymous
|
208
|
+
if allow_anonymous_forwarding_in_block?(forward_block_arg)
|
196
209
|
register_forward_block_arg_offense(!forward_rest, node.arguments, block_arg)
|
197
210
|
register_forward_block_arg_offense(!forward_rest, send_node, forward_block_arg)
|
198
211
|
end
|
@@ -213,23 +226,22 @@ module RuboCop
|
|
213
226
|
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
214
227
|
def add_post_ruby_32_offenses(def_node, send_classifications, forwardable_args)
|
215
228
|
return unless use_anonymous_forwarding?
|
229
|
+
return unless all_forwarding_offenses_correctable?(send_classifications)
|
216
230
|
|
217
231
|
rest_arg, kwrest_arg, block_arg = *forwardable_args
|
218
232
|
|
219
233
|
send_classifications.each do |send_node, _c, forward_rest, forward_kwrest, forward_block_arg| # rubocop:disable Layout/LineLength
|
220
|
-
if
|
234
|
+
if allow_anonymous_forwarding_in_block?(forward_rest)
|
221
235
|
register_forward_args_offense(def_node.arguments, rest_arg)
|
222
236
|
register_forward_args_offense(send_node, forward_rest)
|
223
237
|
end
|
224
238
|
|
225
|
-
if
|
239
|
+
if allow_anonymous_forwarding_in_block?(forward_kwrest)
|
226
240
|
register_forward_kwargs_offense(!forward_rest, def_node.arguments, kwrest_arg)
|
227
241
|
register_forward_kwargs_offense(!forward_rest, send_node, forward_kwrest)
|
228
242
|
end
|
229
243
|
|
230
|
-
|
231
|
-
# in Ruby 3.3.0.
|
232
|
-
if outside_block?(forward_block_arg)
|
244
|
+
if allow_anonymous_forwarding_in_block?(forward_block_arg)
|
233
245
|
register_forward_block_arg_offense(!forward_rest, def_node.arguments, block_arg)
|
234
246
|
register_forward_block_arg_offense(!forward_rest, send_node, forward_block_arg)
|
235
247
|
end
|
@@ -291,10 +303,25 @@ module RuboCop
|
|
291
303
|
redundant_arg_names.include?(arg.source) ? arg : nil
|
292
304
|
end
|
293
305
|
|
294
|
-
|
306
|
+
# Checks if forwarding is uses both in blocks and outside of blocks.
|
307
|
+
# On Ruby 3.3.0, anonymous block forwarding in blocks can be is a syntax
|
308
|
+
# error, so we only want to register an offense if we can change all occurrences.
|
309
|
+
def all_forwarding_offenses_correctable?(send_classifications)
|
310
|
+
return true if target_ruby_version >= 3.4
|
311
|
+
|
312
|
+
send_classifications.none? do |send_node, *|
|
313
|
+
send_node.each_ancestor(:any_block).any?
|
314
|
+
end
|
315
|
+
end
|
316
|
+
|
317
|
+
# Ruby 3.3.0 had a bug where accessing an anonymous block argument inside of a block
|
318
|
+
# was a syntax error in unambiguous cases: https://bugs.ruby-lang.org/issues/20090
|
319
|
+
# We disallow this also for earlier Ruby versions so that code is forwards compatible.
|
320
|
+
def allow_anonymous_forwarding_in_block?(node)
|
295
321
|
return false unless node
|
322
|
+
return true if target_ruby_version >= 3.4
|
296
323
|
|
297
|
-
node.each_ancestor(:
|
324
|
+
node.each_ancestor(:any_block).none?
|
298
325
|
end
|
299
326
|
|
300
327
|
def register_forward_args_offense(def_arguments_or_send, rest_arg_or_splat)
|
@@ -334,13 +361,18 @@ module RuboCop
|
|
334
361
|
end
|
335
362
|
end
|
336
363
|
|
364
|
+
# rubocop:disable Metrics/AbcSize
|
337
365
|
def arguments_range(node, first_node)
|
338
|
-
arguments = node.arguments.reject
|
366
|
+
arguments = node.arguments.reject do |arg|
|
367
|
+
next true if ADDITIONAL_ARG_TYPES.include?(arg.type) || arg.variable? || arg.call_type?
|
339
368
|
|
340
|
-
|
369
|
+
arg.literal? && arg.each_descendant(:kwsplat).none?
|
370
|
+
end
|
341
371
|
|
342
|
-
|
372
|
+
start_node = first_node || arguments.first
|
373
|
+
start_node.source_range.begin.join(arguments.last.source_range.end)
|
343
374
|
end
|
375
|
+
# rubocop:enable Metrics/AbcSize
|
344
376
|
|
345
377
|
def allow_only_rest_arguments?
|
346
378
|
cop_config.fetch('AllowOnlyRestArgument', true)
|
@@ -352,6 +384,7 @@ module RuboCop
|
|
352
384
|
|
353
385
|
def add_parens_if_missing(node, corrector)
|
354
386
|
return if parentheses?(node)
|
387
|
+
return if node.send_type? && node.method?(:[])
|
355
388
|
|
356
389
|
add_parentheses(node, corrector)
|
357
390
|
end
|
@@ -369,6 +402,23 @@ module RuboCop
|
|
369
402
|
# @!method forwarded_block_arg?(node, block_name)
|
370
403
|
def_node_matcher :forwarded_block_arg?, '(block_pass {(lvar %1) nil?})'
|
371
404
|
|
405
|
+
# @!method def_all_anonymous_args?(node)
|
406
|
+
def_node_matcher :def_all_anonymous_args?, <<~PATTERN
|
407
|
+
(
|
408
|
+
def _
|
409
|
+
(args ... (restarg) (kwrestarg) (blockarg nil?))
|
410
|
+
_
|
411
|
+
)
|
412
|
+
PATTERN
|
413
|
+
|
414
|
+
# @!method send_all_anonymous_args?(node)
|
415
|
+
def_node_matcher :send_all_anonymous_args?, <<~PATTERN
|
416
|
+
(
|
417
|
+
send _ _
|
418
|
+
... (forwarded_restarg) (hash (forwarded_kwrestarg)) (block_pass nil?)
|
419
|
+
)
|
420
|
+
PATTERN
|
421
|
+
|
372
422
|
def initialize(def_node, send_node, referenced_lvars, forwardable_args, **config)
|
373
423
|
@def_node = def_node
|
374
424
|
@send_node = send_node
|
@@ -400,7 +450,9 @@ module RuboCop
|
|
400
450
|
def classification
|
401
451
|
return nil unless forwarded_rest_arg || forwarded_kwrest_arg || forwarded_block_arg
|
402
452
|
|
403
|
-
if
|
453
|
+
if ruby_32_only_anonymous_forwarding?
|
454
|
+
:all_anonymous
|
455
|
+
elsif can_forward_all?
|
404
456
|
:all
|
405
457
|
else
|
406
458
|
:rest_or_kwrest
|
@@ -409,16 +461,31 @@ module RuboCop
|
|
409
461
|
|
410
462
|
private
|
411
463
|
|
464
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
412
465
|
def can_forward_all?
|
413
466
|
return false if any_arg_referenced?
|
414
|
-
return false if
|
467
|
+
return false if ruby_30_or_lower_optarg?
|
468
|
+
return false if ruby_32_or_higher_missing_rest_or_kwest?
|
415
469
|
return false unless offensive_block_forwarding?
|
416
470
|
return false if additional_kwargs_or_forwarded_kwargs?
|
417
471
|
|
418
472
|
no_additional_args? || (target_ruby_version >= 3.0 && no_post_splat_args?)
|
419
473
|
end
|
474
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
475
|
+
|
476
|
+
# def foo(a = 41, ...) is a syntax error in 3.0.
|
477
|
+
def ruby_30_or_lower_optarg?
|
478
|
+
target_ruby_version <= 3.0 && @def_node.arguments.any?(&:optarg_type?)
|
479
|
+
end
|
480
|
+
|
481
|
+
def ruby_32_only_anonymous_forwarding?
|
482
|
+
# A block argument and an anonymous block argument are never passed together.
|
483
|
+
return false if @send_node.each_ancestor(:any_block).any?
|
420
484
|
|
421
|
-
|
485
|
+
def_all_anonymous_args?(@def_node) && send_all_anonymous_args?(@send_node)
|
486
|
+
end
|
487
|
+
|
488
|
+
def ruby_32_or_higher_missing_rest_or_kwest?
|
422
489
|
target_ruby_version >= 3.2 && !forwarded_rest_and_kwrest_args
|
423
490
|
end
|
424
491
|
|
@@ -466,7 +533,7 @@ module RuboCop
|
|
466
533
|
end
|
467
534
|
|
468
535
|
def additional_kwargs?
|
469
|
-
@def_node.arguments.any? { |a| a.
|
536
|
+
@def_node.arguments.any? { |a| a.type?(:kwarg, :kwoptarg) }
|
470
537
|
end
|
471
538
|
|
472
539
|
def forward_additional_kwargs?
|
@@ -495,10 +562,7 @@ module RuboCop
|
|
495
562
|
end
|
496
563
|
|
497
564
|
def explicit_block_name?
|
498
|
-
|
499
|
-
return false unless block_forwarding_config['Enabled']
|
500
|
-
|
501
|
-
block_forwarding_config['EnforcedStyle'] == 'explicit'
|
565
|
+
config.for_enabled_cop('Naming/BlockForwarding')['EnforcedStyle'] == 'explicit'
|
502
566
|
end
|
503
567
|
end
|
504
568
|
end
|
@@ -42,14 +42,30 @@ module RuboCop
|
|
42
42
|
return if node.parent && brace_method?(node.parent)
|
43
43
|
|
44
44
|
preferred = (value.zero? ? 'first' : 'last')
|
45
|
-
|
46
|
-
|
45
|
+
offense_range = find_offense_range(node)
|
46
|
+
|
47
|
+
add_offense(offense_range, message: format(MSG, preferred: preferred)) do |corrector|
|
48
|
+
corrector.replace(offense_range, preferred_value(node, preferred))
|
47
49
|
end
|
48
50
|
end
|
49
51
|
# rubocop:enable Metrics/AbcSize
|
52
|
+
alias on_csend on_send
|
50
53
|
|
51
54
|
private
|
52
55
|
|
56
|
+
def preferred_value(node, value)
|
57
|
+
value = ".#{value}" unless node.loc.dot
|
58
|
+
value
|
59
|
+
end
|
60
|
+
|
61
|
+
def find_offense_range(node)
|
62
|
+
if node.loc.dot
|
63
|
+
node.loc.selector.join(node.source_range.end)
|
64
|
+
else
|
65
|
+
node.loc.selector
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
53
69
|
def innermost_braces_node(node)
|
54
70
|
node = node.receiver while node.receiver.send_type? && node.receiver.method?(:[])
|
55
71
|
node
|
@@ -6,7 +6,8 @@ module RuboCop
|
|
6
6
|
# In Ruby 3.1, `Array#intersect?` has been added.
|
7
7
|
#
|
8
8
|
# This cop identifies places where `(array1 & array2).any?`
|
9
|
-
# can be replaced by
|
9
|
+
# or `(array1.intersection(array2)).any?` can be replaced by
|
10
|
+
# `array1.intersect?(array2)`.
|
10
11
|
#
|
11
12
|
# The `array1.intersect?(array2)` method is faster than
|
12
13
|
# `(array1 & array2).any?` and is more readable.
|
@@ -20,6 +21,10 @@ module RuboCop
|
|
20
21
|
# [1].intersect?([1,2]) { |x| false } # => true
|
21
22
|
# ----
|
22
23
|
#
|
24
|
+
# NOTE: Although `Array#intersection` can take zero or multiple arguments,
|
25
|
+
# only cases where exactly one argument is provided can be replaced with
|
26
|
+
# `Array#intersect?` and are handled by this cop.
|
27
|
+
#
|
23
28
|
# @safety
|
24
29
|
# This cop cannot guarantee that `array1` and `array2` are
|
25
30
|
# actually arrays while method `intersect?` is for arrays only.
|
@@ -28,6 +33,12 @@ module RuboCop
|
|
28
33
|
# # bad
|
29
34
|
# (array1 & array2).any?
|
30
35
|
# (array1 & array2).empty?
|
36
|
+
# (array1 & array2).none?
|
37
|
+
#
|
38
|
+
# # bad
|
39
|
+
# array1.intersection(array2).any?
|
40
|
+
# array1.intersection(array2).empty?
|
41
|
+
# array1.intersection(array2).none?
|
31
42
|
#
|
32
43
|
# # good
|
33
44
|
# array1.intersect?(array2)
|
@@ -52,65 +63,66 @@ module RuboCop
|
|
52
63
|
|
53
64
|
minimum_target_ruby_version 3.1
|
54
65
|
|
55
|
-
|
56
|
-
|
57
|
-
(send
|
58
|
-
(begin
|
59
|
-
(send $(...) :& $(...))
|
60
|
-
) ${:any? :empty?}
|
61
|
-
)
|
62
|
-
PATTERN
|
66
|
+
PREDICATES = %i[any? empty? none?].to_set.freeze
|
67
|
+
ACTIVE_SUPPORT_PREDICATES = (PREDICATES + %i[present? blank?]).freeze
|
63
68
|
|
64
|
-
# @!method
|
65
|
-
def_node_matcher :
|
66
|
-
(
|
67
|
-
|
68
|
-
(send $
|
69
|
-
|
69
|
+
# @!method bad_intersection_check?(node, predicates)
|
70
|
+
def_node_matcher :bad_intersection_check?, <<~PATTERN
|
71
|
+
(call
|
72
|
+
{
|
73
|
+
(begin (send $_ :& $_))
|
74
|
+
(call $_ :intersection $_)
|
75
|
+
}
|
76
|
+
$%1
|
70
77
|
)
|
71
78
|
PATTERN
|
72
79
|
|
73
|
-
MSG = 'Use `%<negated>s%<receiver>s
|
74
|
-
'instead of
|
80
|
+
MSG = 'Use `%<negated>s%<receiver>s%<dot>sintersect?(%<argument>s)` ' \
|
81
|
+
'instead of `%<existing>s`.'
|
75
82
|
STRAIGHT_METHODS = %i[present? any?].freeze
|
76
|
-
NEGATED_METHODS = %i[blank? empty?].freeze
|
83
|
+
NEGATED_METHODS = %i[blank? empty? none?].freeze
|
77
84
|
RESTRICT_ON_SEND = (STRAIGHT_METHODS + NEGATED_METHODS).freeze
|
78
85
|
|
79
86
|
def on_send(node)
|
80
|
-
return if
|
81
|
-
return unless (receiver, argument, method_name =
|
87
|
+
return if node.block_literal?
|
88
|
+
return unless (receiver, argument, method_name = bad_intersection?(node))
|
82
89
|
|
83
|
-
|
90
|
+
dot = node.loc.dot.source
|
91
|
+
message = message(receiver.source, argument.source, method_name, dot, node.source)
|
84
92
|
|
85
93
|
add_offense(node, message: message) do |corrector|
|
86
94
|
bang = straight?(method_name) ? '' : '!'
|
87
95
|
|
88
|
-
corrector.replace(node, "#{bang}#{receiver.source}
|
96
|
+
corrector.replace(node, "#{bang}#{receiver.source}#{dot}intersect?(#{argument.source})")
|
89
97
|
end
|
90
98
|
end
|
99
|
+
alias on_csend on_send
|
91
100
|
|
92
101
|
private
|
93
102
|
|
94
|
-
def
|
95
|
-
if active_support_extensions_enabled?
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
103
|
+
def bad_intersection?(node)
|
104
|
+
predicates = if active_support_extensions_enabled?
|
105
|
+
ACTIVE_SUPPORT_PREDICATES
|
106
|
+
else
|
107
|
+
PREDICATES
|
108
|
+
end
|
109
|
+
|
110
|
+
bad_intersection_check?(node, predicates)
|
100
111
|
end
|
101
112
|
|
102
113
|
def straight?(method_name)
|
103
114
|
STRAIGHT_METHODS.include?(method_name.to_sym)
|
104
115
|
end
|
105
116
|
|
106
|
-
def message(receiver, argument, method_name)
|
117
|
+
def message(receiver, argument, method_name, dot, existing)
|
107
118
|
negated = straight?(method_name) ? '' : '!'
|
108
119
|
format(
|
109
120
|
MSG,
|
110
121
|
negated: negated,
|
111
122
|
receiver: receiver,
|
112
123
|
argument: argument,
|
113
|
-
|
124
|
+
dot: dot,
|
125
|
+
existing: existing
|
114
126
|
)
|
115
127
|
end
|
116
128
|
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Style
|
6
|
+
# Prefer bitwise predicate methods over direct comparison operations.
|
7
|
+
#
|
8
|
+
# @safety
|
9
|
+
# This cop is unsafe, as it can produce false positives if the receiver
|
10
|
+
# is not an `Integer` object.
|
11
|
+
#
|
12
|
+
# @example
|
13
|
+
#
|
14
|
+
# # bad - checks any set bits
|
15
|
+
# (variable & flags).positive?
|
16
|
+
#
|
17
|
+
# # good
|
18
|
+
# variable.anybits?(flags)
|
19
|
+
#
|
20
|
+
# # bad - checks all set bits
|
21
|
+
# (variable & flags) == flags
|
22
|
+
#
|
23
|
+
# # good
|
24
|
+
# variable.allbits?(flags)
|
25
|
+
#
|
26
|
+
# # bad - checks no set bits
|
27
|
+
# (variable & flags).zero?
|
28
|
+
#
|
29
|
+
# # good
|
30
|
+
# variable.nobits?(flags)
|
31
|
+
#
|
32
|
+
class BitwisePredicate < Base
|
33
|
+
extend AutoCorrector
|
34
|
+
extend TargetRubyVersion
|
35
|
+
|
36
|
+
MSG = 'Replace with `%<preferred>s` for comparison with bit flags.'
|
37
|
+
RESTRICT_ON_SEND = %i[!= == > >= positive? zero?].freeze
|
38
|
+
|
39
|
+
minimum_target_ruby_version 2.5
|
40
|
+
|
41
|
+
# @!method anybits?(node)
|
42
|
+
def_node_matcher :anybits?, <<~PATTERN
|
43
|
+
{
|
44
|
+
(send #bit_operation? :positive?)
|
45
|
+
(send #bit_operation? :> (int 0))
|
46
|
+
(send #bit_operation? :>= (int 1))
|
47
|
+
(send #bit_operation? :!= (int 0))
|
48
|
+
}
|
49
|
+
PATTERN
|
50
|
+
|
51
|
+
# @!method allbits?(node)
|
52
|
+
def_node_matcher :allbits?, <<~PATTERN
|
53
|
+
{
|
54
|
+
(send (begin (send _ :& _flags)) :== _flags)
|
55
|
+
(send (begin (send _flags :& _)) :== _flags)
|
56
|
+
}
|
57
|
+
PATTERN
|
58
|
+
|
59
|
+
# @!method nobits?(node)
|
60
|
+
def_node_matcher :nobits?, <<~PATTERN
|
61
|
+
{
|
62
|
+
(send #bit_operation? :zero?)
|
63
|
+
(send #bit_operation? :== (int 0))
|
64
|
+
}
|
65
|
+
PATTERN
|
66
|
+
|
67
|
+
# @!method bit_operation?(node)
|
68
|
+
def_node_matcher :bit_operation?, <<~PATTERN
|
69
|
+
(begin
|
70
|
+
(send _ :& _))
|
71
|
+
PATTERN
|
72
|
+
|
73
|
+
def on_send(node)
|
74
|
+
return unless node.receiver&.begin_type?
|
75
|
+
return unless (preferred_method = preferred_method(node))
|
76
|
+
|
77
|
+
bit_operation = node.receiver.children.first
|
78
|
+
lhs, _operator, rhs = *bit_operation
|
79
|
+
preferred = "#{lhs.source}.#{preferred_method}(#{rhs.source})"
|
80
|
+
|
81
|
+
add_offense(node, message: format(MSG, preferred: preferred)) do |corrector|
|
82
|
+
corrector.replace(node, preferred)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
private
|
87
|
+
|
88
|
+
def preferred_method(node)
|
89
|
+
if anybits?(node)
|
90
|
+
'anybits?'
|
91
|
+
elsif allbits?(node)
|
92
|
+
'allbits?'
|
93
|
+
elsif nobits?(node)
|
94
|
+
'nobits?'
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -176,10 +176,15 @@ module RuboCop
|
|
176
176
|
|
177
177
|
BRACES_REQUIRED_MESSAGE = "Brace delimiters `{...}` required for '%<method_name>s' method."
|
178
178
|
|
179
|
+
def self.autocorrect_incompatible_with
|
180
|
+
[Style::RedundantBegin]
|
181
|
+
end
|
182
|
+
|
179
183
|
def on_send(node)
|
180
184
|
return unless node.arguments?
|
181
185
|
return if node.parenthesized?
|
182
|
-
return if node.
|
186
|
+
return if node.assignment_method?
|
187
|
+
return if single_argument_operator_method?(node)
|
183
188
|
|
184
189
|
node.arguments.each do |arg|
|
185
190
|
get_blocks(arg) do |block|
|
@@ -190,6 +195,7 @@ module RuboCop
|
|
190
195
|
end
|
191
196
|
end
|
192
197
|
end
|
198
|
+
alias on_csend on_send
|
193
199
|
|
194
200
|
def on_block(node)
|
195
201
|
return if ignored_node?(node)
|
@@ -202,6 +208,7 @@ module RuboCop
|
|
202
208
|
end
|
203
209
|
|
204
210
|
alias on_numblock on_block
|
211
|
+
alias on_itblock on_block
|
205
212
|
|
206
213
|
private
|
207
214
|
|
@@ -299,13 +306,28 @@ module RuboCop
|
|
299
306
|
|
300
307
|
def move_comment_before_block(corrector, comment, block_node, closing_brace)
|
301
308
|
range = block_node.chained? ? end_of_chain(block_node.parent).source_range : closing_brace
|
309
|
+
|
310
|
+
# It is possible that there is code between the block and the comment
|
311
|
+
# which needs to be preserved and trimmed.
|
312
|
+
pre_comment_range = source_range_before_comment(range, comment)
|
313
|
+
|
302
314
|
corrector.remove(range_with_surrounding_space(comment.source_range, side: :right))
|
303
|
-
remove_trailing_whitespace(corrector,
|
304
|
-
corrector.insert_after(
|
315
|
+
remove_trailing_whitespace(corrector, pre_comment_range, comment)
|
316
|
+
corrector.insert_after(pre_comment_range, "\n")
|
305
317
|
|
306
318
|
corrector.insert_before(block_node, "#{comment.text}\n")
|
307
319
|
end
|
308
320
|
|
321
|
+
def source_range_before_comment(range, comment)
|
322
|
+
range = range.end.join(comment.source_range.begin)
|
323
|
+
|
324
|
+
# End the range before any whitespace that precedes the comment
|
325
|
+
trailing_whitespace_count = range.source[/\s+\z/]&.length
|
326
|
+
range = range.adjust(end_pos: -trailing_whitespace_count) if trailing_whitespace_count
|
327
|
+
|
328
|
+
range
|
329
|
+
end
|
330
|
+
|
309
331
|
def end_of_chain(node)
|
310
332
|
return end_of_chain(node.block_node) if with_block?(node)
|
311
333
|
return node unless node.chained?
|
@@ -323,16 +345,23 @@ module RuboCop
|
|
323
345
|
node.respond_to?(:block_node) && node.block_node
|
324
346
|
end
|
325
347
|
|
348
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
326
349
|
def get_blocks(node, &block)
|
327
350
|
case node.type
|
328
|
-
when :block, :numblock
|
351
|
+
when :block, :numblock, :itblock
|
329
352
|
yield node
|
330
|
-
when :send
|
353
|
+
when :send, :csend
|
354
|
+
# When a method has an argument which is another method with a block,
|
355
|
+
# that block needs braces, otherwise a syntax error will be introduced
|
356
|
+
# for subsequent arguments.
|
357
|
+
# Additionally, even without additional arguments, changing `{...}` to
|
358
|
+
# `do...end` will change the binding of the block to the outer method.
|
331
359
|
get_blocks(node.receiver, &block) if node.receiver
|
360
|
+
node.arguments.each { |argument| get_blocks(argument, &block) }
|
332
361
|
when :hash
|
333
362
|
# A hash which is passed as method argument may have no braces
|
334
363
|
# In that case, one of the K/V pairs could contain a block node
|
335
|
-
# which could change in meaning if do...end replaced {...}
|
364
|
+
# which could change in meaning if `do...end` is replaced with `{...}`
|
336
365
|
return if node.braces?
|
337
366
|
|
338
367
|
node.each_child_node { |child| get_blocks(child, &block) }
|
@@ -340,9 +369,10 @@ module RuboCop
|
|
340
369
|
node.each_child_node { |child| get_blocks(child, &block) }
|
341
370
|
end
|
342
371
|
end
|
372
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
343
373
|
|
344
374
|
def proper_block_style?(node)
|
345
|
-
return true if
|
375
|
+
return true if require_do_end?(node)
|
346
376
|
return special_method_proper_block_style?(node) if special_method?(node.method_name)
|
347
377
|
|
348
378
|
case style
|
@@ -353,12 +383,11 @@ module RuboCop
|
|
353
383
|
end
|
354
384
|
end
|
355
385
|
|
356
|
-
def
|
357
|
-
return false
|
386
|
+
def require_do_end?(node)
|
387
|
+
return false if node.braces? || node.multiline?
|
388
|
+
return false unless (resbody = node.each_descendant(:resbody).first)
|
358
389
|
|
359
|
-
|
360
|
-
send.arithmetic_operation? && node.source_range.end_pos < send.loc.selector.begin_pos
|
361
|
-
end
|
390
|
+
resbody.children.first&.array_type?
|
362
391
|
end
|
363
392
|
|
364
393
|
def special_method?(method_name)
|
@@ -446,18 +475,14 @@ module RuboCop
|
|
446
475
|
end
|
447
476
|
|
448
477
|
def return_value_of_scope?(node)
|
449
|
-
return false unless node.parent
|
450
|
-
|
451
|
-
conditional?(node.parent) || array_or_range?(node.parent) ||
|
452
|
-
node.parent.children.last == node
|
453
|
-
end
|
478
|
+
return false unless (parent = node.parent)
|
454
479
|
|
455
|
-
|
456
|
-
|
480
|
+
parent.conditional? || parent.operator_keyword? || array_or_range?(parent) ||
|
481
|
+
parent.children.last == node
|
457
482
|
end
|
458
483
|
|
459
484
|
def array_or_range?(node)
|
460
|
-
node.
|
485
|
+
node.type?(:array, :range)
|
461
486
|
end
|
462
487
|
|
463
488
|
def begin_required?(block_node)
|
@@ -465,6 +490,12 @@ module RuboCop
|
|
465
490
|
# `begin`...`end` when changing `do-end` to `{}`.
|
466
491
|
block_node.each_child_node(:rescue, :ensure).any? && !block_node.single_line?
|
467
492
|
end
|
493
|
+
|
494
|
+
def single_argument_operator_method?(node)
|
495
|
+
return false unless node.operator_method?
|
496
|
+
|
497
|
+
node.arguments.one? && node.first_argument.block_type?
|
498
|
+
end
|
468
499
|
end
|
469
500
|
end
|
470
501
|
end
|