rubocop 1.67.0 → 1.73.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/LICENSE.txt +1 -1
- data/README.md +4 -4
- data/config/default.yml +168 -19
- data/config/internal_affairs.yml +16 -0
- data/lib/rubocop/cached_data.rb +12 -4
- data/lib/rubocop/cli/command/execute_runner.rb +4 -4
- 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/comment_config.rb +2 -2
- data/lib/rubocop/config.rb +17 -4
- data/lib/rubocop/config_loader.rb +48 -8
- data/lib/rubocop/config_loader_resolver.rb +35 -10
- data/lib/rubocop/config_validator.rb +19 -9
- data/lib/rubocop/cop/autocorrect_logic.rb +36 -19
- data/lib/rubocop/cop/base.rb +7 -1
- 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/insecure_protocol_source.rb +0 -1
- 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/percent_literal_corrector.rb +10 -0
- 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_enabled.rb +85 -0
- data/lib/rubocop/cop/internal_affairs/example_description.rb +4 -2
- 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 +1 -1
- 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 +229 -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_source_range.rb +3 -1
- 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 +7 -1
- data/lib/rubocop/cop/internal_affairs.rb +6 -16
- data/lib/rubocop/cop/layout/access_modifier_indentation.rb +1 -1
- 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 +3 -2
- data/lib/rubocop/cop/layout/class_structure.rb +9 -9
- 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 +2 -2
- data/lib/rubocop/cop/layout/empty_line_between_defs.rb +7 -11
- data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +29 -4
- data/lib/rubocop/cop/layout/empty_lines_around_begin_body.rb +5 -6
- data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +4 -5
- 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 -7
- 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_parameter_indentation.rb +2 -2
- data/lib/rubocop/cop/layout/hash_alignment.rb +6 -4
- data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +2 -1
- data/lib/rubocop/cop/layout/indentation_width.rb +7 -7
- data/lib/rubocop/cop/layout/leading_comment_space.rb +44 -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 +119 -4
- 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_operation_indentation.rb +2 -3
- data/lib/rubocop/cop/layout/parameter_alignment.rb +3 -4
- data/lib/rubocop/cop/layout/redundant_line_break.rb +10 -41
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +4 -3
- 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 +1 -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 +19 -20
- 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 +6 -0
- data/lib/rubocop/cop/layout/space_inside_block_braces.rb +4 -0
- data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +4 -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/array_literal_in_regexp.rb +119 -0
- data/lib/rubocop/cop/lint/assignment_in_condition.rb +1 -3
- data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +10 -12
- data/lib/rubocop/cop/lint/circular_argument_reference.rb +6 -0
- 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 +1 -1
- data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +2 -1
- 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 +0 -14
- data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +1 -1
- data/lib/rubocop/cop/lint/duplicate_set_element.rb +20 -7
- 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 -1
- data/lib/rubocop/cop/lint/float_comparison.rb +20 -14
- 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 +1 -1
- data/lib/rubocop/cop/lint/interpolation_check.rb +9 -0
- data/lib/rubocop/cop/lint/it_without_arguments_in_block.rb +3 -0
- data/lib/rubocop/cop/lint/literal_as_condition.rb +105 -7
- data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +1 -1
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +24 -6
- data/lib/rubocop/cop/lint/missing_super.rb +2 -2
- data/lib/rubocop/cop/lint/mixed_case_range.rb +4 -7
- data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +1 -1
- data/lib/rubocop/cop/lint/nested_method_definition.rb +9 -5
- 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 +1 -1
- 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 +1 -2
- data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +3 -2
- data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +1 -5
- 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 +12 -7
- 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 +252 -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/safe_navigation_chain.rb +17 -1
- data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +5 -1
- 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/shared_mutable_default.rb +65 -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 +1 -1
- data/lib/rubocop/cop/lint/syntax.rb +4 -1
- data/lib/rubocop/cop/lint/unescaped_bracket_in_regexp.rb +88 -0
- data/lib/rubocop/cop/lint/unexpected_block_arity.rb +1 -1
- data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +1 -1
- data/lib/rubocop/cop/lint/unreachable_code.rb +51 -2
- data/lib/rubocop/cop/lint/unreachable_loop.rb +1 -1
- data/lib/rubocop/cop/lint/unused_method_argument.rb +18 -2
- data/lib/rubocop/cop/lint/useless_access_modifier.rb +4 -4
- data/lib/rubocop/cop/lint/useless_assignment.rb +1 -1
- data/lib/rubocop/cop/lint/useless_constant_scoping.rb +80 -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 +2 -1
- data/lib/rubocop/cop/lint/useless_rescue.rb +1 -1
- 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 +14 -11
- data/lib/rubocop/cop/metrics/block_nesting.rb +1 -1
- data/lib/rubocop/cop/metrics/class_length.rb +9 -9
- 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 +8 -1
- data/lib/rubocop/cop/metrics/module_length.rb +1 -1
- 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 +2 -3
- 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/check_assignment.rb +4 -12
- data/lib/rubocop/cop/mixin/check_line_breakable.rb +20 -10
- 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/dig_help.rb +27 -0
- data/lib/rubocop/cop/mixin/endless_method_rewriter.rb +24 -0
- data/lib/rubocop/cop/mixin/frozen_string_literal.rb +4 -2
- 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 +5 -4
- data/lib/rubocop/cop/mixin/method_complexity.rb +1 -1
- data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +5 -9
- 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 +3 -4
- data/lib/rubocop/cop/mixin/space_before_punctuation.rb +1 -1
- data/lib/rubocop/cop/mixin/statement_modifier.rb +8 -3
- data/lib/rubocop/cop/mixin/string_help.rb +2 -2
- data/lib/rubocop/cop/mixin/string_literals_help.rb +1 -1
- data/lib/rubocop/cop/mixin/target_ruby_version.rb +17 -1
- data/lib/rubocop/cop/mixin/trailing_comma.rb +15 -3
- data/lib/rubocop/cop/naming/accessor_method_name.rb +6 -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/memoized_instance_variable_name.rb +11 -12
- data/lib/rubocop/cop/naming/predicate_name.rb +44 -0
- data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +6 -14
- data/lib/rubocop/cop/naming/variable_name.rb +63 -6
- data/lib/rubocop/cop/naming/variable_number.rb +2 -3
- data/lib/rubocop/cop/offense.rb +2 -3
- 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 +86 -28
- data/lib/rubocop/cop/style/accessor_grouping.rb +19 -5
- 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 +39 -23
- data/lib/rubocop/cop/style/array_first_last.rb +18 -2
- data/lib/rubocop/cop/style/array_intersect.rb +5 -4
- data/lib/rubocop/cop/style/bitwise_predicate.rb +100 -0
- data/lib/rubocop/cop/style/block_delimiters.rb +41 -24
- data/lib/rubocop/cop/style/case_like_if.rb +8 -11
- data/lib/rubocop/cop/style/class_and_module_children.rb +6 -3
- data/lib/rubocop/cop/style/collection_methods.rb +1 -1
- data/lib/rubocop/cop/style/combinable_defined.rb +115 -0
- data/lib/rubocop/cop/style/combinable_loops.rb +2 -2
- data/lib/rubocop/cop/style/commented_keyword.rb +11 -1
- data/lib/rubocop/cop/style/concat_array_literals.rb +1 -1
- data/lib/rubocop/cop/style/conditional_assignment.rb +25 -25
- data/lib/rubocop/cop/style/constant_visibility.rb +3 -12
- 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 +3 -3
- 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 +4 -2
- data/lib/rubocop/cop/style/empty_literal.rb +1 -1
- 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 +1 -1
- data/lib/rubocop/cop/style/exact_regexp_match.rb +2 -3
- data/lib/rubocop/cop/style/explicit_block_argument.rb +15 -2
- data/lib/rubocop/cop/style/exponential_notation.rb +1 -1
- 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 +0 -1
- data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +1 -1
- data/lib/rubocop/cop/style/global_vars.rb +1 -3
- data/lib/rubocop/cop/style/guard_clause.rb +15 -2
- data/lib/rubocop/cop/style/hash_conversion.rb +1 -2
- data/lib/rubocop/cop/style/hash_each_methods.rb +3 -6
- data/lib/rubocop/cop/style/hash_except.rb +35 -147
- data/lib/rubocop/cop/style/hash_slice.rb +80 -0
- data/lib/rubocop/cop/style/hash_syntax.rb +6 -3
- data/lib/rubocop/cop/style/identical_conditional_branches.rb +22 -3
- data/lib/rubocop/cop/style/if_inside_else.rb +0 -1
- data/lib/rubocop/cop/style/if_unless_modifier.rb +3 -3
- data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +2 -3
- data/lib/rubocop/cop/style/if_with_semicolon.rb +20 -9
- data/lib/rubocop/cop/style/infinite_loop.rb +1 -1
- data/lib/rubocop/cop/style/inverse_methods.rb +6 -7
- data/lib/rubocop/cop/style/it_assignment.rb +36 -0
- data/lib/rubocop/cop/style/keyword_arguments_merging.rb +67 -0
- data/lib/rubocop/cop/style/keyword_parameters_order.rb +1 -1
- data/lib/rubocop/cop/style/lambda_call.rb +3 -2
- data/lib/rubocop/cop/style/line_end_concatenation.rb +10 -4
- data/lib/rubocop/cop/style/map_into_array.rb +7 -2
- 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 +20 -13
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +2 -0
- data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +8 -11
- data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +2 -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 +1 -1
- data/lib/rubocop/cop/style/multiline_memoization.rb +1 -1
- data/lib/rubocop/cop/style/multiple_comparison.rb +52 -51
- 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_parenthesized_calls.rb +1 -1
- data/lib/rubocop/cop/style/nested_ternary_operator.rb +5 -4
- data/lib/rubocop/cop/style/not.rb +1 -1
- data/lib/rubocop/cop/style/object_then.rb +14 -15
- data/lib/rubocop/cop/style/one_line_conditional.rb +25 -4
- data/lib/rubocop/cop/style/open_struct_use.rb +5 -5
- data/lib/rubocop/cop/style/operator_method_call.rb +5 -6
- data/lib/rubocop/cop/style/or_assignment.rb +3 -6
- data/lib/rubocop/cop/style/parallel_assignment.rb +9 -18
- 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/proc.rb +1 -2
- data/lib/rubocop/cop/style/quoted_symbols.rb +1 -1
- data/lib/rubocop/cop/style/raise_args.rb +7 -5
- 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 +1 -1
- data/lib/rubocop/cop/style/redundant_condition.rb +72 -23
- data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +2 -1
- 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 +250 -0
- data/lib/rubocop/cop/style/redundant_freeze.rb +2 -2
- data/lib/rubocop/cop/style/redundant_initialize.rb +12 -3
- data/lib/rubocop/cop/style/redundant_line_continuation.rb +54 -15
- data/lib/rubocop/cop/style/redundant_parentheses.rb +36 -24
- data/lib/rubocop/cop/style/redundant_regexp_argument.rb +4 -0
- 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 +8 -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_string_escape.rb +2 -2
- data/lib/rubocop/cop/style/rescue_modifier.rb +2 -3
- data/lib/rubocop/cop/style/return_nil.rb +1 -1
- data/lib/rubocop/cop/style/safe_navigation.rb +14 -2
- data/lib/rubocop/cop/style/safe_navigation_chain_length.rb +52 -0
- data/lib/rubocop/cop/style/select_by_regexp.rb +1 -1
- data/lib/rubocop/cop/style/self_assignment.rb +11 -17
- data/lib/rubocop/cop/style/semicolon.rb +1 -1
- 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 +12 -3
- 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 +4 -5
- data/lib/rubocop/cop/style/special_global_vars.rb +1 -1
- data/lib/rubocop/cop/style/string_concatenation.rb +15 -14
- 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/super_arguments.rb +65 -17
- data/lib/rubocop/cop/style/swap_values.rb +4 -15
- data/lib/rubocop/cop/style/ternary_parentheses.rb +25 -4
- data/lib/rubocop/cop/style/top_level_method_definition.rb +1 -1
- data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +4 -1
- 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 +1 -1
- 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/util.rb +12 -5
- data/lib/rubocop/cop/utils/format_string.rb +7 -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/variable.rb +18 -2
- data/lib/rubocop/cop/variable_force/variable_table.rb +5 -5
- data/lib/rubocop/cop/variable_force.rb +4 -10
- data/lib/rubocop/cops_documentation_generator.rb +44 -23
- data/lib/rubocop/directive_comment.rb +44 -10
- data/lib/rubocop/formatter/disabled_config_formatter.rb +1 -1
- data/lib/rubocop/formatter/formatter_set.rb +1 -1
- 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 +17 -49
- data/lib/rubocop/lsp/server.rb +0 -2
- data/lib/rubocop/lsp/stdin_runner.rb +83 -0
- data/lib/rubocop/magic_comment.rb +3 -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/result_cache.rb +13 -13
- data/lib/rubocop/rspec/cop_helper.rb +9 -0
- data/lib/rubocop/rspec/expect_offense.rb +6 -2
- data/lib/rubocop/rspec/shared_contexts.rb +19 -1
- data/lib/rubocop/rspec/support.rb +2 -2
- data/lib/rubocop/runner.rb +21 -14
- data/lib/rubocop/server/cache.rb +35 -2
- data/lib/rubocop/server/cli.rb +2 -2
- data/lib/rubocop/target_finder.rb +1 -0
- data/lib/rubocop/target_ruby.rb +16 -1
- data/lib/rubocop/version.rb +41 -7
- data/lib/rubocop.rb +27 -1
- data/lib/ruby_lsp/rubocop/addon.rb +75 -0
- data/lib/ruby_lsp/rubocop/runtime_adapter.rb +47 -0
- metadata +73 -20
- data/lib/rubocop/cop/utils/regexp_ranges.rb +0 -113
- data/lib/rubocop/rspec/host_environment_simulation_helper.rb +0 -28
@@ -70,6 +70,7 @@ module RuboCop
|
|
70
70
|
# private :bar, :baz
|
71
71
|
# private *%i[qux quux]
|
72
72
|
# private *METHOD_NAMES
|
73
|
+
# private *private_methods
|
73
74
|
#
|
74
75
|
# end
|
75
76
|
#
|
@@ -80,6 +81,7 @@ module RuboCop
|
|
80
81
|
# private :bar, :baz
|
81
82
|
# private *%i[qux quux]
|
82
83
|
# private *METHOD_NAMES
|
84
|
+
# private *private_methods
|
83
85
|
#
|
84
86
|
# end
|
85
87
|
#
|
@@ -110,6 +112,26 @@ module RuboCop
|
|
110
112
|
# private attr :quux
|
111
113
|
#
|
112
114
|
# end
|
115
|
+
#
|
116
|
+
# @example AllowModifiersOnAliasMethod: true (default)
|
117
|
+
# # good
|
118
|
+
# class Foo
|
119
|
+
#
|
120
|
+
# public alias_method :bar, :foo
|
121
|
+
# protected alias_method :baz, :foo
|
122
|
+
# private alias_method :qux, :foo
|
123
|
+
#
|
124
|
+
# end
|
125
|
+
#
|
126
|
+
# @example AllowModifiersOnAliasMethod: false
|
127
|
+
# # bad
|
128
|
+
# class Foo
|
129
|
+
#
|
130
|
+
# public alias_method :bar, :foo
|
131
|
+
# protected alias_method :baz, :foo
|
132
|
+
# private alias_method :qux, :foo
|
133
|
+
#
|
134
|
+
# end
|
113
135
|
class AccessModifierDeclarations < Base
|
114
136
|
extend AutoCorrector
|
115
137
|
|
@@ -128,26 +150,27 @@ module RuboCop
|
|
128
150
|
|
129
151
|
RESTRICT_ON_SEND = %i[private protected public module_function].freeze
|
130
152
|
|
131
|
-
ALLOWED_NODE_TYPES = %i[pair block].freeze
|
132
|
-
|
133
153
|
# @!method access_modifier_with_symbol?(node)
|
134
154
|
def_node_matcher :access_modifier_with_symbol?, <<~PATTERN
|
135
155
|
(send nil? {:private :protected :public :module_function}
|
136
|
-
{(sym _) (splat {#percent_symbol_array? const})}
|
156
|
+
{(sym _)+ (splat {#percent_symbol_array? const send})}
|
137
157
|
)
|
138
158
|
PATTERN
|
139
159
|
|
140
160
|
# @!method access_modifier_with_attr?(node)
|
141
161
|
def_node_matcher :access_modifier_with_attr?, <<~PATTERN
|
142
162
|
(send nil? {:private :protected :public :module_function}
|
143
|
-
(send nil? {:attr :attr_reader :attr_writer :attr_accessor} _))
|
163
|
+
(send nil? {:attr :attr_reader :attr_writer :attr_accessor} _+))
|
164
|
+
PATTERN
|
165
|
+
|
166
|
+
# @!method access_modifier_with_alias_method?, <<~PATTERN
|
167
|
+
def_node_matcher :access_modifier_with_alias_method?, <<~PATTERN
|
168
|
+
(send nil? {:private :protected :public :module_function}
|
169
|
+
(send nil? :alias_method _ _))
|
144
170
|
PATTERN
|
145
171
|
|
146
172
|
def on_send(node)
|
147
|
-
return
|
148
|
-
return if ALLOWED_NODE_TYPES.include?(node.parent&.type)
|
149
|
-
return if allow_modifiers_on_symbols?(node)
|
150
|
-
return if allow_modifiers_on_attrs?(node)
|
173
|
+
return if allowed?(node)
|
151
174
|
|
152
175
|
if offense?(node)
|
153
176
|
add_offense(node.loc.selector) do |corrector|
|
@@ -161,15 +184,23 @@ module RuboCop
|
|
161
184
|
|
162
185
|
private
|
163
186
|
|
187
|
+
def allowed?(node)
|
188
|
+
!node.access_modifier? ||
|
189
|
+
node.parent&.type?(:pair, :any_block) ||
|
190
|
+
allow_modifiers_on_symbols?(node) ||
|
191
|
+
allow_modifiers_on_attrs?(node) ||
|
192
|
+
allow_modifiers_on_alias_method?(node)
|
193
|
+
end
|
194
|
+
|
164
195
|
def autocorrect(corrector, node)
|
165
196
|
case style
|
166
197
|
when :group
|
167
|
-
|
168
|
-
return unless
|
198
|
+
def_nodes = find_corresponding_def_nodes(node)
|
199
|
+
return unless def_nodes.any?
|
169
200
|
|
170
|
-
|
201
|
+
replace_defs(corrector, node, def_nodes)
|
171
202
|
when :inline
|
172
|
-
|
203
|
+
remove_nodes(corrector, node)
|
173
204
|
select_grouped_def_nodes(node).each do |grouped_def_node|
|
174
205
|
insert_inline_modifier(corrector, grouped_def_node, node.method_name)
|
175
206
|
end
|
@@ -188,12 +219,23 @@ module RuboCop
|
|
188
219
|
cop_config['AllowModifiersOnAttrs'] && access_modifier_with_attr?(node)
|
189
220
|
end
|
190
221
|
|
222
|
+
def allow_modifiers_on_alias_method?(node)
|
223
|
+
cop_config['AllowModifiersOnAliasMethod'] && access_modifier_with_alias_method?(node)
|
224
|
+
end
|
225
|
+
|
191
226
|
def offense?(node)
|
192
227
|
(group_style? && access_modifier_is_inlined?(node) &&
|
193
|
-
!right_siblings_same_inline_method?(node)) ||
|
228
|
+
!node.parent&.if_type? && !right_siblings_same_inline_method?(node)) ||
|
194
229
|
(inline_style? && access_modifier_is_not_inlined?(node))
|
195
230
|
end
|
196
231
|
|
232
|
+
def correctable_group_offense?(node)
|
233
|
+
return false unless group_style?
|
234
|
+
return false if allowed?(node)
|
235
|
+
|
236
|
+
access_modifier_is_inlined?(node) && find_corresponding_def_nodes(node).any?
|
237
|
+
end
|
238
|
+
|
197
239
|
def group_style?
|
198
240
|
style == :group
|
199
241
|
end
|
@@ -212,7 +254,11 @@ module RuboCop
|
|
212
254
|
|
213
255
|
def right_siblings_same_inline_method?(node)
|
214
256
|
node.right_siblings.any? do |sibling|
|
215
|
-
sibling.send_type? &&
|
257
|
+
sibling.send_type? &&
|
258
|
+
correctable_group_offense?(sibling) &&
|
259
|
+
sibling.method?(node.method_name) &&
|
260
|
+
!sibling.arguments.empty? &&
|
261
|
+
find_corresponding_def_nodes(sibling).any?
|
216
262
|
end
|
217
263
|
end
|
218
264
|
|
@@ -226,14 +272,22 @@ module RuboCop
|
|
226
272
|
end
|
227
273
|
end
|
228
274
|
|
229
|
-
def
|
275
|
+
def find_corresponding_def_nodes(node)
|
230
276
|
if access_modifier_with_symbol?(node)
|
231
|
-
|
232
|
-
|
233
|
-
|
277
|
+
method_names = node.arguments.filter_map do |argument|
|
278
|
+
next unless argument.sym_type?
|
279
|
+
|
280
|
+
argument.respond_to?(:value) && argument.value
|
234
281
|
end
|
282
|
+
|
283
|
+
def_nodes = node.parent.each_child_node(:def).select do |child|
|
284
|
+
method_names.include?(child.method_name)
|
285
|
+
end
|
286
|
+
|
287
|
+
# If there isn't a `def` node for each symbol, we will skip autocorrection.
|
288
|
+
def_nodes.size == method_names.size ? def_nodes : []
|
235
289
|
else
|
236
|
-
node.first_argument
|
290
|
+
[node.first_argument]
|
237
291
|
end
|
238
292
|
end
|
239
293
|
|
@@ -251,12 +305,12 @@ module RuboCop
|
|
251
305
|
end.select(&:def_type?)
|
252
306
|
end
|
253
307
|
|
254
|
-
def
|
255
|
-
source = def_source(node,
|
308
|
+
def replace_defs(corrector, node, def_nodes)
|
309
|
+
source = def_source(node, def_nodes)
|
256
310
|
argument_less_modifier_node = find_argument_less_modifier_node(node)
|
257
311
|
if argument_less_modifier_node
|
258
312
|
corrector.insert_after(argument_less_modifier_node, "\n\n#{source}")
|
259
|
-
elsif (ancestor = node.each_ancestor(:
|
313
|
+
elsif (ancestor = node.each_ancestor(:class, :module).first)
|
260
314
|
|
261
315
|
corrector.insert_before(ancestor.loc.end, "#{node.method_name}\n\n#{source}\n")
|
262
316
|
else
|
@@ -264,20 +318,24 @@ module RuboCop
|
|
264
318
|
return
|
265
319
|
end
|
266
320
|
|
267
|
-
|
268
|
-
remove_node(corrector, node)
|
321
|
+
remove_nodes(corrector, *def_nodes, node)
|
269
322
|
end
|
270
323
|
|
271
324
|
def insert_inline_modifier(corrector, node, modifier_name)
|
272
325
|
corrector.insert_before(node, "#{modifier_name} ")
|
273
326
|
end
|
274
327
|
|
275
|
-
def
|
276
|
-
|
328
|
+
def remove_nodes(corrector, *nodes)
|
329
|
+
nodes.each do |node|
|
330
|
+
corrector.remove(range_with_comments_and_lines(node))
|
331
|
+
end
|
277
332
|
end
|
278
333
|
|
279
|
-
def def_source(node,
|
280
|
-
[
|
334
|
+
def def_source(node, def_nodes)
|
335
|
+
[
|
336
|
+
*processed_source.ast_with_comments[node].map(&:text),
|
337
|
+
*def_nodes.map(&:source)
|
338
|
+
].join("\n")
|
281
339
|
end
|
282
340
|
end
|
283
341
|
end
|
@@ -139,12 +139,16 @@ module RuboCop
|
|
139
139
|
style == :separated
|
140
140
|
end
|
141
141
|
|
142
|
+
def groupable_sibling_accessor?(node, sibling)
|
143
|
+
sibling.attribute_accessor? &&
|
144
|
+
sibling.method?(node.method_name) &&
|
145
|
+
node_visibility(sibling) == node_visibility(node) &&
|
146
|
+
groupable_accessor?(sibling) && !previous_line_comment?(sibling)
|
147
|
+
end
|
148
|
+
|
142
149
|
def groupable_sibling_accessors(send_node)
|
143
150
|
send_node.parent.each_child_node(:send).select do |sibling|
|
144
|
-
|
145
|
-
sibling.method?(send_node.method_name) &&
|
146
|
-
node_visibility(sibling) == node_visibility(send_node) &&
|
147
|
-
groupable_accessor?(sibling) && !previous_line_comment?(sibling)
|
151
|
+
groupable_sibling_accessor?(send_node, sibling)
|
148
152
|
end
|
149
153
|
end
|
150
154
|
|
@@ -155,13 +159,23 @@ module RuboCop
|
|
155
159
|
|
156
160
|
def preferred_accessors(node)
|
157
161
|
if grouped_style?
|
162
|
+
return if skip_for_grouping?(node)
|
163
|
+
|
158
164
|
accessors = groupable_sibling_accessors(node)
|
159
|
-
|
165
|
+
if node.loc == accessors.first.loc || skip_for_grouping?(accessors.first)
|
166
|
+
group_accessors(node, accessors)
|
167
|
+
end
|
160
168
|
else
|
161
169
|
separate_accessors(node)
|
162
170
|
end
|
163
171
|
end
|
164
172
|
|
173
|
+
# Group after constants
|
174
|
+
def skip_for_grouping?(node)
|
175
|
+
node.right_siblings.any?(&:casgn_type?) &&
|
176
|
+
node.right_siblings.any? { |n| n.send_type? && groupable_sibling_accessor?(node, n) }
|
177
|
+
end
|
178
|
+
|
165
179
|
def group_accessors(node, accessors)
|
166
180
|
accessor_names = accessors.flat_map { |accessor| accessor.arguments.map(&:source) }.uniq
|
167
181
|
|
@@ -0,0 +1,79 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Style
|
6
|
+
# Looks for endless methods inside operations of lower precedence (`and`, `or`, and
|
7
|
+
# modifier forms of `if`, `unless`, `while`, `until`) that are ambiguous due to
|
8
|
+
# lack of parentheses. This may lead to unexpected behavior as the code may appear
|
9
|
+
# to use these keywords as part of the method but in fact they modify
|
10
|
+
# the method definition itself.
|
11
|
+
#
|
12
|
+
# In these cases, using a normal method definition is more clear.
|
13
|
+
#
|
14
|
+
# @example
|
15
|
+
#
|
16
|
+
# # bad
|
17
|
+
# def foo = true if bar
|
18
|
+
#
|
19
|
+
# # good - using a non-endless method is more explicit
|
20
|
+
# def foo
|
21
|
+
# true
|
22
|
+
# end if bar
|
23
|
+
#
|
24
|
+
# # ok - method body is explicit
|
25
|
+
# def foo = (true if bar)
|
26
|
+
#
|
27
|
+
# # ok - method definition is explicit
|
28
|
+
# (def foo = true) if bar
|
29
|
+
class AmbiguousEndlessMethodDefinition < Base
|
30
|
+
extend TargetRubyVersion
|
31
|
+
extend AutoCorrector
|
32
|
+
include EndlessMethodRewriter
|
33
|
+
include RangeHelp
|
34
|
+
|
35
|
+
minimum_target_ruby_version 3.0
|
36
|
+
|
37
|
+
MSG = 'Avoid using `%<keyword>s` statements with endless methods.'
|
38
|
+
|
39
|
+
# @!method ambiguous_endless_method_body(node)
|
40
|
+
def_node_matcher :ambiguous_endless_method_body, <<~PATTERN
|
41
|
+
^${
|
42
|
+
(if _ <def _>)
|
43
|
+
({and or} def _)
|
44
|
+
({while until} _ def)
|
45
|
+
}
|
46
|
+
PATTERN
|
47
|
+
|
48
|
+
def on_def(node)
|
49
|
+
return unless node.endless?
|
50
|
+
|
51
|
+
operation = ambiguous_endless_method_body(node)
|
52
|
+
return unless operation
|
53
|
+
|
54
|
+
return unless modifier_form?(operation)
|
55
|
+
|
56
|
+
add_offense(operation, message: format(MSG, keyword: keyword(operation))) do |corrector|
|
57
|
+
correct_to_multiline(corrector, node)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
def modifier_form?(operation)
|
64
|
+
return true if operation.operator_keyword?
|
65
|
+
|
66
|
+
operation.modifier_form?
|
67
|
+
end
|
68
|
+
|
69
|
+
def keyword(operation)
|
70
|
+
if operation.respond_to?(:keyword)
|
71
|
+
operation.keyword
|
72
|
+
else
|
73
|
+
operation.operator
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -31,6 +31,20 @@ module RuboCop
|
|
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)
|
@@ -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
|
@@ -191,9 +205,7 @@ module RuboCop
|
|
191
205
|
|
192
206
|
send_classifications.each do |send_node, c, forward_rest, forward_kwrest, forward_block_arg| # rubocop:disable Layout/LineLength
|
193
207
|
if !forward_rest && !forward_kwrest && c != :all_anonymous
|
194
|
-
|
195
|
-
# in Ruby 3.3.0.
|
196
|
-
if outside_block?(forward_block_arg)
|
208
|
+
if allow_anonymous_forwarding_in_block?(forward_block_arg)
|
197
209
|
register_forward_block_arg_offense(!forward_rest, node.arguments, block_arg)
|
198
210
|
register_forward_block_arg_offense(!forward_rest, send_node, forward_block_arg)
|
199
211
|
end
|
@@ -214,24 +226,22 @@ module RuboCop
|
|
214
226
|
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
215
227
|
def add_post_ruby_32_offenses(def_node, send_classifications, forwardable_args)
|
216
228
|
return unless use_anonymous_forwarding?
|
217
|
-
return
|
229
|
+
return unless all_forwarding_offenses_correctable?(send_classifications)
|
218
230
|
|
219
231
|
rest_arg, kwrest_arg, block_arg = *forwardable_args
|
220
232
|
|
221
233
|
send_classifications.each do |send_node, _c, forward_rest, forward_kwrest, forward_block_arg| # rubocop:disable Layout/LineLength
|
222
|
-
if
|
234
|
+
if allow_anonymous_forwarding_in_block?(forward_rest)
|
223
235
|
register_forward_args_offense(def_node.arguments, rest_arg)
|
224
236
|
register_forward_args_offense(send_node, forward_rest)
|
225
237
|
end
|
226
238
|
|
227
|
-
if
|
239
|
+
if allow_anonymous_forwarding_in_block?(forward_kwrest)
|
228
240
|
register_forward_kwargs_offense(!forward_rest, def_node.arguments, kwrest_arg)
|
229
241
|
register_forward_kwargs_offense(!forward_rest, send_node, forward_kwrest)
|
230
242
|
end
|
231
243
|
|
232
|
-
|
233
|
-
# in Ruby 3.3.0.
|
234
|
-
if outside_block?(forward_block_arg)
|
244
|
+
if allow_anonymous_forwarding_in_block?(forward_block_arg)
|
235
245
|
register_forward_block_arg_offense(!forward_rest, def_node.arguments, block_arg)
|
236
246
|
register_forward_block_arg_offense(!forward_rest, send_node, forward_block_arg)
|
237
247
|
end
|
@@ -293,10 +303,25 @@ module RuboCop
|
|
293
303
|
redundant_arg_names.include?(arg.source) ? arg : nil
|
294
304
|
end
|
295
305
|
|
296
|
-
|
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)
|
297
321
|
return false unless node
|
322
|
+
return true if target_ruby_version >= 3.4
|
298
323
|
|
299
|
-
node.each_ancestor(:
|
324
|
+
node.each_ancestor(:any_block).none?
|
300
325
|
end
|
301
326
|
|
302
327
|
def register_forward_args_offense(def_arguments_or_send, rest_arg_or_splat)
|
@@ -357,12 +382,6 @@ module RuboCop
|
|
357
382
|
cop_config.fetch('UseAnonymousForwarding', false)
|
358
383
|
end
|
359
384
|
|
360
|
-
def send_inside_block?(send_classifications)
|
361
|
-
send_classifications.any? do |send_node, *|
|
362
|
-
send_node.each_ancestor(:block, :numblock).any?
|
363
|
-
end
|
364
|
-
end
|
365
|
-
|
366
385
|
def add_parens_if_missing(node, corrector)
|
367
386
|
return if parentheses?(node)
|
368
387
|
return if node.send_type? && node.method?(:[])
|
@@ -511,7 +530,7 @@ module RuboCop
|
|
511
530
|
end
|
512
531
|
|
513
532
|
def additional_kwargs?
|
514
|
-
@def_node.arguments.any? { |a| a.
|
533
|
+
@def_node.arguments.any? { |a| a.type?(:kwarg, :kwoptarg) }
|
515
534
|
end
|
516
535
|
|
517
536
|
def forward_additional_kwargs?
|
@@ -540,10 +559,7 @@ module RuboCop
|
|
540
559
|
end
|
541
560
|
|
542
561
|
def explicit_block_name?
|
543
|
-
|
544
|
-
return false unless block_forwarding_config['Enabled']
|
545
|
-
|
546
|
-
block_forwarding_config['EnforcedStyle'] == 'explicit'
|
562
|
+
config.for_enabled_cop('Naming/BlockForwarding')['EnforcedStyle'] == 'explicit'
|
547
563
|
end
|
548
564
|
end
|
549
565
|
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
|
@@ -28,6 +28,7 @@ module RuboCop
|
|
28
28
|
# # bad
|
29
29
|
# (array1 & array2).any?
|
30
30
|
# (array1 & array2).empty?
|
31
|
+
# (array1 & array2).none?
|
31
32
|
#
|
32
33
|
# # good
|
33
34
|
# array1.intersect?(array2)
|
@@ -57,7 +58,7 @@ module RuboCop
|
|
57
58
|
(send
|
58
59
|
(begin
|
59
60
|
(send $(...) :& $(...))
|
60
|
-
) ${:any? :empty?}
|
61
|
+
) ${:any? :empty? :none?}
|
61
62
|
)
|
62
63
|
PATTERN
|
63
64
|
|
@@ -66,18 +67,18 @@ module RuboCop
|
|
66
67
|
(send
|
67
68
|
(begin
|
68
69
|
(send $(...) :& $(...))
|
69
|
-
) ${:present? :any? :blank? :empty?}
|
70
|
+
) ${:present? :any? :blank? :empty? :none?}
|
70
71
|
)
|
71
72
|
PATTERN
|
72
73
|
|
73
74
|
MSG = 'Use `%<negated>s%<receiver>s.intersect?(%<argument>s)` ' \
|
74
75
|
'instead of `(%<receiver>s & %<argument>s).%<method_name>s`.'
|
75
76
|
STRAIGHT_METHODS = %i[present? any?].freeze
|
76
|
-
NEGATED_METHODS = %i[blank? empty?].freeze
|
77
|
+
NEGATED_METHODS = %i[blank? empty? none?].freeze
|
77
78
|
RESTRICT_ON_SEND = (STRAIGHT_METHODS + NEGATED_METHODS).freeze
|
78
79
|
|
79
80
|
def on_send(node)
|
80
|
-
return if
|
81
|
+
return if node.block_literal?
|
81
82
|
return unless (receiver, argument, method_name = bad_intersection_check?(node))
|
82
83
|
|
83
84
|
message = message(receiver.source, argument.source, method_name)
|
@@ -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
|