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
@@ -26,6 +26,13 @@ module RuboCop
|
|
26
26
|
extend NodePattern::Macros
|
27
27
|
include RuboCop::AST::Sexp
|
28
28
|
|
29
|
+
VAR_SETTER_TO_GETTER = {
|
30
|
+
lvasgn: :lvar,
|
31
|
+
ivasgn: :ivar,
|
32
|
+
cvasgn: :cvar,
|
33
|
+
gvasgn: :gvar
|
34
|
+
}.freeze
|
35
|
+
|
29
36
|
# Plug into the calculator
|
30
37
|
def initialize(node, discount_repeated_attributes: false)
|
31
38
|
super(node)
|
@@ -114,13 +121,6 @@ module RuboCop
|
|
114
121
|
calls.fetch(value) { yield [calls, value] }
|
115
122
|
end
|
116
123
|
|
117
|
-
VAR_SETTER_TO_GETTER = {
|
118
|
-
lvasgn: :lvar,
|
119
|
-
ivasgn: :ivar,
|
120
|
-
cvasgn: :cvar,
|
121
|
-
gvasgn: :gvar
|
122
|
-
}.freeze
|
123
|
-
|
124
124
|
# @returns `[receiver, method | nil]` for the given setter `node`
|
125
125
|
# or `nil` if it is not a setter.
|
126
126
|
def setter_to_getter(node)
|
@@ -5,10 +5,10 @@ module RuboCop
|
|
5
5
|
# This module checks for nodes that should be aligned to the left or right.
|
6
6
|
# This amount is determined by the instance variable @column_delta.
|
7
7
|
module Alignment
|
8
|
-
private
|
9
|
-
|
10
8
|
SPACE = ' '
|
11
9
|
|
10
|
+
private
|
11
|
+
|
12
12
|
attr_reader :column_delta
|
13
13
|
|
14
14
|
def configured_indentation_width
|
@@ -18,12 +18,12 @@ module RuboCop
|
|
18
18
|
end
|
19
19
|
|
20
20
|
# @deprecated Use allowed_line? instead
|
21
|
-
def ignored_line?
|
21
|
+
def ignored_line?(line)
|
22
22
|
warn Rainbow(<<~WARNING).yellow, uplevel: 1
|
23
23
|
`ignored_line?` is deprecated. Use `allowed_line?` instead.
|
24
24
|
WARNING
|
25
25
|
|
26
|
-
allowed_line?
|
26
|
+
allowed_line?(line)
|
27
27
|
end
|
28
28
|
|
29
29
|
def matches_allowed_pattern?(line)
|
@@ -31,12 +31,12 @@ module RuboCop
|
|
31
31
|
end
|
32
32
|
|
33
33
|
# @deprecated Use matches_allowed_pattern? instead
|
34
|
-
def matches_ignored_pattern?
|
34
|
+
def matches_ignored_pattern?(line)
|
35
35
|
warn Rainbow(<<~WARNING).yellow, uplevel: 1
|
36
36
|
`matches_ignored_pattern?` is deprecated. Use `matches_allowed_pattern?` instead.
|
37
37
|
WARNING
|
38
38
|
|
39
|
-
matches_allowed_pattern?
|
39
|
+
matches_allowed_pattern?(line)
|
40
40
|
end
|
41
41
|
|
42
42
|
def allowed_patterns
|
@@ -43,14 +43,14 @@ module RuboCop
|
|
43
43
|
# (Note: Passes may not happen exactly in this sequence.)
|
44
44
|
module CheckLineBreakable
|
45
45
|
def extract_breakable_node(node, max)
|
46
|
-
if node.
|
46
|
+
if node.call_type?
|
47
47
|
return if chained_to_heredoc?(node)
|
48
48
|
|
49
49
|
args = process_args(node.arguments)
|
50
50
|
return extract_breakable_node_from_elements(node, args, max)
|
51
|
-
elsif node.
|
51
|
+
elsif node.any_def_type?
|
52
52
|
return extract_breakable_node_from_elements(node, node.arguments, max)
|
53
|
-
elsif node.
|
53
|
+
elsif node.type?(:array, :hash)
|
54
54
|
return extract_breakable_node_from_elements(node, node.children, max)
|
55
55
|
end
|
56
56
|
nil
|
@@ -74,9 +74,9 @@ module RuboCop
|
|
74
74
|
def extract_first_element_over_column_limit(node, elements, max)
|
75
75
|
line = node.first_line
|
76
76
|
|
77
|
-
# If a `send` node is not parenthesized, don't move the first element, because it
|
77
|
+
# If a `send` or `csend` node is not parenthesized, don't move the first element, because it
|
78
78
|
# can result in changed behavior or a syntax error.
|
79
|
-
if node.
|
79
|
+
if node.call_type? && !node.parenthesized? && !first_argument_is_heredoc?(node)
|
80
80
|
elements = elements.drop(1)
|
81
81
|
end
|
82
82
|
|
@@ -98,10 +98,10 @@ module RuboCop
|
|
98
98
|
end
|
99
99
|
|
100
100
|
# @api private
|
101
|
-
# If a send node contains a heredoc argument, splitting cannot happen
|
101
|
+
# If a `send` or `csend` node contains a heredoc argument, splitting cannot happen
|
102
102
|
# after the heredoc or else it will cause a syntax error.
|
103
103
|
def shift_elements_for_heredoc_arg(node, elements, index)
|
104
|
-
return index unless node.
|
104
|
+
return index unless node.type?(:call, :array)
|
105
105
|
|
106
106
|
heredoc_index = elements.index { |arg| arg.respond_to?(:heredoc?) && arg.heredoc? }
|
107
107
|
return index unless heredoc_index
|
@@ -154,9 +154,9 @@ module RuboCop
|
|
154
154
|
# Ignore ancestors on different lines.
|
155
155
|
break if ancestor.first_line != node.first_line
|
156
156
|
|
157
|
-
if ancestor.
|
157
|
+
if ancestor.type?(:hash, :array)
|
158
158
|
elements = ancestor.children
|
159
|
-
elsif ancestor.
|
159
|
+
elsif ancestor.call_type?
|
160
160
|
elements = process_args(ancestor.arguments)
|
161
161
|
else
|
162
162
|
next
|
@@ -171,12 +171,12 @@ module RuboCop
|
|
171
171
|
# @api private
|
172
172
|
def contained_by_multiline_collection_that_could_be_broken_up?(node)
|
173
173
|
node.each_ancestor.find do |ancestor|
|
174
|
-
if
|
174
|
+
if ancestor.type?(:hash, :array) &&
|
175
175
|
breakable_collection?(ancestor, ancestor.children)
|
176
176
|
return children_could_be_broken_up?(ancestor.children)
|
177
177
|
end
|
178
178
|
|
179
|
-
next unless ancestor.
|
179
|
+
next unless ancestor.call_type?
|
180
180
|
|
181
181
|
args = process_args(ancestor.arguments)
|
182
182
|
return children_could_be_broken_up?(args) if breakable_collection?(ancestor, args)
|
@@ -220,14 +220,14 @@ module RuboCop
|
|
220
220
|
|
221
221
|
# @api private
|
222
222
|
def already_on_multiple_lines?(node)
|
223
|
-
return node.first_line != node.last_argument.last_line if node.
|
223
|
+
return node.first_line != node.last_argument.last_line if node.any_def_type?
|
224
224
|
|
225
225
|
!node.single_line?
|
226
226
|
end
|
227
227
|
|
228
228
|
def chained_to_heredoc?(node)
|
229
229
|
while (node = node.receiver)
|
230
|
-
return true if
|
230
|
+
return true if node.type?(:str, :dstr, :xstr) && node.heredoc?
|
231
231
|
end
|
232
232
|
|
233
233
|
false
|
@@ -35,12 +35,12 @@ module RuboCop
|
|
35
35
|
comment_line_numbers = processed_source.comments.map { |comment| comment.loc.line }
|
36
36
|
|
37
37
|
comment_line_numbers.any? do |comment_line_number|
|
38
|
-
comment_line_number
|
38
|
+
comment_line_number.between?(node.first_line, node.last_line)
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
42
42
|
def safe_to_split?(node)
|
43
|
-
node.each_descendant(:if, :case, :kwbegin, :
|
43
|
+
node.each_descendant(:if, :case, :kwbegin, :any_def).none? &&
|
44
44
|
node.each_descendant(:dstr, :str).none? { |n| n.heredoc? || n.value.include?("\n") } &&
|
45
45
|
node.each_descendant(:begin, :sym).none? { |b| !b.single_line? }
|
46
46
|
end
|
@@ -73,14 +73,16 @@ module RuboCop
|
|
73
73
|
node.else_branch.loc.line
|
74
74
|
elsif node.elsif?
|
75
75
|
node.each_ancestor(:if).find(&:if?).loc.end.line
|
76
|
+
elsif node.if? && node.parent && parentheses?(node.parent)
|
77
|
+
node.parent.loc.end.line
|
76
78
|
end
|
77
|
-
elsif node.
|
79
|
+
elsif node.any_block_type?
|
78
80
|
node.loc.end.line
|
79
81
|
elsif (next_sibling = node.right_sibling) && next_sibling.is_a?(AST::Node) &&
|
80
82
|
next_sibling.source_range
|
81
83
|
next_sibling.loc.line
|
82
84
|
elsif (parent = node.parent)
|
83
|
-
if parent.loc
|
85
|
+
if parent.loc?(:end)
|
84
86
|
parent.loc.end.line
|
85
87
|
else
|
86
88
|
parent.loc.line
|
@@ -19,7 +19,7 @@ module RuboCop
|
|
19
19
|
|
20
20
|
# @!method non_public_modifier?(node)
|
21
21
|
def_node_matcher :non_public_modifier?, <<~PATTERN
|
22
|
-
(send nil? {:private :protected :private_class_method} (
|
22
|
+
(send nil? {:private :protected :private_class_method} (any_def ...))
|
23
23
|
PATTERN
|
24
24
|
end
|
25
25
|
end
|
@@ -21,7 +21,7 @@ module RuboCop
|
|
21
21
|
|
22
22
|
# @!method empty_line_required?(node)
|
23
23
|
def_node_matcher :empty_line_required?,
|
24
|
-
'{
|
24
|
+
'{any_def class module (send nil? {:private :protected :public})}'
|
25
25
|
|
26
26
|
def check(node, body, adjusted_first_line: nil)
|
27
27
|
return if valid_body_style?(body)
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
# This module encapsulates the ability to forbid certain identifiers in a cop.
|
6
|
+
module ForbiddenIdentifiers
|
7
|
+
SIGILS = '@$' # if a variable starts with a sigil it will be removed
|
8
|
+
|
9
|
+
def forbidden_identifier?(name)
|
10
|
+
name = name.to_s.delete(SIGILS)
|
11
|
+
|
12
|
+
forbidden_identifiers.any? && forbidden_identifiers.include?(name)
|
13
|
+
end
|
14
|
+
|
15
|
+
def forbidden_identifiers
|
16
|
+
cop_config.fetch('ForbiddenIdentifiers', [])
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
# This module encapsulates the ability to forbid certain patterns in a cop.
|
6
|
+
module ForbiddenPattern
|
7
|
+
def forbidden_pattern?(name)
|
8
|
+
forbidden_patterns.any? { |pattern| Regexp.new(pattern).match?(name) }
|
9
|
+
end
|
10
|
+
|
11
|
+
def forbidden_patterns
|
12
|
+
cop_config.fetch('ForbiddenPatterns', [])
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -11,6 +11,24 @@ module RuboCop
|
|
11
11
|
DO_NOT_MIX_OMIT_VALUE_MSG = "#{DO_NOT_MIX_MSG_PREFIX} #{OMIT_HASH_VALUE_MSG}"
|
12
12
|
DO_NOT_MIX_EXPLICIT_VALUE_MSG = "#{DO_NOT_MIX_MSG_PREFIX} #{EXPLICIT_HASH_VALUE_MSG}"
|
13
13
|
|
14
|
+
DefNode = Struct.new(:node) do
|
15
|
+
def selector
|
16
|
+
if node.loc.respond_to?(:selector)
|
17
|
+
node.loc.selector
|
18
|
+
else
|
19
|
+
node.loc.keyword
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def first_argument
|
24
|
+
node.first_argument
|
25
|
+
end
|
26
|
+
|
27
|
+
def last_argument
|
28
|
+
node.last_argument
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
14
32
|
def on_hash_for_mixed_shorthand(hash_node)
|
15
33
|
return if ignore_mixed_hash_shorthand_syntax?(hash_node)
|
16
34
|
|
@@ -86,7 +104,7 @@ module RuboCop
|
|
86
104
|
return true if !node.key.sym_type? || require_hash_value_for_around_hash_literal?(node)
|
87
105
|
|
88
106
|
hash_value = node.value
|
89
|
-
return true unless hash_value.
|
107
|
+
return true unless hash_value.type?(:send, :lvar)
|
90
108
|
|
91
109
|
hash_key_source != hash_value.source || hash_key_source.end_with?('!', '?')
|
92
110
|
end
|
@@ -109,7 +127,7 @@ module RuboCop
|
|
109
127
|
return if dispatch_node.parent && parentheses?(dispatch_node.parent)
|
110
128
|
return if last_expression?(dispatch_node) && !method_dispatch_as_argument?(dispatch_node)
|
111
129
|
|
112
|
-
def_node = node.each_ancestor(:
|
130
|
+
def_node = node.each_ancestor(:call, :super, :yield).first
|
113
131
|
|
114
132
|
DefNode.new(def_node) unless def_node && def_node.arguments.empty?
|
115
133
|
end
|
@@ -117,7 +135,7 @@ module RuboCop
|
|
117
135
|
|
118
136
|
def find_ancestor_method_dispatch_node(node)
|
119
137
|
return unless (ancestor = node.parent.parent)
|
120
|
-
return unless ancestor.
|
138
|
+
return unless ancestor.type?(:call, :super, :yield)
|
121
139
|
return if brackets?(ancestor)
|
122
140
|
|
123
141
|
ancestor
|
@@ -150,7 +168,7 @@ module RuboCop
|
|
150
168
|
parent = method_dispatch_node.parent
|
151
169
|
return false unless parent
|
152
170
|
|
153
|
-
parent.
|
171
|
+
parent.type?(:call, :super, :yield)
|
154
172
|
end
|
155
173
|
|
156
174
|
def breakdown_value_types_of_hash(hash_node)
|
@@ -212,24 +230,6 @@ module RuboCop
|
|
212
230
|
register_offense(pair_node, OMIT_HASH_VALUE_MSG, replacement)
|
213
231
|
end
|
214
232
|
end
|
215
|
-
|
216
|
-
DefNode = Struct.new(:node) do
|
217
|
-
def selector
|
218
|
-
if node.loc.respond_to?(:selector)
|
219
|
-
node.loc.selector
|
220
|
-
else
|
221
|
-
node.loc.keyword
|
222
|
-
end
|
223
|
-
end
|
224
|
-
|
225
|
-
def first_argument
|
226
|
-
node.first_argument
|
227
|
-
end
|
228
|
-
|
229
|
-
def last_argument
|
230
|
-
node.last_argument
|
231
|
-
end
|
232
|
-
end
|
233
233
|
end
|
234
234
|
end
|
235
235
|
# rubocop:enable Metrics/ModuleLength
|
@@ -0,0 +1,203 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
# Common functionality for Style/HashExcept and Style/HashSlice cops.
|
6
|
+
# It registers an offense on methods with blocks that are equivalent
|
7
|
+
# to Hash#except or Hash#slice.
|
8
|
+
# rubocop:disable Metrics/ModuleLength
|
9
|
+
module HashSubset
|
10
|
+
include RangeHelp
|
11
|
+
extend NodePattern::Macros
|
12
|
+
|
13
|
+
RESTRICT_ON_SEND = %i[reject select filter].freeze
|
14
|
+
|
15
|
+
SUBSET_METHODS = %i[== != eql? include?].freeze
|
16
|
+
ACTIVE_SUPPORT_SUBSET_METHODS = (SUBSET_METHODS + %i[in? exclude?]).freeze
|
17
|
+
|
18
|
+
MSG = 'Use `%<prefer>s` instead.'
|
19
|
+
|
20
|
+
# @!method block_with_first_arg_check?(node)
|
21
|
+
def_node_matcher :block_with_first_arg_check?, <<~PATTERN
|
22
|
+
(block
|
23
|
+
(call _ _)
|
24
|
+
(args
|
25
|
+
$(arg _key)
|
26
|
+
$(arg _))
|
27
|
+
{
|
28
|
+
$(send
|
29
|
+
{(lvar _key) $_ _ | _ $_ (lvar _key)})
|
30
|
+
(send
|
31
|
+
$(send
|
32
|
+
{(lvar _key) $_ _ | _ $_ (lvar _key)}) :!)
|
33
|
+
})
|
34
|
+
PATTERN
|
35
|
+
|
36
|
+
def on_send(node)
|
37
|
+
offense_range, key_source = extract_offense(node)
|
38
|
+
|
39
|
+
return unless offense_range
|
40
|
+
return unless semantically_subset_method?(node)
|
41
|
+
|
42
|
+
preferred_method = "#{preferred_method_name}(#{key_source})"
|
43
|
+
add_offense(offense_range, message: format(MSG, prefer: preferred_method)) do |corrector|
|
44
|
+
corrector.replace(offense_range, preferred_method)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
alias on_csend on_send
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def semantically_subset_method?(node)
|
52
|
+
raise NotImplementedError
|
53
|
+
end
|
54
|
+
|
55
|
+
def preferred_method_name
|
56
|
+
raise NotImplementedError
|
57
|
+
end
|
58
|
+
|
59
|
+
def extract_offense(node)
|
60
|
+
block = node.parent
|
61
|
+
return unless extracts_hash_subset?(block)
|
62
|
+
|
63
|
+
except_key = except_key(block)
|
64
|
+
return if except_key.nil? || !safe_to_register_offense?(block, except_key)
|
65
|
+
|
66
|
+
[offense_range(node), except_key_source(except_key)]
|
67
|
+
end
|
68
|
+
|
69
|
+
def extracts_hash_subset?(block)
|
70
|
+
block_with_first_arg_check?(block) do |key_arg, value_arg, send_node, method|
|
71
|
+
# Only consider methods that have one argument
|
72
|
+
return false unless send_node.arguments.one?
|
73
|
+
|
74
|
+
return false unless supported_subset_method?(method)
|
75
|
+
return false if range_include?(send_node)
|
76
|
+
|
77
|
+
case method
|
78
|
+
when :include?, :exclude?
|
79
|
+
slices_key?(send_node, :first_argument, key_arg, value_arg)
|
80
|
+
when :in?
|
81
|
+
slices_key?(send_node, :receiver, key_arg, value_arg)
|
82
|
+
else
|
83
|
+
true
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def slices_key?(send_node, method, key_arg, value_arg)
|
89
|
+
return false if using_value_variable?(send_node, value_arg)
|
90
|
+
|
91
|
+
node = method == :receiver ? send_node.receiver : send_node.first_argument
|
92
|
+
node.source == key_arg.source
|
93
|
+
end
|
94
|
+
|
95
|
+
def range_include?(send_node)
|
96
|
+
# When checking `include?`, `exclude?` and `in?` for offenses, if the receiver
|
97
|
+
# or first argument is a range, an offense should not be registered.
|
98
|
+
# ie. `(1..5).include?(k)` or `k.in?('a'..'z')`
|
99
|
+
|
100
|
+
return true if send_node.first_argument.range_type?
|
101
|
+
|
102
|
+
receiver = send_node.receiver
|
103
|
+
receiver = receiver.child_nodes.first while receiver.begin_type?
|
104
|
+
receiver.range_type?
|
105
|
+
end
|
106
|
+
|
107
|
+
def using_value_variable?(send_node, value_arg)
|
108
|
+
# If the receiver of `include?` or `exclude?`, or the first argument of `in?` is the
|
109
|
+
# hash value block argument, an offense should not be registered.
|
110
|
+
# ie. `v.include?(k)` or `k.in?(v)`
|
111
|
+
(send_node.receiver.lvar_type? && send_node.receiver.name == value_arg.name) ||
|
112
|
+
(send_node.first_argument.lvar_type? && send_node.first_argument.name == value_arg.name)
|
113
|
+
end
|
114
|
+
|
115
|
+
def supported_subset_method?(method)
|
116
|
+
if active_support_extensions_enabled?
|
117
|
+
ACTIVE_SUPPORT_SUBSET_METHODS.include?(method)
|
118
|
+
else
|
119
|
+
SUBSET_METHODS.include?(method)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def semantically_except_method?(node)
|
124
|
+
block = node.parent
|
125
|
+
body, negated = extract_body_if_negated(block.body)
|
126
|
+
|
127
|
+
if node.method?('reject')
|
128
|
+
body.method?('==') || body.method?('eql?') || included?(body, negated)
|
129
|
+
else
|
130
|
+
body.method?('!=') || not_included?(body, negated)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
def semantically_slice_method?(node)
|
135
|
+
!semantically_except_method?(node)
|
136
|
+
end
|
137
|
+
|
138
|
+
def included?(body, negated)
|
139
|
+
if negated
|
140
|
+
body.method?('exclude?')
|
141
|
+
else
|
142
|
+
body.method?('include?') || body.method?('in?')
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
def not_included?(body, negated)
|
147
|
+
included?(body, !negated)
|
148
|
+
end
|
149
|
+
|
150
|
+
def safe_to_register_offense?(block, except_key)
|
151
|
+
body = block.body
|
152
|
+
|
153
|
+
if body.method?('==') || body.method?('!=')
|
154
|
+
except_key.type?(:sym, :str)
|
155
|
+
else
|
156
|
+
true
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
def extract_body_if_negated(body)
|
161
|
+
if body.method?('!')
|
162
|
+
[body.receiver, true]
|
163
|
+
else
|
164
|
+
[body, false]
|
165
|
+
end
|
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_arg = node.argument_list.first.source
|
191
|
+
body, = extract_body_if_negated(node.body)
|
192
|
+
lhs, _method_name, rhs = *body
|
193
|
+
|
194
|
+
lhs.source == key_arg ? rhs : lhs
|
195
|
+
end
|
196
|
+
|
197
|
+
def offense_range(node)
|
198
|
+
range_between(node.loc.selector.begin_pos, node.parent.loc.end.end_pos)
|
199
|
+
end
|
200
|
+
end
|
201
|
+
# rubocop:enable Metrics/ModuleLength
|
202
|
+
end
|
203
|
+
end
|