rubocop 1.69.0 → 1.76.1
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 +22 -16
- data/config/default.yml +234 -47
- data/config/internal_affairs.yml +20 -0
- data/config/obsoletion.yml +8 -3
- 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 +44 -39
- data/lib/rubocop/cop/base.rb +6 -0
- 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/ordered_gems.rb +1 -1
- data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +50 -6
- data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +1 -1
- data/lib/rubocop/cop/generator.rb +6 -0
- data/lib/rubocop/cop/internal_affairs/cop_enabled.rb +85 -0
- data/lib/rubocop/cop/internal_affairs/example_description.rb +8 -4
- data/lib/rubocop/cop/internal_affairs/location_exists.rb +116 -0
- data/lib/rubocop/cop/internal_affairs/location_expression.rb +2 -1
- data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +1 -0
- 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 +231 -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/operator_keyword.rb +4 -2
- 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 +44 -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 +34 -3
- data/lib/rubocop/cop/layout/empty_lines_around_begin_body.rb +5 -6
- data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +1 -0
- data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +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 +4 -9
- 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 +8 -6
- 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/leading_comment_space.rb +13 -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 +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 +11 -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_brackets.rb +6 -32
- 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 +5 -1
- data/lib/rubocop/cop/layout/space_inside_block_braces.rb +1 -0
- data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +3 -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 +118 -0
- data/lib/rubocop/cop/lint/assignment_in_condition.rb +1 -3
- data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +2 -3
- data/lib/rubocop/cop/lint/boolean_symbol.rb +1 -1
- data/lib/rubocop/cop/lint/circular_argument_reference.rb +4 -3
- data/lib/rubocop/cop/lint/constant_definition_in_block.rb +3 -3
- data/lib/rubocop/cop/lint/constant_reassignment.rb +148 -0
- data/lib/rubocop/cop/lint/cop_directive_syntax.rb +84 -0
- data/lib/rubocop/cop/lint/debugger.rb +3 -3
- data/lib/rubocop/cop/lint/deprecated_class_methods.rb +1 -1
- data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +2 -1
- data/lib/rubocop/cop/lint/duplicate_match_pattern.rb +1 -1
- data/lib/rubocop/cop/lint/duplicate_methods.rb +86 -19
- 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/empty_interpolation.rb +3 -1
- data/lib/rubocop/cop/lint/erb_new_arguments.rb +0 -6
- data/lib/rubocop/cop/lint/float_comparison.rb +33 -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/identity_comparison.rb +19 -15
- data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +1 -1
- data/lib/rubocop/cop/lint/literal_as_condition.rb +110 -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 -2
- data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +3 -3
- data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +3 -3
- data/lib/rubocop/cop/lint/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/refinement_import_methods.rb +1 -1
- 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 +13 -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 -1
- data/lib/rubocop/cop/lint/unexpected_block_arity.rb +3 -1
- data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +1 -1
- data/lib/rubocop/cop/lint/unreachable_code.rb +52 -2
- data/lib/rubocop/cop/lint/unreachable_loop.rb +6 -6
- data/lib/rubocop/cop/lint/useless_access_modifier.rb +5 -4
- data/lib/rubocop/cop/lint/useless_assignment.rb +3 -1
- data/lib/rubocop/cop/lint/useless_constant_scoping.rb +71 -0
- data/lib/rubocop/cop/lint/useless_default_value_argument.rb +87 -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_or.rb +98 -0
- 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 +14 -11
- data/lib/rubocop/cop/message_annotator.rb +7 -3
- data/lib/rubocop/cop/metrics/abc_size.rb +1 -1
- 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/class_length.rb +9 -9
- 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 +2 -2
- 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 +8 -3
- 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_alignment_styles.rb +15 -14
- data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +22 -22
- data/lib/rubocop/cop/mixin/hash_subset.rb +203 -0
- data/lib/rubocop/cop/mixin/hash_transform_method.rb +74 -74
- data/lib/rubocop/cop/mixin/line_length_help.rb +5 -4
- 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/ordered_gem_node.rb +1 -1
- data/lib/rubocop/cop/mixin/percent_literal.rb +1 -1
- data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +68 -30
- data/lib/rubocop/cop/mixin/range_help.rb +15 -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 +21 -5
- data/lib/rubocop/cop/naming/accessor_method_name.rb +6 -6
- 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_method.rb +216 -0
- data/lib/rubocop/cop/naming/{predicate_name.rb → predicate_prefix.rb} +46 -2
- data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +4 -4
- 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 +2 -0
- data/lib/rubocop/cop/security/yaml_load.rb +3 -2
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +66 -15
- 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 +47 -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 +26 -23
- 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/command_literal.rb +1 -1
- data/lib/rubocop/cop/style/commented_keyword.rb +12 -5
- data/lib/rubocop/cop/style/comparable_between.rb +78 -0
- data/lib/rubocop/cop/style/concat_array_literals.rb +1 -1
- data/lib/rubocop/cop/style/conditional_assignment.rb +20 -6
- data/lib/rubocop/cop/style/data_inheritance.rb +7 -0
- data/lib/rubocop/cop/style/def_with_parentheses.rb +18 -5
- data/lib/rubocop/cop/style/dig_chain.rb +5 -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/empty_string_inside_interpolation.rb +100 -0
- 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 +2 -3
- data/lib/rubocop/cop/style/expand_path_arguments.rb +2 -7
- data/lib/rubocop/cop/style/explicit_block_argument.rb +16 -3
- data/lib/rubocop/cop/style/exponential_notation.rb +3 -3
- data/lib/rubocop/cop/style/fetch_env_var.rb +2 -1
- data/lib/rubocop/cop/style/file_null.rb +20 -4
- 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 +35 -147
- data/lib/rubocop/cop/style/hash_fetch_chain.rb +104 -0
- data/lib/rubocop/cop/style/hash_slice.rb +80 -0
- data/lib/rubocop/cop/style/hash_syntax.rb +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 +25 -6
- data/lib/rubocop/cop/style/if_inside_else.rb +10 -13
- data/lib/rubocop/cop/style/if_unless_modifier.rb +25 -7
- data/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +4 -7
- data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +2 -2
- data/lib/rubocop/cop/style/if_with_semicolon.rb +7 -5
- 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 +119 -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 +10 -3
- 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 +12 -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 +26 -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 +3 -2
- 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_if_modifier.rb +2 -0
- data/lib/rubocop/cop/style/multiline_method_signature.rb +1 -9
- data/lib/rubocop/cop/style/multiple_comparison.rb +34 -22
- 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 +15 -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/percent_q_literals.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_argument.rb +3 -1
- data/lib/rubocop/cop/style/redundant_array_flatten.rb +50 -0
- 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 +262 -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 +38 -21
- data/lib/rubocop/cop/style/redundant_parentheses.rb +61 -17
- 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 +2 -1
- 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/regexp_literal.rb +1 -1
- 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 +44 -16
- 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 +42 -105
- data/lib/rubocop/cop/style/string_concatenation.rb +15 -14
- data/lib/rubocop/cop/style/string_literals.rb +1 -1
- data/lib/rubocop/cop/style/string_methods.rb +1 -1
- data/lib/rubocop/cop/style/struct_inheritance.rb +8 -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/team.rb +1 -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/assignment.rb +7 -3
- 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 +2 -1
- data/lib/rubocop/formatter/formatter_set.rb +1 -1
- data/lib/rubocop/formatter/html_formatter.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 +11 -3
- data/lib/rubocop/options.rb +28 -12
- data/lib/rubocop/path_util.rb +15 -8
- data/lib/rubocop/plugin/configuration_integrator.rb +143 -0
- data/lib/rubocop/plugin/load_error.rb +26 -0
- data/lib/rubocop/plugin/loader.rb +100 -0
- data/lib/rubocop/plugin/not_supported_error.rb +29 -0
- data/lib/rubocop/plugin.rb +46 -0
- data/lib/rubocop/rake_task.rb +4 -1
- data/lib/rubocop/result_cache.rb +13 -13
- data/lib/rubocop/rspec/cop_helper.rb +13 -1
- data/lib/rubocop/rspec/expect_offense.rb +15 -5
- 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 +22 -2
- data/lib/ruby_lsp/rubocop/addon.rb +75 -0
- data/lib/ruby_lsp/rubocop/runtime_adapter.rb +65 -0
- metadata +67 -19
- data/lib/rubocop/cop/utils/regexp_ranges.rb +0 -113
- data/lib/rubocop/rspec/host_environment_simulation_helper.rb +0 -28
@@ -0,0 +1,148 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Lint
|
6
|
+
# Checks for constant reassignments.
|
7
|
+
#
|
8
|
+
# Emulates Ruby's runtime warning "already initialized constant X"
|
9
|
+
# when a constant is reassigned in the same file and namespace using the
|
10
|
+
# `NAME = value` syntax.
|
11
|
+
#
|
12
|
+
# The cop cannot catch all offenses, like, for example, when a constant
|
13
|
+
# is reassigned in another file, or when using metaprogramming (`Module#const_set`).
|
14
|
+
#
|
15
|
+
# The cop only takes into account constants assigned in a "simple" way: directly
|
16
|
+
# inside class/module definition, or within another constant. Other type of assignments
|
17
|
+
# (e.g., inside a conditional) are disregarded.
|
18
|
+
#
|
19
|
+
# The cop also tracks constant removal using `Module#remove_const` with symbol
|
20
|
+
# or string argument.
|
21
|
+
#
|
22
|
+
# @example
|
23
|
+
# # bad
|
24
|
+
# X = :foo
|
25
|
+
# X = :bar
|
26
|
+
#
|
27
|
+
# # bad
|
28
|
+
# class A
|
29
|
+
# X = :foo
|
30
|
+
# X = :bar
|
31
|
+
# end
|
32
|
+
#
|
33
|
+
# # bad
|
34
|
+
# module A
|
35
|
+
# X = :foo
|
36
|
+
# X = :bar
|
37
|
+
# end
|
38
|
+
#
|
39
|
+
# # good - keep only one assignment
|
40
|
+
# X = :bar
|
41
|
+
#
|
42
|
+
# class A
|
43
|
+
# X = :bar
|
44
|
+
# end
|
45
|
+
#
|
46
|
+
# module A
|
47
|
+
# X = :bar
|
48
|
+
# end
|
49
|
+
#
|
50
|
+
# # good - use OR assignment
|
51
|
+
# X = :foo
|
52
|
+
# X ||= :bar
|
53
|
+
#
|
54
|
+
# # good - use conditional assignment
|
55
|
+
# X = :foo
|
56
|
+
# X = :bar unless defined?(X)
|
57
|
+
#
|
58
|
+
# # good - remove the assigned constant first
|
59
|
+
# class A
|
60
|
+
# X = :foo
|
61
|
+
# remove_const :X
|
62
|
+
# X = :bar
|
63
|
+
# end
|
64
|
+
#
|
65
|
+
class ConstantReassignment < Base
|
66
|
+
MSG = 'Constant `%<constant>s` is already assigned in this namespace.'
|
67
|
+
|
68
|
+
RESTRICT_ON_SEND = %i[remove_const].freeze
|
69
|
+
|
70
|
+
# @!method remove_constant(node)
|
71
|
+
def_node_matcher :remove_constant, <<~PATTERN
|
72
|
+
(send _ :remove_const
|
73
|
+
({sym str} $_))
|
74
|
+
PATTERN
|
75
|
+
|
76
|
+
def on_casgn(node)
|
77
|
+
return unless fixed_constant_path?(node)
|
78
|
+
return unless simple_assignment?(node)
|
79
|
+
return if constant_names.add?(fully_qualified_constant_name(node))
|
80
|
+
|
81
|
+
add_offense(node, message: format(MSG, constant: node.name))
|
82
|
+
end
|
83
|
+
|
84
|
+
def on_send(node)
|
85
|
+
constant = remove_constant(node)
|
86
|
+
|
87
|
+
return unless constant
|
88
|
+
|
89
|
+
namespaces = ancestor_namespaces(node)
|
90
|
+
|
91
|
+
return if namespaces.none?
|
92
|
+
|
93
|
+
constant_names.delete(fully_qualified_name_for(namespaces, constant))
|
94
|
+
end
|
95
|
+
|
96
|
+
private
|
97
|
+
|
98
|
+
def fixed_constant_path?(node)
|
99
|
+
node.each_path.all? { |path| path.type?(:cbase, :const, :self) }
|
100
|
+
end
|
101
|
+
|
102
|
+
def simple_assignment?(node)
|
103
|
+
node.ancestors.all? do |ancestor|
|
104
|
+
return true if ancestor.type?(:module, :class)
|
105
|
+
|
106
|
+
ancestor.begin_type? || ancestor.literal? || ancestor.casgn_type? ||
|
107
|
+
freeze_method?(ancestor)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def freeze_method?(node)
|
112
|
+
node.send_type? && node.method?(:freeze)
|
113
|
+
end
|
114
|
+
|
115
|
+
def fully_qualified_constant_name(node)
|
116
|
+
if node.absolute?
|
117
|
+
namespace = node.namespace.const_type? ? node.namespace.source : nil
|
118
|
+
|
119
|
+
"#{namespace}::#{node.name}"
|
120
|
+
else
|
121
|
+
constant_namespaces = ancestor_namespaces(node) + constant_namespaces(node)
|
122
|
+
|
123
|
+
fully_qualified_name_for(constant_namespaces, node.name)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
def fully_qualified_name_for(namespaces, constant)
|
128
|
+
['', *namespaces, constant].join('::')
|
129
|
+
end
|
130
|
+
|
131
|
+
def constant_namespaces(node)
|
132
|
+
node.each_path.select(&:const_type?).map(&:short_name)
|
133
|
+
end
|
134
|
+
|
135
|
+
def ancestor_namespaces(node)
|
136
|
+
node
|
137
|
+
.each_ancestor(:class, :module)
|
138
|
+
.map { |ancestor| ancestor.identifier.short_name }
|
139
|
+
.reverse
|
140
|
+
end
|
141
|
+
|
142
|
+
def constant_names
|
143
|
+
@constant_names ||= Set.new
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# rubocop:disable Lint/RedundantCopDisableDirective
|
4
|
+
# rubocop:disable Style/DoubleCopDisableDirective
|
5
|
+
module RuboCop
|
6
|
+
module Cop
|
7
|
+
module Lint
|
8
|
+
# Checks that `# rubocop:enable ...` and `# rubocop:disable ...` statements
|
9
|
+
# are strictly formatted.
|
10
|
+
#
|
11
|
+
# A comment can be added to the directive by prefixing it with `--`.
|
12
|
+
#
|
13
|
+
# @example
|
14
|
+
# # bad
|
15
|
+
# # rubocop:disable Layout/LineLength Style/Encoding
|
16
|
+
# # ^ missing comma
|
17
|
+
#
|
18
|
+
# # bad
|
19
|
+
# # rubocop:disable
|
20
|
+
#
|
21
|
+
# # bad
|
22
|
+
# # rubocop:disable Layout/LineLength # rubocop:disable Style/Encoding
|
23
|
+
#
|
24
|
+
# # bad
|
25
|
+
# # rubocop:wrongmode Layout/LineLength
|
26
|
+
#
|
27
|
+
# # good
|
28
|
+
# # rubocop:disable Layout/LineLength
|
29
|
+
#
|
30
|
+
# # good
|
31
|
+
# # rubocop:disable Layout/LineLength, Style/Encoding
|
32
|
+
#
|
33
|
+
# # good
|
34
|
+
# # rubocop:disable all
|
35
|
+
#
|
36
|
+
# # good
|
37
|
+
# # rubocop:disable Layout/LineLength -- This is a good comment.
|
38
|
+
#
|
39
|
+
class CopDirectiveSyntax < Base
|
40
|
+
COMMON_MSG = 'Malformed directive comment detected.'
|
41
|
+
|
42
|
+
MISSING_MODE_NAME_MSG = 'The mode name is missing.'
|
43
|
+
INVALID_MODE_NAME_MSG = 'The mode name must be one of `enable`, `disable`, or `todo`.'
|
44
|
+
MISSING_COP_NAME_MSG = 'The cop name is missing.'
|
45
|
+
MALFORMED_COP_NAMES_MSG = 'Cop names must be separated by commas. ' \
|
46
|
+
'Comment in the directive must start with `--`.'
|
47
|
+
|
48
|
+
def on_new_investigation
|
49
|
+
processed_source.comments.each do |comment|
|
50
|
+
directive_comment = DirectiveComment.new(comment)
|
51
|
+
next unless directive_comment.start_with_marker?
|
52
|
+
next unless directive_comment.malformed?
|
53
|
+
|
54
|
+
message = offense_message(directive_comment)
|
55
|
+
add_offense(comment, message: message)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
# rubocop:disable Metrics/MethodLength
|
62
|
+
def offense_message(directive_comment)
|
63
|
+
comment = directive_comment.comment
|
64
|
+
after_marker = comment.text.sub(DirectiveComment::DIRECTIVE_MARKER_REGEXP, '')
|
65
|
+
mode = after_marker.split(' ', 2).first
|
66
|
+
additional_msg = if mode.nil?
|
67
|
+
MISSING_MODE_NAME_MSG
|
68
|
+
elsif !DirectiveComment::AVAILABLE_MODES.include?(mode)
|
69
|
+
INVALID_MODE_NAME_MSG
|
70
|
+
elsif directive_comment.missing_cop_name?
|
71
|
+
MISSING_COP_NAME_MSG
|
72
|
+
else
|
73
|
+
MALFORMED_COP_NAMES_MSG
|
74
|
+
end
|
75
|
+
|
76
|
+
"#{COMMON_MSG} #{additional_msg}"
|
77
|
+
end
|
78
|
+
# rubocop:enable Metrics/MethodLength
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
# rubocop:enable Lint/RedundantCopDisableDirective
|
84
|
+
# rubocop:enable Style/DoubleCopDisableDirective
|
@@ -73,7 +73,7 @@ module RuboCop
|
|
73
73
|
# require 'my_debugger/start'
|
74
74
|
class Debugger < Base
|
75
75
|
MSG = 'Remove debugger entry point `%<source>s`.'
|
76
|
-
BLOCK_TYPES = %i[block numblock kwbegin].freeze
|
76
|
+
BLOCK_TYPES = %i[block numblock itblock kwbegin].freeze
|
77
77
|
|
78
78
|
def on_send(node)
|
79
79
|
return if assumed_usage_context?(node)
|
@@ -116,11 +116,11 @@ module RuboCop
|
|
116
116
|
|
117
117
|
def assumed_usage_context?(node)
|
118
118
|
# Basically, debugger methods are not used as a method argument without arguments.
|
119
|
-
return false unless node.arguments.empty? && node.each_ancestor(:
|
119
|
+
return false unless node.arguments.empty? && node.each_ancestor(:call).any?
|
120
120
|
return true if assumed_argument?(node)
|
121
121
|
|
122
122
|
node.each_ancestor.none? do |ancestor|
|
123
|
-
|
123
|
+
ancestor.type?(:any_block, :kwbegin) || ancestor.lambda_or_proc?
|
124
124
|
end
|
125
125
|
end
|
126
126
|
|
@@ -33,6 +33,7 @@ module RuboCop
|
|
33
33
|
|
34
34
|
MSG = 'Use `%<constant>s.%<method>s(%<replacement_args>s)` instead of `%<original>s`.'
|
35
35
|
|
36
|
+
RESTRICT_ON_SEND = %i[new digest].freeze
|
36
37
|
NO_ARG_ALGORITHM = %w[BF DES IDEA RC4].freeze
|
37
38
|
|
38
39
|
# @!method algorithm_const(node)
|
@@ -133,7 +134,7 @@ module RuboCop
|
|
133
134
|
if NO_ARG_ALGORITHM.include?(algorithm_parts.first.upcase) && no_arguments
|
134
135
|
"'#{algorithm_parts.first}'"
|
135
136
|
else
|
136
|
-
mode = 'cbc'
|
137
|
+
mode = 'cbc' if size_and_mode.empty?
|
137
138
|
|
138
139
|
"'#{(algorithm_parts + size_and_mode + [mode]).compact.take(3).join('-')}'"
|
139
140
|
end
|
@@ -106,7 +106,7 @@ module RuboCop
|
|
106
106
|
private
|
107
107
|
|
108
108
|
def pattern_identity(pattern)
|
109
|
-
pattern_source = if pattern.
|
109
|
+
pattern_source = if pattern.type?(:hash_pattern, :match_alt)
|
110
110
|
pattern.children.map(&:source).sort.to_s
|
111
111
|
else
|
112
112
|
pattern.source
|
@@ -39,10 +39,52 @@ module RuboCop
|
|
39
39
|
# end
|
40
40
|
#
|
41
41
|
# alias bar foo
|
42
|
+
#
|
43
|
+
# @example AllCops:ActiveSupportExtensionsEnabled: false (default)
|
44
|
+
#
|
45
|
+
# # good
|
46
|
+
# def foo
|
47
|
+
# 1
|
48
|
+
# end
|
49
|
+
#
|
50
|
+
# delegate :foo, to: :bar
|
51
|
+
#
|
52
|
+
# @example AllCops:ActiveSupportExtensionsEnabled: true
|
53
|
+
#
|
54
|
+
# # bad
|
55
|
+
# def foo
|
56
|
+
# 1
|
57
|
+
# end
|
58
|
+
#
|
59
|
+
# delegate :foo, to: :bar
|
60
|
+
#
|
61
|
+
# # good
|
62
|
+
# def foo
|
63
|
+
# 1
|
64
|
+
# end
|
65
|
+
#
|
66
|
+
# delegate :baz, to: :bar
|
67
|
+
#
|
68
|
+
# # good - delegate with splat arguments is ignored
|
69
|
+
# def foo
|
70
|
+
# 1
|
71
|
+
# end
|
72
|
+
#
|
73
|
+
# delegate :foo, **options
|
74
|
+
#
|
75
|
+
# # good - delegate inside a condition is ignored
|
76
|
+
# def foo
|
77
|
+
# 1
|
78
|
+
# end
|
79
|
+
#
|
80
|
+
# if cond
|
81
|
+
# delegate :foo, to: :bar
|
82
|
+
# end
|
83
|
+
#
|
42
84
|
class DuplicateMethods < Base
|
43
85
|
MSG = 'Method `%<method>s` is defined at both %<defined>s and %<current>s.'
|
44
|
-
RESTRICT_ON_SEND = %i[alias_method attr_reader attr_writer attr_accessor attr
|
45
|
-
|
86
|
+
RESTRICT_ON_SEND = %i[alias_method attr_reader attr_writer attr_accessor attr
|
87
|
+
delegate].freeze
|
46
88
|
|
47
89
|
def initialize(config = nil, options = nil)
|
48
90
|
super
|
@@ -54,14 +96,12 @@ module RuboCop
|
|
54
96
|
# if a method definition is inside an if, it is very likely
|
55
97
|
# that a different definition is used depending on platform, etc.
|
56
98
|
return if node.each_ancestor.any?(&:if_type?)
|
57
|
-
return if possible_dsl?(node)
|
58
99
|
|
59
100
|
found_instance_method(node, node.method_name)
|
60
101
|
end
|
61
102
|
|
62
103
|
def on_defs(node)
|
63
104
|
return if node.each_ancestor.any?(&:if_type?)
|
64
|
-
return if possible_dsl?(node)
|
65
105
|
|
66
106
|
if node.receiver.const_type?
|
67
107
|
_, const_name = *node.receiver
|
@@ -79,7 +119,6 @@ module RuboCop
|
|
79
119
|
def on_alias(node)
|
80
120
|
return unless (name = method_alias?(node))
|
81
121
|
return if node.ancestors.any?(&:if_type?)
|
82
|
-
return if possible_dsl?(node)
|
83
122
|
|
84
123
|
found_instance_method(node, name)
|
85
124
|
end
|
@@ -89,16 +128,28 @@ module RuboCop
|
|
89
128
|
(send nil? :alias_method (sym $_name) _)
|
90
129
|
PATTERN
|
91
130
|
|
131
|
+
# @!method delegate_method?(node)
|
132
|
+
def_node_matcher :delegate_method?, <<~PATTERN
|
133
|
+
(send nil? :delegate
|
134
|
+
({sym str} $_)+
|
135
|
+
(hash <(pair (sym :to) {sym str}) ...>)
|
136
|
+
)
|
137
|
+
PATTERN
|
138
|
+
|
92
139
|
# @!method sym_name(node)
|
93
140
|
def_node_matcher :sym_name, '(sym $_name)'
|
94
|
-
|
141
|
+
|
142
|
+
def on_send(node) # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
95
143
|
if (name = alias_method?(node))
|
96
144
|
return if node.ancestors.any?(&:if_type?)
|
97
|
-
return if possible_dsl?(node)
|
98
145
|
|
99
146
|
found_instance_method(node, name)
|
100
147
|
elsif (attr = node.attribute_accessor?)
|
101
148
|
on_attr(node, *attr)
|
149
|
+
elsif active_support_extensions_enabled? && (names = delegate_method?(node))
|
150
|
+
return if node.ancestors.any?(&:if_type?)
|
151
|
+
|
152
|
+
on_delegate(node, names)
|
102
153
|
end
|
103
154
|
end
|
104
155
|
|
@@ -123,6 +174,32 @@ module RuboCop
|
|
123
174
|
current: source_location(node))
|
124
175
|
end
|
125
176
|
|
177
|
+
def on_delegate(node, method_names)
|
178
|
+
name_prefix = delegate_prefix(node)
|
179
|
+
|
180
|
+
method_names.each do |name|
|
181
|
+
name = "#{name_prefix}_#{name}" if name_prefix
|
182
|
+
|
183
|
+
found_instance_method(node, name)
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
def delegate_prefix(node)
|
188
|
+
kwargs_node = node.last_argument
|
189
|
+
|
190
|
+
return unless (prefix = hash_value(kwargs_node, :prefix))
|
191
|
+
|
192
|
+
if prefix.true_type?
|
193
|
+
hash_value(kwargs_node, :to).value
|
194
|
+
elsif prefix.type?(:sym, :str)
|
195
|
+
prefix.value
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
def hash_value(node, key)
|
200
|
+
node.pairs.find { |pair| pair.key.value == key }&.value
|
201
|
+
end
|
202
|
+
|
126
203
|
def found_instance_method(node, name)
|
127
204
|
return found_sclass_method(node, name) unless (scope = node.parent_module_name)
|
128
205
|
|
@@ -166,7 +243,7 @@ module RuboCop
|
|
166
243
|
end
|
167
244
|
|
168
245
|
def method_key(node, method_name)
|
169
|
-
if (ancestor_def = node.each_ancestor(
|
246
|
+
if (ancestor_def = node.each_ancestor(:any_def).first)
|
170
247
|
"#{ancestor_def.method_name}.#{method_name}"
|
171
248
|
else
|
172
249
|
method_name
|
@@ -174,7 +251,7 @@ module RuboCop
|
|
174
251
|
end
|
175
252
|
|
176
253
|
def location(node)
|
177
|
-
if
|
254
|
+
if node.any_def_type?
|
178
255
|
node.loc.keyword.join(node.loc.name)
|
179
256
|
else
|
180
257
|
node.source_range
|
@@ -237,16 +314,6 @@ module RuboCop
|
|
237
314
|
end
|
238
315
|
end
|
239
316
|
|
240
|
-
def possible_dsl?(node)
|
241
|
-
# DSL methods may evaluate a block in the context of a newly created
|
242
|
-
# class or module
|
243
|
-
# Assume that if a method definition is inside any block call which
|
244
|
-
# we can't identify, it could be a DSL
|
245
|
-
node.each_ancestor(:block).any? do |ancestor|
|
246
|
-
!ancestor.method?(:class_eval) && !ancestor.class_constructor?
|
247
|
-
end
|
248
|
-
end
|
249
|
-
|
250
317
|
def source_location(node)
|
251
318
|
range = node.source_range
|
252
319
|
path = smart_path(range.source_buffer.name)
|
@@ -3,7 +3,7 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module Lint
|
6
|
-
# Checks for duplicate literal, constant, or variable elements in Set
|
6
|
+
# Checks for duplicate literal, constant, or variable elements in `Set` and `SortedSet`.
|
7
7
|
#
|
8
8
|
# @example
|
9
9
|
#
|
@@ -25,17 +25,28 @@ module RuboCop
|
|
25
25
|
# # good
|
26
26
|
# [:foo, :bar].to_set
|
27
27
|
#
|
28
|
+
# # bad
|
29
|
+
# SortedSet[:foo, :bar, :foo]
|
30
|
+
#
|
31
|
+
# # good
|
32
|
+
# SortedSet[:foo, :bar]
|
33
|
+
#
|
34
|
+
# # bad
|
35
|
+
# SortedSet.new([:foo, :bar, :foo])
|
36
|
+
#
|
37
|
+
# # good
|
38
|
+
# SortedSet.new([:foo, :bar])
|
28
39
|
class DuplicateSetElement < Base
|
29
40
|
extend AutoCorrector
|
30
41
|
|
31
|
-
MSG = 'Remove the duplicate element in
|
42
|
+
MSG = 'Remove the duplicate element in %<class_name>s.'
|
32
43
|
RESTRICT_ON_SEND = %i[\[\] new to_set].freeze
|
33
44
|
|
34
45
|
# @!method set_init_elements(node)
|
35
46
|
def_node_matcher :set_init_elements, <<~PATTERN
|
36
47
|
{
|
37
|
-
(send (const {nil? cbase} :Set) :[] $...)
|
38
|
-
(send (const {nil? cbase} :Set) :new (array $...))
|
48
|
+
(send (const {nil? cbase} {:Set :SortedSet}) :[] $...)
|
49
|
+
(send (const {nil? cbase} {:Set :SortedSet}) :new (array $...))
|
39
50
|
(call (array $...) :to_set)
|
40
51
|
}
|
41
52
|
PATTERN
|
@@ -51,7 +62,7 @@ module RuboCop
|
|
51
62
|
next if !set_element.literal? && !set_element.const_type? && !set_element.variable?
|
52
63
|
|
53
64
|
if seen_elements.include?(set_element)
|
54
|
-
register_offense(set_element, set_elements[index - 1])
|
65
|
+
register_offense(set_element, set_elements[index - 1], node)
|
55
66
|
else
|
56
67
|
seen_elements << set_element
|
57
68
|
end
|
@@ -61,8 +72,10 @@ module RuboCop
|
|
61
72
|
|
62
73
|
private
|
63
74
|
|
64
|
-
def register_offense(current_element, prev_element)
|
65
|
-
|
75
|
+
def register_offense(current_element, prev_element, node)
|
76
|
+
class_name = node.receiver.const_type? ? node.receiver.const_name : 'Set'
|
77
|
+
|
78
|
+
add_offense(current_element, message: format(MSG, class_name: class_name)) do |corrector|
|
66
79
|
range = prev_element.source_range.end.join(current_element.source_range.end)
|
67
80
|
|
68
81
|
corrector.remove(range)
|
@@ -7,11 +7,6 @@ module RuboCop
|
|
7
7
|
#
|
8
8
|
# NOTE: empty `else` branches are handled by `Style/EmptyElse`.
|
9
9
|
#
|
10
|
-
# @safety
|
11
|
-
# Autocorrection for this cop is not safe. The conditions for empty branches that
|
12
|
-
# the autocorrection removes may have side effects, or the logic in subsequent
|
13
|
-
# branches may change due to the removal of a previous condition.
|
14
|
-
#
|
15
10
|
# @example
|
16
11
|
# # bad
|
17
12
|
# if condition
|
@@ -41,6 +36,13 @@ module RuboCop
|
|
41
36
|
# if condition
|
42
37
|
# do_something
|
43
38
|
# elsif other_condition
|
39
|
+
# nil
|
40
|
+
# end
|
41
|
+
#
|
42
|
+
# # good
|
43
|
+
# if condition
|
44
|
+
# do_something
|
45
|
+
# elsif other_condition
|
44
46
|
# do_something_else
|
45
47
|
# end
|
46
48
|
#
|
@@ -63,11 +65,9 @@ module RuboCop
|
|
63
65
|
class EmptyConditionalBody < Base
|
64
66
|
extend AutoCorrector
|
65
67
|
include CommentsHelp
|
66
|
-
include RangeHelp
|
67
68
|
|
68
69
|
MSG = 'Avoid `%<keyword>s` branches without a body.'
|
69
70
|
|
70
|
-
# rubocop:disable Metrics/AbcSize
|
71
71
|
def on_if(node)
|
72
72
|
return if node.body || same_line?(node.loc.begin, node.loc.end)
|
73
73
|
return if cop_config['AllowComments'] && contains_comments?(node)
|
@@ -75,12 +75,11 @@ module RuboCop
|
|
75
75
|
range = offense_range(node)
|
76
76
|
|
77
77
|
add_offense(range, message: format(MSG, keyword: node.keyword)) do |corrector|
|
78
|
-
next
|
78
|
+
next unless can_simplify_conditional?(node)
|
79
79
|
|
80
|
-
|
80
|
+
flip_orphaned_else(corrector, node)
|
81
81
|
end
|
82
82
|
end
|
83
|
-
# rubocop:enable Metrics/AbcSize
|
84
83
|
|
85
84
|
private
|
86
85
|
|
@@ -92,53 +91,23 @@ module RuboCop
|
|
92
91
|
end
|
93
92
|
end
|
94
93
|
|
95
|
-
def
|
96
|
-
|
97
|
-
remove_empty_branch(corrector, node)
|
98
|
-
correct_other_branches(corrector, node)
|
99
|
-
end
|
100
|
-
|
101
|
-
def remove_comments(corrector, node)
|
102
|
-
comments_in_range(node).each do |comment|
|
103
|
-
range = range_by_whole_lines(comment.source_range, include_final_newline: true)
|
104
|
-
corrector.remove(range)
|
105
|
-
end
|
94
|
+
def can_simplify_conditional?(node)
|
95
|
+
node.else_branch && node.loc.else.source == 'else'
|
106
96
|
end
|
107
97
|
|
108
|
-
# rubocop:disable Metrics/AbcSize
|
109
98
|
def remove_empty_branch(corrector, node)
|
110
99
|
range = if empty_if_branch?(node) && else_branch?(node)
|
111
100
|
branch_range(node)
|
112
|
-
elsif same_line?(node, else_kw_loc = node.loc.else)
|
113
|
-
node.source_range.begin.join(else_kw_loc.begin)
|
114
|
-
elsif node.parent&.loc.respond_to?(:end) &&
|
115
|
-
same_line?(node, end_loc = node.parent.loc.end)
|
116
|
-
node.source_range.begin.join(end_loc.begin)
|
117
101
|
else
|
118
102
|
deletion_range(branch_range(node))
|
119
103
|
end
|
120
104
|
|
121
105
|
corrector.remove(range)
|
122
106
|
end
|
123
|
-
# rubocop:enable Metrics/AbcSize
|
124
|
-
|
125
|
-
def correct_other_branches(corrector, node)
|
126
|
-
return unless require_other_branches_correction?(node)
|
127
|
-
|
128
|
-
if node.else_branch&.if_type? && !node.else_branch.modifier_form?
|
129
|
-
# Replace an orphaned `elsif` with `if`
|
130
|
-
corrector.replace(node.else_branch.loc.keyword, 'if')
|
131
|
-
else
|
132
|
-
# Flip orphaned `else`
|
133
|
-
corrector.replace(node.loc.else, "#{node.inverse_keyword} #{node.condition.source}")
|
134
|
-
end
|
135
|
-
end
|
136
|
-
|
137
|
-
def require_other_branches_correction?(node)
|
138
|
-
return false unless node.if_type? && node.else?
|
139
|
-
return false if !empty_if_branch?(node) && node.elsif?
|
140
107
|
|
141
|
-
|
108
|
+
def flip_orphaned_else(corrector, node)
|
109
|
+
corrector.replace(node.loc.else, "#{node.inverse_keyword} #{node.condition.source}")
|
110
|
+
remove_empty_branch(corrector, node)
|
142
111
|
end
|
143
112
|
|
144
113
|
def empty_if_branch?(node)
|
@@ -149,36 +118,17 @@ module RuboCop
|
|
149
118
|
if_branch.if_type? && !if_branch.body
|
150
119
|
end
|
151
120
|
|
152
|
-
def empty_elsif_branch?(node)
|
153
|
-
return false unless (else_branch = node.else_branch)
|
154
|
-
|
155
|
-
else_branch.if_type? && !else_branch.body
|
156
|
-
end
|
157
|
-
|
158
121
|
def else_branch?(node)
|
159
122
|
node.else_branch && !node.else_branch.if_type?
|
160
123
|
end
|
161
124
|
|
162
|
-
# rubocop:disable Metrics/AbcSize
|
163
125
|
def branch_range(node)
|
164
126
|
if empty_if_branch?(node) && else_branch?(node)
|
165
127
|
node.source_range.with(end_pos: node.loc.else.begin_pos)
|
166
128
|
elsif node.loc.else
|
167
129
|
node.source_range.with(end_pos: node.condition.source_range.end_pos)
|
168
|
-
elsif all_branches_body_missing?(node)
|
169
|
-
if_node = node.ancestors.detect(&:if?)
|
170
|
-
node.source_range.join(if_node.loc.end.end)
|
171
|
-
else
|
172
|
-
node.source_range
|
173
130
|
end
|
174
131
|
end
|
175
|
-
# rubocop:enable Metrics/AbcSize
|
176
|
-
|
177
|
-
def all_branches_body_missing?(node)
|
178
|
-
return false unless node.parent&.if_type?
|
179
|
-
|
180
|
-
node.parent.branches.compact.empty?
|
181
|
-
end
|
182
132
|
|
183
133
|
def deletion_range(range)
|
184
134
|
# Collect a range between the start of the `if` node and the next relevant node,
|