rubocop 1.69.2 → 1.75.4
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 +183 -41
- data/config/internal_affairs.yml +20 -0
- data/config/obsoletion.yml +3 -1
- data/lib/rubocop/cli/command/execute_runner.rb +3 -3
- data/lib/rubocop/cli/command/show_cops.rb +24 -2
- data/lib/rubocop/cli/command/suggest_extensions.rb +7 -1
- data/lib/rubocop/cli.rb +1 -1
- data/lib/rubocop/comment_config.rb +2 -2
- data/lib/rubocop/config.rb +52 -10
- data/lib/rubocop/config_loader.rb +52 -9
- data/lib/rubocop/config_loader_resolver.rb +36 -10
- data/lib/rubocop/config_obsoletion/extracted_cop.rb +4 -3
- data/lib/rubocop/config_obsoletion/renamed_cop.rb +18 -3
- data/lib/rubocop/config_obsoletion.rb +46 -2
- data/lib/rubocop/config_validator.rb +25 -14
- data/lib/rubocop/cop/autocorrect_logic.rb +1 -1
- data/lib/rubocop/cop/base.rb +6 -0
- data/lib/rubocop/cop/bundler/duplicated_gem.rb +1 -1
- data/lib/rubocop/cop/bundler/gem_comment.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/cop_enabled.rb +85 -0
- data/lib/rubocop/cop/internal_affairs/example_description.rb +8 -4
- data/lib/rubocop/cop/internal_affairs/location_exists.rb +116 -0
- data/lib/rubocop/cop/internal_affairs/location_expression.rb +2 -1
- data/lib/rubocop/cop/internal_affairs/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 +230 -0
- data/lib/rubocop/cop/internal_affairs/node_type_group.rb +91 -0
- data/lib/rubocop/cop/internal_affairs/node_type_multiple_predicates.rb +126 -0
- data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +4 -3
- data/lib/rubocop/cop/internal_affairs/on_send_without_on_csend.rb +90 -0
- data/lib/rubocop/cop/internal_affairs/plugin.rb +33 -0
- data/lib/rubocop/cop/internal_affairs/redundant_described_class_as_subject.rb +6 -5
- data/lib/rubocop/cop/internal_affairs/redundant_source_range.rb +3 -1
- data/lib/rubocop/cop/internal_affairs/single_line_comparison.rb +5 -4
- data/lib/rubocop/cop/internal_affairs/undefined_config.rb +13 -2
- 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 -8
- data/lib/rubocop/cop/layout/block_alignment.rb +3 -1
- data/lib/rubocop/cop/layout/block_end_newline.rb +1 -0
- data/lib/rubocop/cop/layout/class_structure.rb +9 -9
- data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +4 -4
- data/lib/rubocop/cop/layout/def_end_alignment.rb +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 +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 +28 -1
- data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +1 -0
- data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +1 -1
- data/lib/rubocop/cop/layout/empty_lines_around_method_body.rb +22 -2
- 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 +7 -5
- data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +2 -1
- data/lib/rubocop/cop/layout/indentation_width.rb +1 -0
- 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 +9 -4
- data/lib/rubocop/cop/layout/multiline_block_layout.rb +1 -0
- data/lib/rubocop/cop/layout/multiline_hash_key_line_breaks.rb +1 -1
- data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +25 -0
- data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +1 -0
- data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +4 -4
- data/lib/rubocop/cop/layout/multiline_method_parameter_line_breaks.rb +1 -0
- data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/redundant_line_break.rb +16 -11
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +3 -5
- 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 +1 -0
- data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +1 -1
- data/lib/rubocop/cop/layout/space_around_operators.rb +7 -4
- data/lib/rubocop/cop/layout/space_before_block_braces.rb +1 -0
- 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_block_braces.rb +1 -0
- 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 +1 -1
- data/lib/rubocop/cop/lint/boolean_symbol.rb +1 -1
- data/lib/rubocop/cop/lint/circular_argument_reference.rb +2 -5
- data/lib/rubocop/cop/lint/constant_definition_in_block.rb +3 -3
- data/lib/rubocop/cop/lint/constant_reassignment.rb +148 -0
- data/lib/rubocop/cop/lint/cop_directive_syntax.rb +84 -0
- data/lib/rubocop/cop/lint/debugger.rb +3 -3
- data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +1 -1
- data/lib/rubocop/cop/lint/duplicate_match_pattern.rb +1 -1
- data/lib/rubocop/cop/lint/duplicate_methods.rb +2 -17
- 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_conditional_body.rb +14 -64
- data/lib/rubocop/cop/lint/empty_expression.rb +0 -2
- data/lib/rubocop/cop/lint/erb_new_arguments.rb +0 -6
- data/lib/rubocop/cop/lint/float_comparison.rb +6 -8
- data/lib/rubocop/cop/lint/float_out_of_range.rb +1 -1
- data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +2 -2
- data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +1 -1
- data/lib/rubocop/cop/lint/literal_as_condition.rb +117 -9
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +24 -6
- data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +1 -1
- data/lib/rubocop/cop/lint/missing_super.rb +2 -2
- data/lib/rubocop/cop/lint/mixed_case_range.rb +3 -3
- 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/non_atomic_file_operation.rb +4 -3
- data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +3 -3
- data/lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +18 -31
- data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +1 -1
- data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +2 -1
- data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +1 -5
- data/lib/rubocop/cop/lint/raise_exception.rb +29 -10
- 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_string_coercion.rb +2 -2
- data/lib/rubocop/cop/lint/redundant_type_conversion.rb +261 -0
- data/lib/rubocop/cop/lint/redundant_with_index.rb +3 -0
- data/lib/rubocop/cop/lint/redundant_with_object.rb +3 -0
- data/lib/rubocop/cop/lint/rescue_exception.rb +1 -1
- data/lib/rubocop/cop/lint/return_in_void_context.rb +9 -11
- data/lib/rubocop/cop/lint/safe_navigation_chain.rb +8 -1
- data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +8 -1
- data/lib/rubocop/cop/lint/shared_mutable_default.rb +76 -0
- data/lib/rubocop/cop/lint/suppressed_exception.rb +1 -1
- data/lib/rubocop/cop/lint/suppressed_exception_in_number_conversion.rb +111 -0
- data/lib/rubocop/cop/lint/symbol_conversion.rb +1 -1
- data/lib/rubocop/cop/lint/syntax.rb +4 -1
- data/lib/rubocop/cop/lint/to_enum_arguments.rb +1 -1
- data/lib/rubocop/cop/lint/top_level_return_with_argument.rb +1 -1
- data/lib/rubocop/cop/lint/unescaped_bracket_in_regexp.rb +1 -4
- data/lib/rubocop/cop/lint/unexpected_block_arity.rb +3 -1
- data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +1 -1
- data/lib/rubocop/cop/lint/unreachable_code.rb +2 -1
- data/lib/rubocop/cop/lint/unreachable_loop.rb +6 -6
- data/lib/rubocop/cop/lint/useless_access_modifier.rb +5 -4
- data/lib/rubocop/cop/lint/useless_assignment.rb +1 -1
- data/lib/rubocop/cop/lint/useless_constant_scoping.rb +71 -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/void.rb +12 -9
- data/lib/rubocop/cop/message_annotator.rb +7 -3
- data/lib/rubocop/cop/metrics/block_length.rb +1 -0
- data/lib/rubocop/cop/metrics/block_nesting.rb +1 -1
- data/lib/rubocop/cop/metrics/collection_literal_length.rb +7 -0
- data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +1 -1
- data/lib/rubocop/cop/metrics/method_length.rb +9 -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/code_length_calculator.rb +1 -1
- 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_line_breakable.rb +13 -13
- data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +2 -2
- data/lib/rubocop/cop/mixin/comments_help.rb +4 -2
- data/lib/rubocop/cop/mixin/def_node.rb +1 -1
- data/lib/rubocop/cop/mixin/dig_help.rb +1 -1
- data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +1 -1
- data/lib/rubocop/cop/mixin/forbidden_identifiers.rb +20 -0
- data/lib/rubocop/cop/mixin/forbidden_pattern.rb +16 -0
- data/lib/rubocop/cop/mixin/frozen_string_literal.rb +0 -1
- 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/method_complexity.rb +2 -1
- data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +2 -0
- data/lib/rubocop/cop/mixin/percent_literal.rb +1 -1
- data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +48 -24
- data/lib/rubocop/cop/mixin/range_help.rb +15 -3
- 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 +1 -1
- data/lib/rubocop/cop/mixin/trailing_comma.rb +16 -4
- data/lib/rubocop/cop/naming/block_forwarding.rb +19 -15
- data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +1 -1
- data/lib/rubocop/cop/naming/method_name.rb +64 -8
- data/lib/rubocop/cop/naming/predicate_name.rb +44 -0
- data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +3 -3
- data/lib/rubocop/cop/naming/variable_name.rb +51 -6
- data/lib/rubocop/cop/registry.rb +9 -6
- data/lib/rubocop/cop/security/compound_hash.rb +1 -0
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +34 -5
- data/lib/rubocop/cop/style/accessor_grouping.rb +19 -5
- data/lib/rubocop/cop/style/and_or.rb +1 -1
- data/lib/rubocop/cop/style/arguments_forwarding.rb +44 -28
- data/lib/rubocop/cop/style/array_first_last.rb +18 -2
- data/lib/rubocop/cop/style/array_intersect.rb +39 -28
- data/lib/rubocop/cop/style/block_delimiters.rb +9 -21
- data/lib/rubocop/cop/style/class_and_module_children.rb +52 -11
- data/lib/rubocop/cop/style/class_equality_comparison.rb +1 -1
- data/lib/rubocop/cop/style/collection_methods.rb +2 -1
- data/lib/rubocop/cop/style/combinable_defined.rb +1 -1
- data/lib/rubocop/cop/style/combinable_loops.rb +3 -2
- data/lib/rubocop/cop/style/commented_keyword.rb +12 -5
- data/lib/rubocop/cop/style/comparable_between.rb +75 -0
- data/lib/rubocop/cop/style/concat_array_literals.rb +1 -1
- data/lib/rubocop/cop/style/conditional_assignment.rb +20 -6
- data/lib/rubocop/cop/style/documentation.rb +1 -1
- data/lib/rubocop/cop/style/double_negation.rb +4 -4
- data/lib/rubocop/cop/style/each_for_simple_loop.rb +4 -7
- data/lib/rubocop/cop/style/each_with_object.rb +2 -3
- data/lib/rubocop/cop/style/empty_else.rb +4 -2
- data/lib/rubocop/cop/style/empty_literal.rb +5 -1
- data/lib/rubocop/cop/style/empty_method.rb +1 -1
- data/lib/rubocop/cop/style/endless_method.rb +163 -18
- data/lib/rubocop/cop/style/eval_with_location.rb +4 -4
- data/lib/rubocop/cop/style/exact_regexp_match.rb +3 -10
- data/lib/rubocop/cop/style/expand_path_arguments.rb +2 -7
- data/lib/rubocop/cop/style/explicit_block_argument.rb +16 -3
- data/lib/rubocop/cop/style/exponential_notation.rb +3 -3
- data/lib/rubocop/cop/style/fetch_env_var.rb +1 -1
- data/lib/rubocop/cop/style/float_division.rb +8 -4
- data/lib/rubocop/cop/style/for.rb +1 -0
- data/lib/rubocop/cop/style/format_string_token.rb +38 -11
- data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +3 -2
- data/lib/rubocop/cop/style/global_std_stream.rb +3 -0
- data/lib/rubocop/cop/style/guard_clause.rb +2 -1
- data/lib/rubocop/cop/style/hash_each_methods.rb +6 -8
- data/lib/rubocop/cop/style/hash_except.rb +24 -148
- data/lib/rubocop/cop/style/hash_fetch_chain.rb +104 -0
- data/lib/rubocop/cop/style/hash_slice.rb +80 -0
- data/lib/rubocop/cop/style/hash_syntax.rb +9 -3
- data/lib/rubocop/cop/style/hash_transform_keys.rb +2 -2
- data/lib/rubocop/cop/style/hash_transform_values.rb +2 -2
- data/lib/rubocop/cop/style/identical_conditional_branches.rb +22 -3
- data/lib/rubocop/cop/style/if_inside_else.rb +10 -13
- data/lib/rubocop/cop/style/if_unless_modifier.rb +5 -5
- data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +2 -2
- data/lib/rubocop/cop/style/if_with_semicolon.rb +2 -2
- data/lib/rubocop/cop/style/infinite_loop.rb +1 -1
- data/lib/rubocop/cop/style/inverse_methods.rb +15 -11
- data/lib/rubocop/cop/style/invertible_unless_condition.rb +2 -2
- data/lib/rubocop/cop/style/ip_addresses.rb +2 -2
- data/lib/rubocop/cop/style/it_assignment.rb +36 -0
- data/lib/rubocop/cop/style/it_block_parameter.rb +100 -0
- data/lib/rubocop/cop/style/keyword_parameters_order.rb +14 -8
- data/lib/rubocop/cop/style/lambda.rb +1 -0
- data/lib/rubocop/cop/style/lambda_call.rb +7 -2
- data/lib/rubocop/cop/style/line_end_concatenation.rb +10 -4
- data/lib/rubocop/cop/style/map_into_array.rb +5 -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 +23 -16
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +2 -0
- data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +2 -1
- data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +3 -4
- data/lib/rubocop/cop/style/method_def_parentheses.rb +1 -1
- data/lib/rubocop/cop/style/missing_else.rb +2 -0
- data/lib/rubocop/cop/style/multiline_block_chain.rb +3 -2
- data/lib/rubocop/cop/style/multiline_method_signature.rb +1 -9
- data/lib/rubocop/cop/style/multiple_comparison.rb +26 -20
- data/lib/rubocop/cop/style/mutable_constant.rb +3 -3
- data/lib/rubocop/cop/style/negated_if_else_condition.rb +1 -1
- data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +1 -1
- data/lib/rubocop/cop/style/next.rb +44 -0
- data/lib/rubocop/cop/style/object_then.rb +14 -15
- data/lib/rubocop/cop/style/open_struct_use.rb +5 -5
- data/lib/rubocop/cop/style/parallel_assignment.rb +1 -5
- 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 +2 -2
- data/lib/rubocop/cop/style/quoted_symbols.rb +1 -1
- data/lib/rubocop/cop/style/raise_args.rb +14 -12
- data/lib/rubocop/cop/style/random_with_offset.rb +3 -3
- data/lib/rubocop/cop/style/redundant_begin.rb +2 -1
- data/lib/rubocop/cop/style/redundant_condition.rb +59 -2
- data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +16 -5
- data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +6 -10
- data/lib/rubocop/cop/style/redundant_each.rb +1 -1
- data/lib/rubocop/cop/style/redundant_exception.rb +2 -2
- data/lib/rubocop/cop/style/redundant_format.rb +257 -0
- data/lib/rubocop/cop/style/redundant_freeze.rb +3 -3
- data/lib/rubocop/cop/style/redundant_initialize.rb +12 -3
- data/lib/rubocop/cop/style/redundant_line_continuation.rb +34 -16
- data/lib/rubocop/cop/style/redundant_parentheses.rb +48 -16
- data/lib/rubocop/cop/style/redundant_regexp_argument.rb +3 -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_self.rb +1 -0
- data/lib/rubocop/cop/style/redundant_self_assignment.rb +14 -28
- data/lib/rubocop/cop/style/redundant_sort.rb +2 -2
- data/lib/rubocop/cop/style/redundant_sort_by.rb +17 -1
- data/lib/rubocop/cop/style/redundant_string_escape.rb +2 -2
- data/lib/rubocop/cop/style/rescue_modifier.rb +3 -0
- data/lib/rubocop/cop/style/return_nil.rb +2 -2
- data/lib/rubocop/cop/style/safe_navigation.rb +20 -5
- data/lib/rubocop/cop/style/select_by_regexp.rb +4 -1
- 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/single_line_block_params.rb +1 -1
- data/lib/rubocop/cop/style/single_line_do_end_block.rb +4 -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 +41 -106
- data/lib/rubocop/cop/style/string_concatenation.rb +2 -2
- 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 +66 -19
- data/lib/rubocop/cop/style/symbol_proc.rb +2 -0
- data/lib/rubocop/cop/style/ternary_parentheses.rb +1 -1
- data/lib/rubocop/cop/style/top_level_method_definition.rb +2 -1
- data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +11 -2
- data/lib/rubocop/cop/style/trailing_comma_in_array_literal.rb +47 -6
- data/lib/rubocop/cop/style/trailing_comma_in_hash_literal.rb +48 -6
- data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
- 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 +10 -5
- data/lib/rubocop/cop/variable_force/scope.rb +1 -1
- data/lib/rubocop/cop/variable_force/variable.rb +10 -3
- data/lib/rubocop/cop/variable_force/variable_table.rb +3 -3
- data/lib/rubocop/cop/variable_force.rb +1 -1
- data/lib/rubocop/cops_documentation_generator.rb +31 -16
- data/lib/rubocop/directive_comment.rb +45 -11
- data/lib/rubocop/ext/regexp_node.rb +0 -1
- data/lib/rubocop/formatter/disabled_config_formatter.rb +1 -1
- data/lib/rubocop/formatter/formatter_set.rb +1 -1
- data/lib/rubocop/formatter/pacman_formatter.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 -50
- data/lib/rubocop/lsp/server.rb +0 -2
- data/lib/rubocop/lsp/stdin_runner.rb +85 -0
- data/lib/rubocop/magic_comment.rb +8 -0
- 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 +13 -1
- data/lib/rubocop/rspec/expect_offense.rb +6 -2
- data/lib/rubocop/rspec/shared_contexts.rb +38 -1
- data/lib/rubocop/rspec/support.rb +4 -2
- data/lib/rubocop/runner.rb +10 -7
- data/lib/rubocop/server/cache.rb +47 -11
- data/lib/rubocop/server/cli.rb +2 -2
- data/lib/rubocop/target_finder.rb +7 -2
- data/lib/rubocop/target_ruby.rb +16 -1
- data/lib/rubocop/version.rb +30 -8
- data/lib/rubocop.rb +16 -1
- data/lib/ruby_lsp/rubocop/addon.rb +75 -0
- data/lib/ruby_lsp/rubocop/runtime_adapter.rb +65 -0
- metadata +59 -16
- data/lib/rubocop/cop/utils/regexp_ranges.rb +0 -113
- data/lib/rubocop/rspec/host_environment_simulation_helper.rb +0 -28
@@ -151,7 +151,7 @@ module RuboCop
|
|
151
151
|
|
152
152
|
def frozen_string_literal_comment(processed_source)
|
153
153
|
processed_source.tokens.find do |token|
|
154
|
-
token.text.
|
154
|
+
MagicComment.parse(token.text).frozen_string_literal_specified?
|
155
155
|
end
|
156
156
|
end
|
157
157
|
|
@@ -189,8 +189,9 @@ module RuboCop
|
|
189
189
|
|
190
190
|
def enable_comment(corrector)
|
191
191
|
comment = frozen_string_literal_comment(processed_source)
|
192
|
+
replacement = MagicComment.parse(comment.text).new_frozen_string_literal(true)
|
192
193
|
|
193
|
-
corrector.replace(line_range(comment.line),
|
194
|
+
corrector.replace(line_range(comment.line), replacement)
|
194
195
|
end
|
195
196
|
|
196
197
|
def insert_comment(corrector)
|
@@ -8,6 +8,9 @@ module RuboCop
|
|
8
8
|
# reassign (possibly to redirect some stream) constants in Ruby, you'll get
|
9
9
|
# an interpreter warning if you do so.
|
10
10
|
#
|
11
|
+
# Additionally, `$stdout/$stderr/$stdin` can safely be accessed in a Ractor because they
|
12
|
+
# are ractor-local, while `STDOUT/STDERR/STDIN` will raise `Ractor::IsolationError`.
|
13
|
+
#
|
11
14
|
# @safety
|
12
15
|
# Autocorrection is unsafe because `STDOUT` and `$stdout` may point to different
|
13
16
|
# objects, for example.
|
@@ -135,6 +135,7 @@ module RuboCop
|
|
135
135
|
on_def(node)
|
136
136
|
end
|
137
137
|
alias on_numblock on_block
|
138
|
+
alias on_itblock on_block
|
138
139
|
|
139
140
|
def on_if(node)
|
140
141
|
return if accepted_form?(node)
|
@@ -213,7 +214,7 @@ module RuboCop
|
|
213
214
|
if_branch = node.if_branch
|
214
215
|
else_branch = node.else_branch
|
215
216
|
|
216
|
-
corrector.replace(node.loc.begin, "\n") if node.
|
217
|
+
corrector.replace(node.loc.begin, "\n") if node.then?
|
217
218
|
|
218
219
|
if if_branch&.send_type? && heredoc?(if_branch.last_argument)
|
219
220
|
autocorrect_heredoc_argument(corrector, node, if_branch, else_branch, guard)
|
@@ -3,7 +3,7 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module Style
|
6
|
-
# Checks for uses of `each_key` and `each_value` Hash methods.
|
6
|
+
# Checks for uses of `each_key` and `each_value` `Hash` methods.
|
7
7
|
#
|
8
8
|
# NOTE: If you have an array of two-element arrays, you can put
|
9
9
|
# parentheses around the block arguments to indicate that you're not
|
@@ -44,7 +44,7 @@ module RuboCop
|
|
44
44
|
|
45
45
|
# @!method kv_each(node)
|
46
46
|
def_node_matcher :kv_each, <<~PATTERN
|
47
|
-
(
|
47
|
+
(any_block $(call (call _ ${:keys :values}) :each) ...)
|
48
48
|
PATTERN
|
49
49
|
|
50
50
|
# @!method each_arguments(node)
|
@@ -74,6 +74,7 @@ module RuboCop
|
|
74
74
|
check_unused_block_args(node, key, value)
|
75
75
|
end
|
76
76
|
alias on_numblock on_block
|
77
|
+
alias on_itblock on_block
|
77
78
|
|
78
79
|
# rubocop:disable Metrics/AbcSize
|
79
80
|
def check_unused_block_args(node, key, value)
|
@@ -128,8 +129,8 @@ module RuboCop
|
|
128
129
|
lvar_sources = node.body.each_descendant(:lvar).map(&:source)
|
129
130
|
|
130
131
|
if block_arg.mlhs_type?
|
131
|
-
block_arg.each_descendant(:arg, :restarg).all? do |
|
132
|
-
lvar_sources.none?(
|
132
|
+
block_arg.each_descendant(:arg, :restarg).all? do |descendant|
|
133
|
+
lvar_sources.none?(descendant.source.delete_prefix('*'))
|
133
134
|
end
|
134
135
|
else
|
135
136
|
lvar_sources.none?(block_arg.source.delete_prefix('*'))
|
@@ -162,10 +163,7 @@ module RuboCop
|
|
162
163
|
|
163
164
|
def use_array_converter_method_as_preceding?(node)
|
164
165
|
return false unless (preceding_method = node.children.first.children.first)
|
165
|
-
unless preceding_method.
|
166
|
-
preceding_method.block_type? || preceding_method.numblock_type?
|
167
|
-
return false
|
168
|
-
end
|
166
|
+
return false unless preceding_method.type?(:call, :any_block)
|
169
167
|
|
170
168
|
ARRAY_CONVERTER_METHODS.include?(preceding_method.method_name)
|
171
169
|
end
|
@@ -10,8 +10,10 @@ module RuboCop
|
|
10
10
|
# (`Hash#except` was added in Ruby 3.0.)
|
11
11
|
#
|
12
12
|
# For safe detection, it is limited to commonly used string and symbol comparisons
|
13
|
-
# when
|
14
|
-
#
|
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.
|
15
17
|
#
|
16
18
|
# @safety
|
17
19
|
# This cop is unsafe because it cannot be guaranteed that the receiver
|
@@ -30,6 +32,21 @@ module RuboCop
|
|
30
32
|
# {foo: 1, bar: 2, baz: 3}.select {|k, v| !%i[bar].include?(k) }
|
31
33
|
# {foo: 1, bar: 2, baz: 3}.filter {|k, v| !%i[bar].include?(k) }
|
32
34
|
#
|
35
|
+
# # good
|
36
|
+
# {foo: 1, bar: 2, baz: 3}.except(:bar)
|
37
|
+
#
|
38
|
+
# @example AllCops:ActiveSupportExtensionsEnabled: false (default)
|
39
|
+
#
|
40
|
+
# # good
|
41
|
+
# {foo: 1, bar: 2, baz: 3}.reject {|k, v| !%i[bar].exclude?(k) }
|
42
|
+
# {foo: 1, bar: 2, baz: 3}.select {|k, v| %i[bar].exclude?(k) }
|
43
|
+
#
|
44
|
+
# # good
|
45
|
+
# {foo: 1, bar: 2, baz: 3}.reject {|k, v| k.in?(%i[bar]) }
|
46
|
+
# {foo: 1, bar: 2, baz: 3}.select {|k, v| !k.in?(%i[bar]) }
|
47
|
+
#
|
48
|
+
# @example AllCops:ActiveSupportExtensionsEnabled: true
|
49
|
+
#
|
33
50
|
# # bad
|
34
51
|
# {foo: 1, bar: 2, baz: 3}.reject {|k, v| !%i[bar].exclude?(k) }
|
35
52
|
# {foo: 1, bar: 2, baz: 3}.select {|k, v| %i[bar].exclude?(k) }
|
@@ -42,161 +59,20 @@ module RuboCop
|
|
42
59
|
# {foo: 1, bar: 2, baz: 3}.except(:bar)
|
43
60
|
#
|
44
61
|
class HashExcept < Base
|
45
|
-
include
|
62
|
+
include HashSubset
|
46
63
|
extend TargetRubyVersion
|
47
64
|
extend AutoCorrector
|
48
65
|
|
49
66
|
minimum_target_ruby_version 3.0
|
50
67
|
|
51
|
-
MSG = 'Use `%<prefer>s` instead.'
|
52
|
-
RESTRICT_ON_SEND = %i[reject select filter].freeze
|
53
|
-
|
54
|
-
# @!method bad_method_with_poro?(node)
|
55
|
-
def_node_matcher :bad_method_with_poro?, <<~PATTERN
|
56
|
-
(block
|
57
|
-
(call _ _)
|
58
|
-
(args
|
59
|
-
$(arg _)
|
60
|
-
(arg _))
|
61
|
-
{
|
62
|
-
$(send
|
63
|
-
_ {:== :!= :eql? :include?} _)
|
64
|
-
(send
|
65
|
-
$(send
|
66
|
-
_ {:== :!= :eql? :include?} _) :!)
|
67
|
-
})
|
68
|
-
PATTERN
|
69
|
-
|
70
|
-
# @!method bad_method_with_active_support?(node)
|
71
|
-
def_node_matcher :bad_method_with_active_support?, <<~PATTERN
|
72
|
-
(block
|
73
|
-
(send _ _)
|
74
|
-
(args
|
75
|
-
$(arg _)
|
76
|
-
(arg _))
|
77
|
-
{
|
78
|
-
$(send
|
79
|
-
_ {:== :!= :eql? :in? :include? :exclude?} _)
|
80
|
-
(send
|
81
|
-
$(send
|
82
|
-
_ {:== :!= :eql? :in? :include? :exclude?} _) :!)
|
83
|
-
})
|
84
|
-
PATTERN
|
85
|
-
|
86
|
-
def on_send(node)
|
87
|
-
block = node.parent
|
88
|
-
return unless bad_method?(block) && semantically_except_method?(node, block)
|
89
|
-
|
90
|
-
except_key = except_key(block)
|
91
|
-
return if except_key.nil? || !safe_to_register_offense?(block, except_key)
|
92
|
-
|
93
|
-
range = offense_range(node)
|
94
|
-
preferred_method = "except(#{except_key_source(except_key)})"
|
95
|
-
|
96
|
-
add_offense(range, message: format(MSG, prefer: preferred_method)) do |corrector|
|
97
|
-
corrector.replace(range, preferred_method)
|
98
|
-
end
|
99
|
-
end
|
100
|
-
alias on_csend on_send
|
101
|
-
|
102
68
|
private
|
103
69
|
|
104
|
-
|
105
|
-
|
106
|
-
if active_support_extensions_enabled?
|
107
|
-
bad_method_with_active_support?(block) do |key_arg, send_node|
|
108
|
-
if send_node.method?(:in?) && send_node.receiver&.source != key_arg.source
|
109
|
-
return false
|
110
|
-
end
|
111
|
-
return true if !send_node.method?(:include?) && !send_node.method?(:exclude?)
|
112
|
-
|
113
|
-
send_node.first_argument&.source == key_arg.source
|
114
|
-
end
|
115
|
-
else
|
116
|
-
bad_method_with_poro?(block) do |key_arg, send_node|
|
117
|
-
!send_node.method?(:include?) || send_node.first_argument&.source == key_arg.source
|
118
|
-
end
|
119
|
-
end
|
120
|
-
end
|
121
|
-
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
122
|
-
|
123
|
-
def semantically_except_method?(send, block)
|
124
|
-
body = block.body
|
125
|
-
|
126
|
-
negated = body.method?('!')
|
127
|
-
body = body.receiver if negated
|
128
|
-
|
129
|
-
case send.method_name
|
130
|
-
when :reject
|
131
|
-
body.method?('==') || body.method?('eql?') || included?(negated, body)
|
132
|
-
when :select, :filter
|
133
|
-
body.method?('!=') || not_included?(negated, body)
|
134
|
-
else
|
135
|
-
false
|
136
|
-
end
|
137
|
-
end
|
138
|
-
|
139
|
-
def included?(negated, body)
|
140
|
-
if negated
|
141
|
-
body.method?('exclude?')
|
142
|
-
else
|
143
|
-
body.method?('include?') || body.method?('in?')
|
144
|
-
end
|
145
|
-
end
|
146
|
-
|
147
|
-
def not_included?(negated, body)
|
148
|
-
included?(!negated, body)
|
149
|
-
end
|
150
|
-
|
151
|
-
def safe_to_register_offense?(block, except_key)
|
152
|
-
extracted = extract_body_if_negated(block.body)
|
153
|
-
if extracted.method?('in?') || extracted.method?('include?') ||
|
154
|
-
extracted.method?('exclude?')
|
155
|
-
return true
|
156
|
-
end
|
157
|
-
return true if block.body.method?('eql?')
|
158
|
-
|
159
|
-
except_key.sym_type? || except_key.str_type?
|
160
|
-
end
|
161
|
-
|
162
|
-
def extract_body_if_negated(body)
|
163
|
-
return body unless body.method?('!')
|
164
|
-
|
165
|
-
body.receiver
|
166
|
-
end
|
167
|
-
|
168
|
-
def except_key_source(key)
|
169
|
-
if key.array_type?
|
170
|
-
key = if key.percent_literal?
|
171
|
-
key.each_value.map { |v| decorate_source(v) }
|
172
|
-
else
|
173
|
-
key.each_value.map(&:source)
|
174
|
-
end
|
175
|
-
return key.join(', ')
|
176
|
-
end
|
177
|
-
|
178
|
-
key.literal? ? key.source : "*#{key.source}"
|
179
|
-
end
|
180
|
-
|
181
|
-
def decorate_source(value)
|
182
|
-
return ":\"#{value.source}\"" if value.dsym_type?
|
183
|
-
return "\"#{value.source}\"" if value.dstr_type?
|
184
|
-
return ":#{value.source}" if value.sym_type?
|
185
|
-
|
186
|
-
"'#{value.source}'"
|
187
|
-
end
|
188
|
-
|
189
|
-
def except_key(node)
|
190
|
-
key_argument = node.argument_list.first.source
|
191
|
-
body = extract_body_if_negated(node.body)
|
192
|
-
lhs, _method_name, rhs = *body
|
193
|
-
return if [lhs, rhs].map(&:source).none?(key_argument)
|
194
|
-
|
195
|
-
[lhs, rhs].find { |operand| operand.source != key_argument }
|
70
|
+
def semantically_subset_method?(node)
|
71
|
+
semantically_except_method?(node)
|
196
72
|
end
|
197
73
|
|
198
|
-
def
|
199
|
-
|
74
|
+
def preferred_method_name
|
75
|
+
'except'
|
200
76
|
end
|
201
77
|
end
|
202
78
|
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Style
|
6
|
+
# Use `Hash#dig` instead of chaining potentially null `fetch` calls.
|
7
|
+
#
|
8
|
+
# When `fetch(identifier, nil)` calls are chained on a hash, the expectation
|
9
|
+
# is that each step in the chain returns either `nil` or another hash,
|
10
|
+
# and in both cases, these can be simplified with a single call to `dig` with
|
11
|
+
# multiple arguments.
|
12
|
+
#
|
13
|
+
# If the 2nd parameter is `{}` or `Hash.new`, an offense will also be registered,
|
14
|
+
# as long as the final call in the chain is a nil value. If a non-nil value is given,
|
15
|
+
# the chain will not be registered as an offense, as the default value cannot be safely
|
16
|
+
# given with `dig`.
|
17
|
+
#
|
18
|
+
# NOTE: See `Style/DigChain` for replacing chains of `dig` calls with
|
19
|
+
# a single method call.
|
20
|
+
#
|
21
|
+
# @safety
|
22
|
+
# This cop is unsafe because it cannot be guaranteed that the receiver
|
23
|
+
# is a `Hash` or that `fetch` or `dig` have the expected standard implementation.
|
24
|
+
#
|
25
|
+
# @example
|
26
|
+
# # bad
|
27
|
+
# hash.fetch('foo', nil)&.fetch('bar', nil)
|
28
|
+
#
|
29
|
+
# # bad
|
30
|
+
# # earlier members of the chain can return `{}` as long as the final `fetch`
|
31
|
+
# # has `nil` as a default value
|
32
|
+
# hash.fetch('foo', {}).fetch('bar', nil)
|
33
|
+
#
|
34
|
+
# # good
|
35
|
+
# hash.dig('foo', 'bar')
|
36
|
+
#
|
37
|
+
# # ok - not handled by the cop since the final `fetch` value is non-nil
|
38
|
+
# hash.fetch('foo', {}).fetch('bar', {})
|
39
|
+
#
|
40
|
+
class HashFetchChain < Base
|
41
|
+
extend AutoCorrector
|
42
|
+
extend TargetRubyVersion
|
43
|
+
|
44
|
+
MSG = 'Use `%<replacement>s` instead.'
|
45
|
+
RESTRICT_ON_SEND = %i[fetch].freeze
|
46
|
+
|
47
|
+
minimum_target_ruby_version 2.3
|
48
|
+
|
49
|
+
# @!method diggable?(node)
|
50
|
+
def_node_matcher :diggable?, <<~PATTERN
|
51
|
+
(call _ :fetch $_arg {nil (hash) (send (const {nil? cbase} :Hash) :new)})
|
52
|
+
PATTERN
|
53
|
+
|
54
|
+
def on_send(node)
|
55
|
+
return if ignored_node?(node)
|
56
|
+
return if last_fetch_non_nil?(node)
|
57
|
+
|
58
|
+
last_replaceable_node, arguments = inspect_chain(node)
|
59
|
+
return unless last_replaceable_node
|
60
|
+
return unless arguments.size > 1
|
61
|
+
|
62
|
+
range = last_replaceable_node.selector.join(node.loc.end)
|
63
|
+
replacement = replacement(arguments)
|
64
|
+
message = format(MSG, replacement: replacement)
|
65
|
+
|
66
|
+
add_offense(range, message: message) do |corrector|
|
67
|
+
corrector.replace(range, replacement)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
alias on_csend on_send
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
def last_fetch_non_nil?(node)
|
75
|
+
# When chaining `fetch` methods, `fetch(x, {})` is acceptable within
|
76
|
+
# the chain, as long as the last method in the chain has a `nil`
|
77
|
+
# default value.
|
78
|
+
|
79
|
+
return false unless node.method?(:fetch)
|
80
|
+
|
81
|
+
!node.last_argument&.nil_type?
|
82
|
+
end
|
83
|
+
|
84
|
+
def inspect_chain(node)
|
85
|
+
arguments = []
|
86
|
+
|
87
|
+
while (arg = diggable?(node))
|
88
|
+
arguments.unshift(arg)
|
89
|
+
ignore_node(node)
|
90
|
+
last_replaceable_node = node
|
91
|
+
node = node.receiver
|
92
|
+
end
|
93
|
+
|
94
|
+
[last_replaceable_node, arguments]
|
95
|
+
end
|
96
|
+
|
97
|
+
def replacement(arguments)
|
98
|
+
values = arguments.map(&:source).join(', ')
|
99
|
+
"dig(#{values})"
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -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
|
@@ -76,6 +76,9 @@ module RuboCop
|
|
76
76
|
# # good
|
77
77
|
# {foo:, bar:}
|
78
78
|
#
|
79
|
+
# # good - allowed to mix syntaxes
|
80
|
+
# {foo:, bar: baz}
|
81
|
+
#
|
79
82
|
# @example EnforcedShorthandSyntax: never
|
80
83
|
#
|
81
84
|
# # bad
|
@@ -137,6 +140,7 @@ module RuboCop
|
|
137
140
|
MSG_19 = 'Use the new Ruby 1.9 hash syntax.'
|
138
141
|
MSG_NO_MIXED_KEYS = "Don't mix styles in the same hash."
|
139
142
|
MSG_HASH_ROCKETS = 'Use hash rockets syntax.'
|
143
|
+
NO_MIXED_KEYS_STYLES = %i[ruby19_no_mixed_keys no_mixed_keys].freeze
|
140
144
|
|
141
145
|
def on_hash(node)
|
142
146
|
pairs = node.pairs
|
@@ -196,7 +200,7 @@ module RuboCop
|
|
196
200
|
def autocorrect(corrector, node)
|
197
201
|
if style == :hash_rockets || force_hash_rockets?(node.parent.pairs)
|
198
202
|
autocorrect_hash_rockets(corrector, node)
|
199
|
-
elsif style
|
203
|
+
elsif NO_MIXED_KEYS_STYLES.include?(style)
|
200
204
|
autocorrect_no_mixed_keys(corrector, node)
|
201
205
|
else
|
202
206
|
autocorrect_ruby19(corrector, node)
|
@@ -208,7 +212,7 @@ module RuboCop
|
|
208
212
|
end
|
209
213
|
|
210
214
|
def word_symbol_pair?(pair)
|
211
|
-
return false unless pair.key.
|
215
|
+
return false unless pair.key.type?(:sym, :dsym)
|
212
216
|
|
213
217
|
acceptable_19_syntax_symbol?(pair.key.source)
|
214
218
|
end
|
@@ -272,7 +276,9 @@ module RuboCop
|
|
272
276
|
end
|
273
277
|
|
274
278
|
def argument_without_space?(node)
|
275
|
-
node.argument?
|
279
|
+
return false if !node.argument? || !node.parent.loc.selector
|
280
|
+
|
281
|
+
node.source_range.begin_pos == node.parent.loc.selector.end_pos
|
276
282
|
end
|
277
283
|
|
278
284
|
def autocorrect_hash_rockets(corrector, pair_node)
|
@@ -3,8 +3,8 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module Style
|
6
|
-
# Looks for uses of
|
7
|
-
#
|
6
|
+
# Looks for uses of `+_.each_with_object({}) {...}+`,
|
7
|
+
# `+_.map {...}.to_h+`, and `+Hash[_.map {...}]+` that are actually just
|
8
8
|
# transforming the keys of a hash, and tries to use a simpler & faster
|
9
9
|
# call to `transform_keys` instead.
|
10
10
|
# It should only be enabled on Ruby version 2.5 or newer.
|
@@ -3,8 +3,8 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module Style
|
6
|
-
# Looks for uses of
|
7
|
-
#
|
6
|
+
# Looks for uses of `+_.each_with_object({}) {...}+`,
|
7
|
+
# `+_.map {...}.to_h+`, and `+Hash[_.map {...}]+` that are actually just
|
8
8
|
# transforming the values of a hash, and tries to use a simpler & faster
|
9
9
|
# call to `transform_values` instead.
|
10
10
|
#
|
@@ -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
|
|
@@ -97,34 +97,31 @@ module RuboCop
|
|
97
97
|
else
|
98
98
|
correct_to_elsif_from_if_inside_else_form(corrector, node, node.condition)
|
99
99
|
end
|
100
|
-
|
101
|
-
corrector.remove(range_by_whole_lines(find_end_range(node), include_final_newline: true))
|
102
|
-
return unless (if_branch = node.if_branch)
|
103
|
-
|
104
|
-
range = range_by_whole_lines(if_branch.source_range, include_final_newline: true)
|
105
|
-
corrector.remove(range)
|
106
100
|
end
|
107
101
|
|
108
102
|
def correct_to_elsif_from_modifier_form(corrector, node)
|
109
|
-
corrector.replace(node.parent.loc.else,
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
103
|
+
corrector.replace(node.parent.loc.else, "elsif #{node.condition.source}")
|
104
|
+
|
105
|
+
condition_range = range_between(
|
106
|
+
node.if_branch.source_range.end_pos, node.condition.source_range.end_pos
|
107
|
+
)
|
108
|
+
corrector.remove(condition_range)
|
114
109
|
end
|
115
110
|
|
116
|
-
def correct_to_elsif_from_if_inside_else_form(corrector, node, condition)
|
111
|
+
def correct_to_elsif_from_if_inside_else_form(corrector, node, condition) # rubocop:disable Metrics/AbcSize
|
117
112
|
corrector.replace(node.parent.loc.else, "elsif #{condition.source}")
|
118
113
|
|
119
114
|
if_condition_range = if_condition_range(node, condition)
|
120
115
|
|
121
116
|
if (if_branch = node.if_branch)
|
122
|
-
corrector.replace(if_condition_range, if_branch.source)
|
117
|
+
corrector.replace(if_condition_range, range_with_comments(if_branch).source)
|
118
|
+
corrector.remove(range_with_comments_and_lines(if_branch))
|
123
119
|
else
|
124
120
|
corrector.remove(range_by_whole_lines(if_condition_range, include_final_newline: true))
|
125
121
|
end
|
126
122
|
|
127
123
|
corrector.remove(condition)
|
124
|
+
corrector.remove(range_by_whole_lines(find_end_range(node), include_final_newline: true))
|
128
125
|
end
|
129
126
|
|
130
127
|
def then?(node)
|
@@ -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
|
@@ -164,8 +164,8 @@ module RuboCop
|
|
164
164
|
|
165
165
|
def too_long_due_to_comment_after_modifier?(node, comment)
|
166
166
|
source_length = processed_source.lines[node.first_line - 1].length
|
167
|
-
|
168
|
-
|
167
|
+
|
168
|
+
max_line_length.between?(source_length - comment.source_range.length, source_length)
|
169
169
|
end
|
170
170
|
|
171
171
|
def allowed_patterns
|