rubocop 1.66.1 → 1.72.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/LICENSE.txt +1 -1
- data/README.md +2 -2
- data/config/default.yml +162 -14
- data/config/internal_affairs.yml +11 -0
- 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/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 +36 -11
- data/lib/rubocop/config_validator.rb +20 -9
- data/lib/rubocop/cop/autocorrect_logic.rb +36 -19
- data/lib/rubocop/cop/base.rb +13 -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/parentheses_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_description.rb +0 -4
- 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_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 +7 -1
- data/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +0 -5
- data/lib/rubocop/cop/internal_affairs.rb +6 -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 +3 -2
- data/lib/rubocop/cop/layout/class_structure.rb +9 -9
- data/lib/rubocop/cop/layout/def_end_alignment.rb +1 -1
- 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 +3 -3
- data/lib/rubocop/cop/layout/empty_line_between_defs.rb +7 -11
- data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +3 -3
- 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_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 +6 -4
- data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +2 -1
- data/lib/rubocop/cop/layout/indentation_width.rb +11 -12
- data/lib/rubocop/cop/layout/leading_comment_space.rb +71 -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/ambiguous_range.rb +4 -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/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 +1 -1
- 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_regexp_character_class_element.rb +1 -1
- data/lib/rubocop/cop/lint/duplicate_set_element.rb +87 -0
- 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 -1
- data/lib/rubocop/cop/lint/float_comparison.rb +20 -9
- 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 +11 -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 +1 -0
- 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_super.rb +2 -2
- data/lib/rubocop/cop/lint/mixed_case_range.rb +3 -6
- 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 +6 -11
- 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_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 +231 -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 +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/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 +2 -2
- 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/uri_regexp.rb +25 -7
- 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 +8 -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 +188 -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_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 +3 -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 +1 -1
- data/lib/rubocop/cop/mixin/target_ruby_version.rb +17 -1
- data/lib/rubocop/cop/mixin/trailing_comma.rb +3 -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/inclusive_language.rb +12 -3
- data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +11 -12
- data/lib/rubocop/cop/naming/predicate_name.rb +45 -1
- data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +6 -14
- data/lib/rubocop/cop/naming/variable_name.rb +3 -4
- data/lib/rubocop/cop/naming/variable_number.rb +2 -3
- data/lib/rubocop/cop/offense.rb +4 -5
- 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 +10 -2
- 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 +78 -22
- 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 +49 -19
- 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_compact.rb +10 -10
- 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 +9 -2
- data/lib/rubocop/cop/style/commented_keyword.rb +17 -1
- data/lib/rubocop/cop/style/concat_array_literals.rb +1 -1
- data/lib/rubocop/cop/style/conditional_assignment.rb +26 -26
- data/lib/rubocop/cop/style/constant_visibility.rb +3 -12
- data/lib/rubocop/cop/style/data_inheritance.rb +1 -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 +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 +1 -14
- data/lib/rubocop/cop/style/eval_with_location.rb +2 -2
- 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 +16 -3
- data/lib/rubocop/cop/style/hash_conversion.rb +1 -2
- data/lib/rubocop/cop/style/hash_each_methods.rb +9 -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 +8 -5
- data/lib/rubocop/cop/style/identical_conditional_branches.rb +22 -3
- data/lib/rubocop/cop/style/if_inside_else.rb +1 -2
- 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 +26 -11
- 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.rb +1 -1
- data/lib/rubocop/cop/style/lambda_call.rb +3 -2
- data/lib/rubocop/cop/style/map_into_array.rb +60 -9
- 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 +32 -20
- 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 +2 -2
- 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_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/not.rb +1 -1
- data/lib/rubocop/cop/style/object_then.rb +14 -15
- data/lib/rubocop/cop/style/one_line_conditional.rb +29 -4
- 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 +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 +5 -1
- data/lib/rubocop/cop/style/redundant_condition.rb +39 -24
- 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 +238 -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 +56 -17
- data/lib/rubocop/cop/style/redundant_parentheses.rb +37 -25
- 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/require_order.rb +1 -1
- data/lib/rubocop/cop/style/rescue_modifier.rb +15 -4
- data/lib/rubocop/cop/style/return_nil.rb +1 -1
- data/lib/rubocop/cop/style/return_nil_in_predicate_method_definition.rb +54 -12
- data/lib/rubocop/cop/style/safe_navigation.rb +105 -51
- data/lib/rubocop/cop/style/safe_navigation_chain_length.rb +52 -0
- data/lib/rubocop/cop/style/select_by_regexp.rb +10 -7
- 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 +12 -3
- data/lib/rubocop/cop/style/single_line_methods.rb +3 -4
- 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 +14 -13
- 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 +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 +26 -5
- 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_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/team.rb +8 -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 +100 -51
- data/lib/rubocop/directive_comment.rb +44 -10
- data/lib/rubocop/file_finder.rb +9 -4
- 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 +18 -48
- data/lib/rubocop/lsp/server.rb +0 -3
- 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 +39 -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 +7 -2
- data/lib/rubocop/rspec/shared_contexts.rb +4 -1
- data/lib/rubocop/rspec/support.rb +1 -2
- data/lib/rubocop/runner.rb +22 -12
- data/lib/rubocop/server/cache.rb +39 -1
- data/lib/rubocop/server/cli.rb +2 -2
- data/lib/rubocop/server/core.rb +1 -0
- data/lib/rubocop/target_finder.rb +1 -0
- data/lib/rubocop/target_ruby.rb +28 -13
- data/lib/rubocop/version.rb +42 -6
- data/lib/rubocop/yaml_duplication_checker.rb +20 -27
- data/lib/rubocop.rb +29 -0
- data/lib/ruby_lsp/rubocop/addon.rb +75 -0
- data/lib/ruby_lsp/rubocop/runtime_adapter.rb +47 -0
- metadata +75 -19
- data/lib/rubocop/rspec/host_environment_simulation_helper.rb +0 -28
@@ -0,0 +1,80 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Style
|
6
|
+
# Checks for usages of `Hash#reject`, `Hash#select`, and `Hash#filter` methods
|
7
|
+
# that can be replaced with `Hash#slice` method.
|
8
|
+
#
|
9
|
+
# This cop should only be enabled on Ruby version 2.5 or higher.
|
10
|
+
# (`Hash#slice` was added in Ruby 2.5.)
|
11
|
+
#
|
12
|
+
# For safe detection, it is limited to commonly used string and symbol comparisons
|
13
|
+
# when using `==` or `!=`.
|
14
|
+
#
|
15
|
+
# This cop doesn't check for `Hash#delete_if` and `Hash#keep_if` because they
|
16
|
+
# modify the receiver.
|
17
|
+
#
|
18
|
+
# @safety
|
19
|
+
# This cop is unsafe because it cannot be guaranteed that the receiver
|
20
|
+
# is a `Hash` or responds to the replacement method.
|
21
|
+
#
|
22
|
+
# @example
|
23
|
+
#
|
24
|
+
# # bad
|
25
|
+
# {foo: 1, bar: 2, baz: 3}.select {|k, v| k == :bar }
|
26
|
+
# {foo: 1, bar: 2, baz: 3}.reject {|k, v| k != :bar }
|
27
|
+
# {foo: 1, bar: 2, baz: 3}.filter {|k, v| k == :bar }
|
28
|
+
# {foo: 1, bar: 2, baz: 3}.select {|k, v| k.eql?(:bar) }
|
29
|
+
#
|
30
|
+
# # bad
|
31
|
+
# {foo: 1, bar: 2, baz: 3}.select {|k, v| %i[bar].include?(k) }
|
32
|
+
# {foo: 1, bar: 2, baz: 3}.reject {|k, v| !%i[bar].include?(k) }
|
33
|
+
# {foo: 1, bar: 2, baz: 3}.filter {|k, v| %i[bar].include?(k) }
|
34
|
+
#
|
35
|
+
# # good
|
36
|
+
# {foo: 1, bar: 2, baz: 3}.slice(:bar)
|
37
|
+
#
|
38
|
+
# @example AllCops:ActiveSupportExtensionsEnabled: false (default)
|
39
|
+
#
|
40
|
+
# # good
|
41
|
+
# {foo: 1, bar: 2, baz: 3}.select {|k, v| !%i[bar].exclude?(k) }
|
42
|
+
# {foo: 1, bar: 2, baz: 3}.reject {|k, v| %i[bar].exclude?(k) }
|
43
|
+
#
|
44
|
+
# # good
|
45
|
+
# {foo: 1, bar: 2, baz: 3}.select {|k, v| k.in?(%i[bar]) }
|
46
|
+
# {foo: 1, bar: 2, baz: 3}.reject {|k, v| !k.in?(%i[bar]) }
|
47
|
+
#
|
48
|
+
# @example AllCops:ActiveSupportExtensionsEnabled: true
|
49
|
+
#
|
50
|
+
# # bad
|
51
|
+
# {foo: 1, bar: 2, baz: 3}.select {|k, v| !%i[bar].exclude?(k) }
|
52
|
+
# {foo: 1, bar: 2, baz: 3}.reject {|k, v| %i[bar].exclude?(k) }
|
53
|
+
#
|
54
|
+
# # bad
|
55
|
+
# {foo: 1, bar: 2, baz: 3}.select {|k, v| k.in?(%i[bar]) }
|
56
|
+
# {foo: 1, bar: 2, baz: 3}.reject {|k, v| !k.in?(%i[bar]) }
|
57
|
+
#
|
58
|
+
# # good
|
59
|
+
# {foo: 1, bar: 2, baz: 3}.slice(:bar)
|
60
|
+
#
|
61
|
+
class HashSlice < Base
|
62
|
+
include HashSubset
|
63
|
+
extend TargetRubyVersion
|
64
|
+
extend AutoCorrector
|
65
|
+
|
66
|
+
minimum_target_ruby_version 2.5
|
67
|
+
|
68
|
+
private
|
69
|
+
|
70
|
+
def semantically_subset_method?(node)
|
71
|
+
semantically_slice_method?(node)
|
72
|
+
end
|
73
|
+
|
74
|
+
def preferred_method_name
|
75
|
+
'slice'
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -68,7 +68,7 @@ module RuboCop
|
|
68
68
|
# {a: 1, b: 2}
|
69
69
|
# {:c => 3, 'd' => 4}
|
70
70
|
#
|
71
|
-
# @example EnforcedShorthandSyntax: always
|
71
|
+
# @example EnforcedShorthandSyntax: always
|
72
72
|
#
|
73
73
|
# # bad
|
74
74
|
# {foo: foo, bar: bar}
|
@@ -84,7 +84,7 @@ module RuboCop
|
|
84
84
|
# # good
|
85
85
|
# {foo: foo, bar: bar}
|
86
86
|
#
|
87
|
-
# @example EnforcedShorthandSyntax: either
|
87
|
+
# @example EnforcedShorthandSyntax: either (default)
|
88
88
|
#
|
89
89
|
# # good
|
90
90
|
# {foo: foo, bar: bar}
|
@@ -137,6 +137,7 @@ module RuboCop
|
|
137
137
|
MSG_19 = 'Use the new Ruby 1.9 hash syntax.'
|
138
138
|
MSG_NO_MIXED_KEYS = "Don't mix styles in the same hash."
|
139
139
|
MSG_HASH_ROCKETS = 'Use hash rockets syntax.'
|
140
|
+
NO_MIXED_KEYS_STYLES = %i[ruby19_no_mixed_keys no_mixed_keys].freeze
|
140
141
|
|
141
142
|
def on_hash(node)
|
142
143
|
pairs = node.pairs
|
@@ -196,7 +197,7 @@ module RuboCop
|
|
196
197
|
def autocorrect(corrector, node)
|
197
198
|
if style == :hash_rockets || force_hash_rockets?(node.parent.pairs)
|
198
199
|
autocorrect_hash_rockets(corrector, node)
|
199
|
-
elsif style
|
200
|
+
elsif NO_MIXED_KEYS_STYLES.include?(style)
|
200
201
|
autocorrect_no_mixed_keys(corrector, node)
|
201
202
|
else
|
202
203
|
autocorrect_ruby19(corrector, node)
|
@@ -208,7 +209,7 @@ module RuboCop
|
|
208
209
|
end
|
209
210
|
|
210
211
|
def word_symbol_pair?(pair)
|
211
|
-
return false unless pair.key.
|
212
|
+
return false unless pair.key.type?(:sym, :dsym)
|
212
213
|
|
213
214
|
acceptable_19_syntax_symbol?(pair.key.source)
|
214
215
|
end
|
@@ -272,7 +273,9 @@ module RuboCop
|
|
272
273
|
end
|
273
274
|
|
274
275
|
def argument_without_space?(node)
|
275
|
-
node.argument?
|
276
|
+
return false if !node.argument? || !node.parent.loc.selector
|
277
|
+
|
278
|
+
node.source_range.begin_pos == node.parent.loc.selector.end_pos
|
276
279
|
end
|
277
280
|
|
278
281
|
def autocorrect_hash_rockets(corrector, pair_node)
|
@@ -203,17 +203,36 @@ module RuboCop
|
|
203
203
|
corrector.remove(range)
|
204
204
|
next if inserted_expression
|
205
205
|
|
206
|
-
if
|
207
|
-
corrector
|
206
|
+
if node.parent&.assignment?
|
207
|
+
correct_assignment(corrector, node, expression, insert_position)
|
208
208
|
else
|
209
|
-
corrector
|
209
|
+
correct_no_assignment(corrector, node, expression, insert_position)
|
210
210
|
end
|
211
|
+
|
211
212
|
inserted_expression = true
|
212
213
|
end
|
213
214
|
end
|
214
215
|
end
|
215
216
|
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
216
217
|
|
218
|
+
def correct_assignment(corrector, node, expression, insert_position)
|
219
|
+
if insert_position == :after_condition
|
220
|
+
assignment = node.parent.source_range.with(end_pos: node.source_range.begin_pos)
|
221
|
+
corrector.remove(assignment)
|
222
|
+
corrector.insert_after(node, "\n#{assignment.source}#{expression.source}")
|
223
|
+
else
|
224
|
+
corrector.insert_before(node.parent, "#{expression.source}\n")
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
def correct_no_assignment(corrector, node, expression, insert_position)
|
229
|
+
if insert_position == :after_condition
|
230
|
+
corrector.insert_after(node, "\n#{expression.source}")
|
231
|
+
else
|
232
|
+
corrector.insert_before(node, "#{expression.source}\n")
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
217
236
|
def last_child_of_parent?(node)
|
218
237
|
return true unless (parent = node.parent)
|
219
238
|
|
@@ -59,7 +59,6 @@ module RuboCop
|
|
59
59
|
# end
|
60
60
|
#
|
61
61
|
class IfInsideElse < Base
|
62
|
-
include IgnoredNode
|
63
62
|
include RangeHelp
|
64
63
|
extend AutoCorrector
|
65
64
|
|
@@ -71,7 +70,7 @@ module RuboCop
|
|
71
70
|
|
72
71
|
else_branch = node.else_branch
|
73
72
|
|
74
|
-
return unless else_branch&.if_type? && else_branch
|
73
|
+
return unless else_branch&.if_type? && else_branch.if?
|
75
74
|
return if allow_if_modifier_in_else_branch?(else_branch)
|
76
75
|
|
77
76
|
add_offense(else_branch.loc.keyword) do |corrector|
|
@@ -103,7 +103,7 @@ module RuboCop
|
|
103
103
|
|
104
104
|
def defined_argument_is_undefined?(if_node, defined_node)
|
105
105
|
defined_argument = defined_node.first_argument
|
106
|
-
return false unless defined_argument.
|
106
|
+
return false unless defined_argument.type?(:lvar, :send)
|
107
107
|
|
108
108
|
if_node.left_siblings.none? do |sibling|
|
109
109
|
sibling.respond_to?(:lvasgn_type?) && sibling.lvasgn_type? &&
|
@@ -112,11 +112,11 @@ module RuboCop
|
|
112
112
|
end
|
113
113
|
|
114
114
|
def pattern_matching_nodes(condition)
|
115
|
-
if condition.
|
115
|
+
if condition.type?(:match_pattern, :match_pattern_p)
|
116
116
|
[condition]
|
117
117
|
else
|
118
118
|
condition.each_descendant.select do |node|
|
119
|
-
node.
|
119
|
+
node.type?(:match_pattern, :match_pattern_p)
|
120
120
|
end
|
121
121
|
end
|
122
122
|
end
|
@@ -67,7 +67,7 @@ module RuboCop
|
|
67
67
|
|
68
68
|
# @!method if_with_boolean_literal_branches?(node)
|
69
69
|
def_node_matcher :if_with_boolean_literal_branches?, <<~PATTERN
|
70
|
-
(if #return_boolean_value?
|
70
|
+
(if #return_boolean_value? <true false>)
|
71
71
|
PATTERN
|
72
72
|
# @!method double_negative?(node)
|
73
73
|
def_node_matcher :double_negative?, '(send (send _ :!) :!)'
|
@@ -155,8 +155,7 @@ module RuboCop
|
|
155
155
|
end
|
156
156
|
|
157
157
|
def require_parentheses?(condition)
|
158
|
-
condition.
|
159
|
-
(condition.send_type? && condition.comparison_method?)
|
158
|
+
condition.operator_keyword? || (condition.send_type? && condition.comparison_method?)
|
160
159
|
end
|
161
160
|
end
|
162
161
|
end
|
@@ -23,6 +23,7 @@ module RuboCop
|
|
23
23
|
|
24
24
|
def on_normal_if_unless(node)
|
25
25
|
return if node.parent&.if_type?
|
26
|
+
return if part_of_ignored_node?(node)
|
26
27
|
|
27
28
|
beginning = node.loc.begin
|
28
29
|
return unless beginning&.is?(';')
|
@@ -32,16 +33,17 @@ module RuboCop
|
|
32
33
|
add_offense(node, message: message) do |corrector|
|
33
34
|
autocorrect(corrector, node)
|
34
35
|
end
|
36
|
+
|
37
|
+
ignore_node(node)
|
35
38
|
end
|
36
39
|
|
37
40
|
private
|
38
41
|
|
39
|
-
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
40
42
|
def message(node)
|
41
|
-
template = if node
|
43
|
+
template = if require_newline?(node)
|
42
44
|
MSG_NEWLINE
|
43
|
-
elsif node.else_branch&.
|
44
|
-
|
45
|
+
elsif node.else_branch&.type?(:if, :begin) ||
|
46
|
+
use_masgn_or_block_in_branches?(node)
|
45
47
|
MSG_IF_ELSE
|
46
48
|
else
|
47
49
|
MSG_TERNARY
|
@@ -49,18 +51,27 @@ module RuboCop
|
|
49
51
|
|
50
52
|
format(template, expr: node.condition.source)
|
51
53
|
end
|
52
|
-
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
53
54
|
|
54
55
|
def autocorrect(corrector, node)
|
55
|
-
if
|
56
|
+
if require_newline?(node) || use_masgn_or_block_in_branches?(node)
|
56
57
|
corrector.replace(node.loc.begin, "\n")
|
57
58
|
else
|
58
59
|
corrector.replace(node, replacement(node))
|
59
60
|
end
|
60
61
|
end
|
61
62
|
|
62
|
-
def
|
63
|
-
node.branches.compact.any?
|
63
|
+
def require_newline?(node)
|
64
|
+
node.branches.compact.any?(&:begin_type?) || use_return_with_argument?(node)
|
65
|
+
end
|
66
|
+
|
67
|
+
def use_masgn_or_block_in_branches?(node)
|
68
|
+
node.branches.compact.any? do |branch|
|
69
|
+
branch.type?(:masgn, :any_block)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def use_return_with_argument?(node)
|
74
|
+
node.if_branch&.return_type? && node.if_branch&.arguments&.any?
|
64
75
|
end
|
65
76
|
|
66
77
|
def replacement(node)
|
@@ -81,16 +92,14 @@ module RuboCop
|
|
81
92
|
RUBY
|
82
93
|
end
|
83
94
|
|
84
|
-
# rubocop:disable Metrics/AbcSize
|
85
95
|
def build_expression(expr)
|
86
|
-
return expr.source
|
96
|
+
return expr.source unless require_argument_parentheses?(expr)
|
87
97
|
|
88
98
|
method = expr.source_range.begin.join(expr.loc.selector.end)
|
89
99
|
arguments = expr.first_argument.source_range.begin.join(expr.source_range.end)
|
90
100
|
|
91
101
|
"#{method.source}(#{arguments.source})"
|
92
102
|
end
|
93
|
-
# rubocop:enable Metrics/AbcSize
|
94
103
|
|
95
104
|
def build_else_branch(second_condition)
|
96
105
|
result = <<~RUBY
|
@@ -111,6 +120,12 @@ module RuboCop
|
|
111
120
|
|
112
121
|
result
|
113
122
|
end
|
123
|
+
|
124
|
+
def require_argument_parentheses?(node)
|
125
|
+
return false if !node.call_type? || node.arithmetic_operation?
|
126
|
+
|
127
|
+
!node.parenthesized? && node.arguments.any? && !node.method?(:[]) && !node.method?(:[]=)
|
128
|
+
end
|
114
129
|
end
|
115
130
|
end
|
116
131
|
end
|
@@ -68,7 +68,7 @@ module RuboCop
|
|
68
68
|
end
|
69
69
|
|
70
70
|
def autocorrect(corrector, node)
|
71
|
-
if node.
|
71
|
+
if node.type?(:while_post, :until_post)
|
72
72
|
replace_begin_end_with_modifier(corrector, node)
|
73
73
|
elsif node.modifier_form?
|
74
74
|
replace_source(corrector, node.source_range, modifier_replacement(node))
|
@@ -41,7 +41,6 @@ module RuboCop
|
|
41
41
|
# f != 1
|
42
42
|
# end
|
43
43
|
class InverseMethods < Base
|
44
|
-
include IgnoredNode
|
45
44
|
include RangeHelp
|
46
45
|
extend AutoCorrector
|
47
46
|
|
@@ -61,18 +60,18 @@ module RuboCop
|
|
61
60
|
def_node_matcher :inverse_candidate?, <<~PATTERN
|
62
61
|
{
|
63
62
|
(send $(call $(...) $_ $...) :!)
|
64
|
-
(send (
|
63
|
+
(send (any_block $(call $(...) $_) $...) :!)
|
65
64
|
(send (begin $(call $(...) $_ $...)) :!)
|
66
65
|
}
|
67
66
|
PATTERN
|
68
67
|
|
69
68
|
# @!method inverse_block?(node)
|
70
69
|
def_node_matcher :inverse_block?, <<~PATTERN
|
71
|
-
(
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
70
|
+
(any_block $(call (...) $_) ... { $(call ... :!)
|
71
|
+
$(send (...) {:!= :!~} ...)
|
72
|
+
(begin ... $(call ... :!))
|
73
|
+
(begin ... $(send (...) {:!= :!~} ...))
|
74
|
+
})
|
76
75
|
PATTERN
|
77
76
|
|
78
77
|
def on_send(node)
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Style
|
6
|
+
# Checks for assignments to a local `it` variable inside a block
|
7
|
+
# where `it` can refer to the first anonymous parameter as of Ruby 3.4.
|
8
|
+
#
|
9
|
+
# Although Ruby allows reassigning `it` in these cases, it could
|
10
|
+
# cause confusion if `it` is used as a block parameter elsewhere.
|
11
|
+
# For consistency, this also applies to numblocks and blocks with
|
12
|
+
# parameters, even though `it` cannot be used in those cases.
|
13
|
+
#
|
14
|
+
# @example
|
15
|
+
# # bad
|
16
|
+
# foo { it = 5 }
|
17
|
+
# foo { |bar| it = bar }
|
18
|
+
# foo { it = _2 }
|
19
|
+
#
|
20
|
+
# # good - use a different variable name
|
21
|
+
# foo { var = 5 }
|
22
|
+
# foo { |bar| var = bar }
|
23
|
+
# foo { bar = _2 }
|
24
|
+
class ItAssignment < Base
|
25
|
+
MSG = '`it` is the default block parameter; consider another name.'
|
26
|
+
|
27
|
+
def on_lvasgn(node)
|
28
|
+
return unless node.name == :it
|
29
|
+
return unless node.each_ancestor(:any_block).any?
|
30
|
+
|
31
|
+
add_offense(node.loc.name)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Style
|
6
|
+
# When passing an existing hash as keyword arguments, provide additional arguments
|
7
|
+
# directly rather than using `merge`.
|
8
|
+
#
|
9
|
+
# Providing arguments directly is more performant than using `merge`, and
|
10
|
+
# also leads to shorter and simpler code.
|
11
|
+
#
|
12
|
+
# @example
|
13
|
+
# # bad
|
14
|
+
# some_method(**opts.merge(foo: true))
|
15
|
+
# some_method(**opts.merge(other_opts))
|
16
|
+
#
|
17
|
+
# # good
|
18
|
+
# some_method(**opts, foo: true)
|
19
|
+
# some_method(**opts, **other_opts)
|
20
|
+
#
|
21
|
+
class KeywordArgumentsMerging < Base
|
22
|
+
extend AutoCorrector
|
23
|
+
|
24
|
+
MSG = 'Provide additional arguments directly rather than using `merge`.'
|
25
|
+
|
26
|
+
# @!method merge_kwargs?(node)
|
27
|
+
def_node_matcher :merge_kwargs?, <<~PATTERN
|
28
|
+
(send _ _
|
29
|
+
...
|
30
|
+
(hash
|
31
|
+
(kwsplat
|
32
|
+
$(send $_ :merge $...))
|
33
|
+
...))
|
34
|
+
PATTERN
|
35
|
+
|
36
|
+
def on_kwsplat(node)
|
37
|
+
return unless (ancestor = node.parent&.parent)
|
38
|
+
|
39
|
+
merge_kwargs?(ancestor) do |merge_node, hash_node, other_hash_node|
|
40
|
+
add_offense(merge_node) do |corrector|
|
41
|
+
autocorrect(corrector, node, hash_node, other_hash_node)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def autocorrect(corrector, kwsplat_node, hash_node, other_hash_node)
|
49
|
+
other_hash_node_replacement =
|
50
|
+
other_hash_node.map do |node|
|
51
|
+
if node.hash_type?
|
52
|
+
if node.braces?
|
53
|
+
node.source[1...-1]
|
54
|
+
else
|
55
|
+
node.source
|
56
|
+
end
|
57
|
+
else
|
58
|
+
"**#{node.source}"
|
59
|
+
end
|
60
|
+
end.join(', ')
|
61
|
+
|
62
|
+
corrector.replace(kwsplat_node, "**#{hash_node.source}, #{other_hash_node_replacement}")
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -57,7 +57,7 @@ module RuboCop
|
|
57
57
|
|
58
58
|
def append_newline_to_last_kwoptarg(arguments, corrector)
|
59
59
|
last_argument = arguments.last
|
60
|
-
return if last_argument.
|
60
|
+
return if last_argument.type?(:kwrestarg, :blockarg)
|
61
61
|
|
62
62
|
last_kwoptarg = arguments.reverse.find(&:kwoptarg_type?)
|
63
63
|
corrector.insert_after(last_kwoptarg, "\n") unless arguments.parent.block_type?
|
@@ -68,7 +68,7 @@ module RuboCop
|
|
68
68
|
|
69
69
|
return unless offending_selector?(node, selector)
|
70
70
|
|
71
|
-
add_offense(node.send_node
|
71
|
+
add_offense(node.send_node, message: message(node, selector)) do |corrector|
|
72
72
|
if node.send_node.lambda_literal?
|
73
73
|
LambdaLiteralToMethodCorrector.new(node).call(corrector)
|
74
74
|
else
|
@@ -20,7 +20,6 @@ module RuboCop
|
|
20
20
|
# lambda.(x, y)
|
21
21
|
class LambdaCall < Base
|
22
22
|
include ConfigurableEnforcedStyle
|
23
|
-
include IgnoredNode
|
24
23
|
extend AutoCorrector
|
25
24
|
|
26
25
|
MSG = 'Prefer the use of `%<prefer>s` over `%<current>s`.'
|
@@ -45,6 +44,7 @@ module RuboCop
|
|
45
44
|
correct_style_detected
|
46
45
|
end
|
47
46
|
end
|
47
|
+
alias on_csend on_send
|
48
48
|
|
49
49
|
private
|
50
50
|
|
@@ -55,9 +55,10 @@ module RuboCop
|
|
55
55
|
def prefer(node)
|
56
56
|
receiver = node.receiver.source
|
57
57
|
arguments = node.arguments.map(&:source).join(', ')
|
58
|
+
dot = node.loc.dot.source
|
58
59
|
method = explicit_style? ? "call(#{arguments})" : "(#{arguments})"
|
59
60
|
|
60
|
-
"#{receiver}
|
61
|
+
"#{receiver}#{dot}#{method}"
|
61
62
|
end
|
62
63
|
|
63
64
|
def implicit_style?
|
@@ -13,8 +13,10 @@ module RuboCop
|
|
13
13
|
# return value of `Enumerable#map` is an `Array`. They are not autocorrected
|
14
14
|
# when a return value could be used because these types differ.
|
15
15
|
#
|
16
|
-
# NOTE: It only detects when the mapping destination is
|
17
|
-
# initialized as an empty array and referred to only by the
|
16
|
+
# NOTE: It only detects when the mapping destination is either:
|
17
|
+
# * a local variable initialized as an empty array and referred to only by the
|
18
|
+
# pushing operation;
|
19
|
+
# * or, if it is the single block argument to a `[].tap` block.
|
18
20
|
# This is because, if not, it's challenging to statically guarantee that the
|
19
21
|
# mapping destination variable remains an empty array:
|
20
22
|
#
|
@@ -42,6 +44,14 @@ module RuboCop
|
|
42
44
|
# # good
|
43
45
|
# dest = src.map { |e| e * 2 }
|
44
46
|
#
|
47
|
+
# # bad
|
48
|
+
# [].tap do |dest|
|
49
|
+
# src.each { |e| dest << e * 2 }
|
50
|
+
# end
|
51
|
+
#
|
52
|
+
# # good
|
53
|
+
# dest = src.map { |e| e * 2 }
|
54
|
+
#
|
45
55
|
# # good - contains another operation
|
46
56
|
# dest = []
|
47
57
|
# src.each { |e| dest << e * 2; puts e }
|
@@ -53,12 +63,17 @@ module RuboCop
|
|
53
63
|
|
54
64
|
MSG = 'Use `%<new_method_name>s` instead of `each` to map elements into an array.'
|
55
65
|
|
66
|
+
# @!method suitable_argument_node?(node)
|
67
|
+
def_node_matcher :suitable_argument_node?, <<-PATTERN
|
68
|
+
!{splat forwarded-restarg forwarded-args (hash (forwarded-kwrestarg)) (block-pass nil?)}
|
69
|
+
PATTERN
|
70
|
+
|
56
71
|
# @!method each_block_with_push?(node)
|
57
72
|
def_node_matcher :each_block_with_push?, <<-PATTERN
|
58
73
|
[
|
59
|
-
^({begin kwbegin} ...)
|
60
|
-
(
|
61
|
-
(send (lvar _) {:<< :push :append}
|
74
|
+
^({begin kwbegin block} ...)
|
75
|
+
(any_block (send !{nil? self} :each) _
|
76
|
+
(send (lvar _) {:<< :push :append} #suitable_argument_node?))
|
62
77
|
]
|
63
78
|
PATTERN
|
64
79
|
|
@@ -74,6 +89,16 @@ module RuboCop
|
|
74
89
|
)
|
75
90
|
PATTERN
|
76
91
|
|
92
|
+
# @!method empty_array_tap(node)
|
93
|
+
def_node_matcher :empty_array_tap, <<~PATTERN
|
94
|
+
^^$(
|
95
|
+
block
|
96
|
+
(send (array) :tap)
|
97
|
+
(args (arg _))
|
98
|
+
...
|
99
|
+
)
|
100
|
+
PATTERN
|
101
|
+
|
77
102
|
# @!method lvar_ref?(node, name)
|
78
103
|
def_node_matcher :lvar_ref?, '(lvar %1)'
|
79
104
|
|
@@ -89,9 +114,14 @@ module RuboCop
|
|
89
114
|
return unless each_block_with_push?(node)
|
90
115
|
|
91
116
|
dest_var = find_dest_var(node)
|
92
|
-
|
93
|
-
|
94
|
-
|
117
|
+
|
118
|
+
if offending_empty_array_tap?(node, dest_var)
|
119
|
+
asgn = dest_var.declaration_node
|
120
|
+
else
|
121
|
+
return unless (asgn = find_closest_assignment(node, dest_var))
|
122
|
+
return unless empty_array_asgn?(asgn)
|
123
|
+
return unless dest_used_only_for_mapping?(node, dest_var, asgn)
|
124
|
+
end
|
95
125
|
|
96
126
|
register_offense(node, dest_var, asgn)
|
97
127
|
end
|
@@ -108,6 +138,15 @@ module RuboCop
|
|
108
138
|
candidates.find { |v| v.references.any? { |n| n.node.equal?(node) } }
|
109
139
|
end
|
110
140
|
|
141
|
+
def offending_empty_array_tap?(node, dest_var)
|
142
|
+
return false unless (tap_block_node = empty_array_tap(dest_var.declaration_node))
|
143
|
+
|
144
|
+
# A `tap` block only offends if the array push is the only thing in it;
|
145
|
+
# otherwise we cannot guarantee that the block variable is still an empty
|
146
|
+
# array when pushed to.
|
147
|
+
tap_block_node.body == node
|
148
|
+
end
|
149
|
+
|
111
150
|
def find_closest_assignment(block, dest_var)
|
112
151
|
dest_var.assignments.reverse_each.lazy.map(&:node).find do |node|
|
113
152
|
node.source_range.end_pos < block.source_range.begin_pos
|
@@ -127,7 +166,13 @@ module RuboCop
|
|
127
166
|
next if return_value_used?(block)
|
128
167
|
|
129
168
|
corrector.replace(block.send_node.selector, new_method_name)
|
130
|
-
|
169
|
+
|
170
|
+
if (tap_block_node = empty_array_tap(dest_var.declaration_node))
|
171
|
+
remove_tap(corrector, block, tap_block_node)
|
172
|
+
else
|
173
|
+
remove_assignment(corrector, asgn)
|
174
|
+
end
|
175
|
+
|
131
176
|
correct_push_node(corrector, block.body)
|
132
177
|
correct_return_value_handling(corrector, block, dest_var)
|
133
178
|
end
|
@@ -159,6 +204,12 @@ module RuboCop
|
|
159
204
|
corrector.remove(range)
|
160
205
|
end
|
161
206
|
|
207
|
+
def remove_tap(corrector, node, block_node)
|
208
|
+
range = range_between(block_node.source_range.begin_pos, node.source_range.begin_pos)
|
209
|
+
corrector.remove(range)
|
210
|
+
corrector.remove(range_with_surrounding_space(block_node.loc.end, side: :left))
|
211
|
+
end
|
212
|
+
|
162
213
|
def correct_push_node(corrector, push_node)
|
163
214
|
range = push_node.source_range
|
164
215
|
arg_range = push_node.first_argument.source_range
|
@@ -40,7 +40,7 @@ module RuboCop
|
|
40
40
|
# @!method map_to_h(node)
|
41
41
|
def_node_matcher :map_to_h, <<~PATTERN
|
42
42
|
{
|
43
|
-
$(call (
|
43
|
+
$(call (any_block $(call _ {:map :collect}) ...) :to_h)
|
44
44
|
$(call $(call _ {:map :collect} (block_pass sym)) :to_h)
|
45
45
|
}
|
46
46
|
PATTERN
|
@@ -33,8 +33,8 @@ module RuboCop
|
|
33
33
|
# @!method map_to_set?(node)
|
34
34
|
def_node_matcher :map_to_set?, <<~PATTERN
|
35
35
|
{
|
36
|
-
$(
|
37
|
-
$(
|
36
|
+
$(call (any_block $(call _ {:map :collect}) ...) :to_set)
|
37
|
+
$(call $(call _ {:map :collect} (block_pass sym)) :to_set)
|
38
38
|
}
|
39
39
|
PATTERN
|
40
40
|
|
@@ -49,6 +49,7 @@ module RuboCop
|
|
49
49
|
autocorrect(corrector, to_set_node, map_node)
|
50
50
|
end
|
51
51
|
end
|
52
|
+
alias on_csend on_send
|
52
53
|
|
53
54
|
private
|
54
55
|
|