rubocop 1.67.0 → 1.75.7
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 +266 -47
- data/config/internal_affairs.yml +20 -0
- data/config/obsoletion.yml +3 -1
- data/lib/rubocop/cached_data.rb +12 -4
- data/lib/rubocop/cli/command/execute_runner.rb +4 -4
- data/lib/rubocop/cli/command/show_cops.rb +24 -2
- data/lib/rubocop/cli/command/suggest_extensions.rb +7 -1
- data/lib/rubocop/cli/command/version.rb +2 -2
- data/lib/rubocop/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 +36 -19
- data/lib/rubocop/cop/base.rb +7 -1
- data/lib/rubocop/cop/bundler/duplicated_gem.rb +2 -2
- data/lib/rubocop/cop/bundler/gem_comment.rb +1 -1
- data/lib/rubocop/cop/bundler/gem_filename.rb +0 -1
- data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +0 -1
- data/lib/rubocop/cop/correctors/alignment_corrector.rb +1 -12
- data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +1 -1
- data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +10 -0
- data/lib/rubocop/cop/gemspec/deprecated_attribute_assignment.rb +1 -2
- data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +49 -5
- data/lib/rubocop/cop/gemspec/required_ruby_version.rb +0 -2
- data/lib/rubocop/cop/generator.rb +6 -0
- data/lib/rubocop/cop/internal_affairs/cop_enabled.rb +85 -0
- data/lib/rubocop/cop/internal_affairs/example_description.rb +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 +3 -4
- data/lib/rubocop/cop/internal_affairs/node_first_or_last_argument.rb +3 -2
- data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_processor.rb +63 -0
- data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_walker.rb +131 -0
- data/lib/rubocop/cop/internal_affairs/node_pattern_groups.rb +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/numblock_handler.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/on_send_without_on_csend.rb +90 -0
- data/lib/rubocop/cop/internal_affairs/operator_keyword.rb +48 -0
- data/lib/rubocop/cop/internal_affairs/plugin.rb +33 -0
- data/lib/rubocop/cop/internal_affairs/redundant_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/style_detected_api_use.rb +0 -2
- data/lib/rubocop/cop/internal_affairs/undefined_config.rb +13 -2
- data/lib/rubocop/cop/internal_affairs.rb +7 -16
- data/lib/rubocop/cop/layout/access_modifier_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/argument_alignment.rb +2 -9
- data/lib/rubocop/cop/layout/array_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/begin_end_alignment.rb +0 -1
- data/lib/rubocop/cop/layout/block_alignment.rb +3 -2
- data/lib/rubocop/cop/layout/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 +3 -3
- data/lib/rubocop/cop/layout/empty_line_between_defs.rb +7 -11
- data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +30 -4
- 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 +4 -5
- data/lib/rubocop/cop/layout/empty_lines_around_method_body.rb +23 -1
- data/lib/rubocop/cop/layout/end_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/extra_spacing.rb +1 -1
- data/lib/rubocop/cop/layout/first_argument_indentation.rb +3 -8
- data/lib/rubocop/cop/layout/first_array_element_indentation.rb +2 -7
- data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +2 -7
- data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +1 -1
- data/lib/rubocop/cop/layout/first_parameter_indentation.rb +2 -2
- data/lib/rubocop/cop/layout/hash_alignment.rb +8 -6
- data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +2 -1
- data/lib/rubocop/cop/layout/indentation_width.rb +8 -7
- data/lib/rubocop/cop/layout/leading_comment_space.rb +57 -2
- 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 +123 -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 +2 -1
- data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +4 -4
- data/lib/rubocop/cop/layout/multiline_method_definition_brace_layout.rb +1 -1
- data/lib/rubocop/cop/layout/multiline_method_parameter_line_breaks.rb +1 -0
- data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +3 -4
- data/lib/rubocop/cop/layout/parameter_alignment.rb +3 -4
- data/lib/rubocop/cop/layout/redundant_line_break.rb +19 -46
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +6 -7
- 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 +2 -1
- data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +1 -1
- data/lib/rubocop/cop/layout/space_around_operators.rb +23 -21
- data/lib/rubocop/cop/layout/space_before_block_braces.rb +1 -0
- data/lib/rubocop/cop/layout/space_before_brackets.rb +8 -34
- 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 +11 -1
- data/lib/rubocop/cop/layout/space_inside_block_braces.rb +5 -0
- data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +7 -0
- data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +0 -1
- data/lib/rubocop/cop/layout/trailing_whitespace.rb +5 -3
- data/lib/rubocop/cop/lint/ambiguous_block_association.rb +1 -1
- data/lib/rubocop/cop/lint/array_literal_in_regexp.rb +118 -0
- data/lib/rubocop/cop/lint/assignment_in_condition.rb +1 -3
- data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +10 -12
- data/lib/rubocop/cop/lint/boolean_symbol.rb +1 -1
- data/lib/rubocop/cop/lint/circular_argument_reference.rb +4 -1
- 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 +3 -2
- data/lib/rubocop/cop/lint/duplicate_branch.rb +39 -4
- data/lib/rubocop/cop/lint/duplicate_match_pattern.rb +1 -1
- data/lib/rubocop/cop/lint/duplicate_methods.rb +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_ensure.rb +1 -1
- data/lib/rubocop/cop/lint/empty_expression.rb +0 -2
- data/lib/rubocop/cop/lint/empty_file.rb +0 -2
- data/lib/rubocop/cop/lint/ensure_return.rb +1 -1
- data/lib/rubocop/cop/lint/erb_new_arguments.rb +0 -6
- data/lib/rubocop/cop/lint/float_comparison.rb +20 -14
- data/lib/rubocop/cop/lint/float_out_of_range.rb +2 -4
- data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +2 -2
- data/lib/rubocop/cop/lint/hash_new_with_keyword_arguments_as_default.rb +55 -0
- data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +1 -1
- data/lib/rubocop/cop/lint/interpolation_check.rb +9 -0
- data/lib/rubocop/cop/lint/it_without_arguments_in_block.rb +3 -0
- data/lib/rubocop/cop/lint/literal_as_condition.rb +118 -9
- data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +1 -1
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +24 -6
- data/lib/rubocop/cop/lint/missing_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 +5 -8
- data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +1 -1
- data/lib/rubocop/cop/lint/nested_method_definition.rb +10 -6
- data/lib/rubocop/cop/lint/next_without_accumulator.rb +1 -1
- data/lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +2 -2
- data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +12 -3
- data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +3 -3
- data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +3 -3
- data/lib/rubocop/cop/lint/number_conversion.rb +0 -1
- data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +1 -2
- data/lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +93 -0
- data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +2 -3
- data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +3 -2
- data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +1 -5
- data/lib/rubocop/cop/lint/raise_exception.rb +29 -10
- data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +1 -1
- data/lib/rubocop/cop/lint/redundant_regexp_quantifiers.rb +1 -1
- data/lib/rubocop/cop/lint/redundant_require_statement.rb +0 -21
- data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +12 -7
- data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +8 -7
- data/lib/rubocop/cop/lint/redundant_string_coercion.rb +2 -2
- data/lib/rubocop/cop/lint/redundant_type_conversion.rb +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/regexp_as_condition.rb +0 -1
- data/lib/rubocop/cop/lint/rescue_exception.rb +1 -1
- data/lib/rubocop/cop/lint/rescue_type.rb +3 -7
- data/lib/rubocop/cop/lint/return_in_void_context.rb +9 -11
- data/lib/rubocop/cop/lint/safe_navigation_chain.rb +17 -1
- data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +5 -1
- data/lib/rubocop/cop/lint/self_assignment.rb +8 -10
- data/lib/rubocop/cop/lint/shadowed_exception.rb +1 -1
- data/lib/rubocop/cop/lint/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 +88 -0
- 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/unused_method_argument.rb +18 -2
- 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_defined.rb +55 -0
- data/lib/rubocop/cop/lint/useless_else_without_rescue.rb +4 -0
- data/lib/rubocop/cop/lint/useless_method_definition.rb +1 -1
- data/lib/rubocop/cop/lint/useless_numeric_operation.rb +2 -1
- data/lib/rubocop/cop/lint/useless_rescue.rb +2 -2
- data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +2 -2
- data/lib/rubocop/cop/lint/useless_setter_call.rb +14 -25
- data/lib/rubocop/cop/lint/void.rb +16 -12
- 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 +5 -2
- 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/abc_size_calculator.rb +1 -1
- data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +3 -4
- data/lib/rubocop/cop/metrics/utils/repeated_attribute_discount.rb +7 -7
- data/lib/rubocop/cop/mixin/alignment.rb +2 -2
- data/lib/rubocop/cop/mixin/allowed_pattern.rb +4 -4
- data/lib/rubocop/cop/mixin/check_assignment.rb +4 -12
- data/lib/rubocop/cop/mixin/check_line_breakable.rb +22 -12
- data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +49 -0
- data/lib/rubocop/cop/mixin/comments_help.rb +8 -3
- data/lib/rubocop/cop/mixin/def_node.rb +1 -1
- data/lib/rubocop/cop/mixin/dig_help.rb +27 -0
- data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +1 -1
- data/lib/rubocop/cop/mixin/endless_method_rewriter.rb +24 -0
- 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 +3 -2
- 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 +7 -9
- data/lib/rubocop/cop/mixin/percent_literal.rb +1 -1
- data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +68 -30
- data/lib/rubocop/cop/mixin/range_help.rb +15 -4
- data/lib/rubocop/cop/mixin/space_before_punctuation.rb +1 -1
- data/lib/rubocop/cop/mixin/statement_modifier.rb +8 -3
- data/lib/rubocop/cop/mixin/string_help.rb +2 -2
- data/lib/rubocop/cop/mixin/string_literals_help.rb +1 -1
- data/lib/rubocop/cop/mixin/target_ruby_version.rb +17 -1
- data/lib/rubocop/cop/mixin/trailing_comma.rb +21 -5
- data/lib/rubocop/cop/naming/accessor_method_name.rb +6 -6
- data/lib/rubocop/cop/naming/block_forwarding.rb +20 -16
- data/lib/rubocop/cop/naming/constant_name.rb +6 -7
- data/lib/rubocop/cop/naming/file_name.rb +0 -2
- data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +12 -13
- 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 +6 -14
- data/lib/rubocop/cop/naming/variable_name.rb +50 -6
- data/lib/rubocop/cop/naming/variable_number.rb +2 -3
- data/lib/rubocop/cop/offense.rb +2 -3
- 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 +114 -34
- data/lib/rubocop/cop/style/accessor_grouping.rb +19 -5
- data/lib/rubocop/cop/style/ambiguous_endless_method_definition.rb +79 -0
- data/lib/rubocop/cop/style/and_or.rb +1 -1
- data/lib/rubocop/cop/style/arguments_forwarding.rb +47 -28
- data/lib/rubocop/cop/style/array_first_last.rb +18 -2
- data/lib/rubocop/cop/style/array_intersect.rb +42 -30
- data/lib/rubocop/cop/style/bitwise_predicate.rb +100 -0
- data/lib/rubocop/cop/style/block_delimiters.rb +43 -25
- data/lib/rubocop/cop/style/case_like_if.rb +8 -11
- 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 +115 -0
- 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 +20 -3
- 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 +39 -27
- data/lib/rubocop/cop/style/constant_visibility.rb +3 -12
- data/lib/rubocop/cop/style/data_inheritance.rb +7 -0
- data/lib/rubocop/cop/style/dig_chain.rb +89 -0
- data/lib/rubocop/cop/style/documentation.rb +1 -1
- data/lib/rubocop/cop/style/double_negation.rb +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 +150 -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 +89 -0
- data/lib/rubocop/cop/style/file_touch.rb +75 -0
- data/lib/rubocop/cop/style/float_division.rb +8 -4
- data/lib/rubocop/cop/style/for.rb +1 -1
- 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/global_vars.rb +1 -3
- data/lib/rubocop/cop/style/guard_clause.rb +17 -3
- data/lib/rubocop/cop/style/hash_conversion.rb +1 -2
- 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 -14
- data/lib/rubocop/cop/style/if_unless_modifier.rb +25 -5
- 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 +3 -4
- data/lib/rubocop/cop/style/if_with_semicolon.rb +20 -9
- data/lib/rubocop/cop/style/infinite_loop.rb +1 -1
- data/lib/rubocop/cop/style/inverse_methods.rb +15 -12
- 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_arguments_merging.rb +67 -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 -4
- data/lib/rubocop/cop/style/line_end_concatenation.rb +10 -4
- data/lib/rubocop/cop/style/map_into_array.rb +11 -3
- 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 +27 -17
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +2 -0
- data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +8 -11
- data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +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/missing_respond_to_missing.rb +33 -3
- 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_memoization.rb +1 -1
- data/lib/rubocop/cop/style/multiline_method_signature.rb +1 -9
- data/lib/rubocop/cop/style/multiple_comparison.rb +52 -51
- data/lib/rubocop/cop/style/mutable_constant.rb +7 -8
- data/lib/rubocop/cop/style/negated_if_else_condition.rb +7 -5
- data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +1 -1
- data/lib/rubocop/cop/style/nested_ternary_operator.rb +5 -4
- data/lib/rubocop/cop/style/next.rb +44 -0
- data/lib/rubocop/cop/style/not.rb +1 -1
- data/lib/rubocop/cop/style/object_then.rb +15 -15
- data/lib/rubocop/cop/style/one_line_conditional.rb +25 -4
- data/lib/rubocop/cop/style/open_struct_use.rb +5 -5
- data/lib/rubocop/cop/style/operator_method_call.rb +5 -6
- data/lib/rubocop/cop/style/or_assignment.rb +3 -6
- data/lib/rubocop/cop/style/parallel_assignment.rb +9 -18
- data/lib/rubocop/cop/style/parentheses_around_condition.rb +2 -2
- data/lib/rubocop/cop/style/percent_literal_delimiters.rb +1 -1
- data/lib/rubocop/cop/style/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 +15 -13
- data/lib/rubocop/cop/style/random_with_offset.rb +3 -3
- data/lib/rubocop/cop/style/redundant_argument.rb +3 -1
- data/lib/rubocop/cop/style/redundant_assignment.rb +1 -1
- data/lib/rubocop/cop/style/redundant_begin.rb +2 -1
- data/lib/rubocop/cop/style/redundant_condition.rb +95 -23
- 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 +54 -18
- data/lib/rubocop/cop/style/redundant_parentheses.rb +56 -26
- data/lib/rubocop/cop/style/redundant_regexp_argument.rb +4 -0
- data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +1 -1
- data/lib/rubocop/cop/style/redundant_regexp_escape.rb +1 -1
- data/lib/rubocop/cop/style/redundant_return.rb +2 -2
- data/lib/rubocop/cop/style/redundant_self.rb +9 -15
- data/lib/rubocop/cop/style/redundant_self_assignment.rb +20 -32
- data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +4 -4
- data/lib/rubocop/cop/style/redundant_sort.rb +3 -3
- data/lib/rubocop/cop/style/redundant_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 +5 -3
- data/lib/rubocop/cop/style/return_nil.rb +2 -2
- data/lib/rubocop/cop/style/safe_navigation.rb +32 -5
- data/lib/rubocop/cop/style/safe_navigation_chain_length.rb +52 -0
- data/lib/rubocop/cop/style/select_by_regexp.rb +5 -2
- data/lib/rubocop/cop/style/self_assignment.rb +11 -17
- data/lib/rubocop/cop/style/semicolon.rb +1 -1
- data/lib/rubocop/cop/style/send_with_literal_method_name.rb +2 -1
- data/lib/rubocop/cop/style/signal_exception.rb +2 -3
- data/lib/rubocop/cop/style/single_argument_dig.rb +9 -5
- data/lib/rubocop/cop/style/single_line_block_params.rb +1 -1
- data/lib/rubocop/cop/style/single_line_do_end_block.rb +15 -4
- 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 -106
- data/lib/rubocop/cop/style/special_global_vars.rb +1 -1
- data/lib/rubocop/cop/style/string_concatenation.rb +15 -15
- 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/swap_values.rb +4 -15
- data/lib/rubocop/cop/style/symbol_proc.rb +2 -0
- data/lib/rubocop/cop/style/ternary_parentheses.rb +25 -4
- 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/trailing_underscore_variable.rb +4 -4
- data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
- data/lib/rubocop/cop/style/variable_interpolation.rb +1 -2
- data/lib/rubocop/cop/style/while_until_modifier.rb +0 -1
- data/lib/rubocop/cop/style/yoda_condition.rb +8 -4
- data/lib/rubocop/cop/style/yoda_expression.rb +2 -1
- data/lib/rubocop/cop/util.rb +12 -5
- data/lib/rubocop/cop/utils/format_string.rb +10 -5
- data/lib/rubocop/cop/variable_force/assignment.rb +24 -5
- data/lib/rubocop/cop/variable_force/branch.rb +1 -1
- data/lib/rubocop/cop/variable_force/scope.rb +1 -1
- data/lib/rubocop/cop/variable_force/variable.rb +14 -3
- data/lib/rubocop/cop/variable_force/variable_table.rb +5 -5
- data/lib/rubocop/cop/variable_force.rb +5 -11
- data/lib/rubocop/cops_documentation_generator.rb +50 -25
- 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 +3 -2
- 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 +6 -2
- data/lib/rubocop/rspec/shared_contexts.rb +38 -1
- data/lib/rubocop/rspec/support.rb +4 -2
- data/lib/rubocop/runner.rb +26 -15
- 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 +17 -2
- data/lib/rubocop/version.rb +53 -12
- data/lib/rubocop.rb +32 -1
- data/lib/ruby_lsp/rubocop/addon.rb +75 -0
- data/lib/ruby_lsp/rubocop/runtime_adapter.rb +65 -0
- metadata +79 -20
- data/lib/rubocop/cop/utils/regexp_ranges.rb +0 -113
- data/lib/rubocop/rspec/host_environment_simulation_helper.rb +0 -28
@@ -5,17 +5,16 @@ module RuboCop
|
|
5
5
|
module Lint
|
6
6
|
# Checks for places where binary operator has identical operands.
|
7
7
|
#
|
8
|
-
# It covers
|
9
|
-
# comparison operators: `==`, `===`, `=~`, `>`, `>=`, `<`, ``<=``;
|
8
|
+
# It covers comparison operators: `==`, `===`, `=~`, `>`, `>=`, `<`, ``<=``;
|
10
9
|
# bitwise operators: `|`, `^`, `&`;
|
11
10
|
# boolean operators: `&&`, `||`
|
12
11
|
# and "spaceship" operator - ``<=>``.
|
13
12
|
#
|
14
13
|
# Simple arithmetic operations are allowed by this cop: `+`, `*`, `**`, `<<` and `>>`.
|
15
14
|
# Although these can be rewritten in a different way, it should not be necessary to
|
16
|
-
# do so.
|
17
|
-
#
|
18
|
-
#
|
15
|
+
# do so. Operations such as `-` or `/` where the result will always be the same
|
16
|
+
# (`x - x` will always be 0; `x / x` will always be 1) are offenses, but these
|
17
|
+
# are covered by `Lint/NumericOperationWithConstantResult` instead.
|
19
18
|
#
|
20
19
|
# @safety
|
21
20
|
# This cop is unsafe as it does not consider side effects when calling methods
|
@@ -30,7 +29,6 @@ module RuboCop
|
|
30
29
|
#
|
31
30
|
# @example
|
32
31
|
# # bad
|
33
|
-
# x / x
|
34
32
|
# x.top >= x.top
|
35
33
|
#
|
36
34
|
# if a.x != 0 && a.x != 0
|
@@ -47,19 +45,19 @@ module RuboCop
|
|
47
45
|
#
|
48
46
|
class BinaryOperatorWithIdenticalOperands < Base
|
49
47
|
MSG = 'Binary operator `%<op>s` has identical operands.'
|
50
|
-
|
48
|
+
RESTRICT_ON_SEND = %i[== != === <=> =~ && || > >= < <= | ^].freeze
|
51
49
|
|
52
50
|
def on_send(node)
|
53
51
|
return unless node.binary_operation?
|
52
|
+
return unless node.receiver == node.first_argument
|
54
53
|
|
55
|
-
|
56
|
-
return if ALLOWED_MATH_OPERATORS.include?(node.method_name)
|
57
|
-
|
58
|
-
add_offense(node, message: format(MSG, op: operation)) if lhs == rhs
|
54
|
+
add_offense(node, message: format(MSG, op: node.method_name))
|
59
55
|
end
|
60
56
|
|
61
57
|
def on_and(node)
|
62
|
-
|
58
|
+
return unless node.lhs == node.rhs
|
59
|
+
|
60
|
+
add_offense(node, message: format(MSG, op: node.operator))
|
63
61
|
end
|
64
62
|
alias on_or on_and
|
65
63
|
end
|
@@ -48,7 +48,7 @@ module RuboCop
|
|
48
48
|
def autocorrect(corrector, node)
|
49
49
|
boolean_literal = node.source.delete(':')
|
50
50
|
parent = node.parent
|
51
|
-
if parent&.pair_type? && node.equal?(parent.children[0])
|
51
|
+
if parent&.pair_type? && parent.colon? && node.equal?(parent.children[0])
|
52
52
|
corrector.remove(parent.loc.operator)
|
53
53
|
boolean_literal = "#{node.source} =>"
|
54
54
|
end
|
@@ -6,7 +6,8 @@ module RuboCop
|
|
6
6
|
# Checks for circular argument references in optional keyword
|
7
7
|
# arguments and optional ordinal arguments.
|
8
8
|
#
|
9
|
-
# This
|
9
|
+
# NOTE: This syntax was made invalid on Ruby 2.7 - Ruby 3.3 but is allowed
|
10
|
+
# again since Ruby 3.4.
|
10
11
|
#
|
11
12
|
# @example
|
12
13
|
#
|
@@ -35,6 +36,8 @@ module RuboCop
|
|
35
36
|
# dry_ingredients.combine
|
36
37
|
# end
|
37
38
|
class CircularArgumentReference < Base
|
39
|
+
extend TargetRubyVersion
|
40
|
+
|
38
41
|
MSG = 'Circular argument reference - `%<arg_name>s`.'
|
39
42
|
|
40
43
|
def on_kwoptarg(node)
|
@@ -68,12 +68,12 @@ module RuboCop
|
|
68
68
|
|
69
69
|
# @!method constant_assigned_in_block?(node)
|
70
70
|
def_node_matcher :constant_assigned_in_block?, <<~PATTERN
|
71
|
-
({^
|
71
|
+
({^any_block [^begin ^^any_block]} nil? ...)
|
72
72
|
PATTERN
|
73
73
|
|
74
74
|
# @!method module_defined_in_block?(node)
|
75
75
|
def_node_matcher :module_defined_in_block?, <<~PATTERN
|
76
|
-
({^
|
76
|
+
({^any_block [^begin ^^any_block]} ...)
|
77
77
|
PATTERN
|
78
78
|
|
79
79
|
def on_casgn(node)
|
@@ -92,7 +92,7 @@ module RuboCop
|
|
92
92
|
private
|
93
93
|
|
94
94
|
def method_name(node)
|
95
|
-
node.ancestors.find(&:
|
95
|
+
node.ancestors.find(&:any_block_type?).method_name
|
96
96
|
end
|
97
97
|
end
|
98
98
|
end
|
@@ -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)
|
@@ -51,7 +52,7 @@ module RuboCop
|
|
51
52
|
PATTERN
|
52
53
|
|
53
54
|
def on_send(node)
|
54
|
-
return if node.arguments.any? { |arg| arg.variable? || arg.
|
55
|
+
return if node.arguments.any? { |arg| arg.variable? || arg.call_type? || arg.const_type? }
|
55
56
|
return if digest_const?(node.receiver)
|
56
57
|
return unless algorithm_const(node)
|
57
58
|
|
@@ -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
|
@@ -15,6 +15,9 @@ module RuboCop
|
|
15
15
|
# With `IgnoreConstantBranches: true`, branches are not registered
|
16
16
|
# as offenses if they return a constant value.
|
17
17
|
#
|
18
|
+
# With `IgnoreDuplicateElseBranch: true`, in conditionals with multiple branches,
|
19
|
+
# duplicate 'else' branches are not registered as offenses.
|
20
|
+
#
|
18
21
|
# @example
|
19
22
|
# # bad
|
20
23
|
# if foo
|
@@ -83,21 +86,37 @@ module RuboCop
|
|
83
86
|
# else MEDIUM_SIZE
|
84
87
|
# end
|
85
88
|
#
|
89
|
+
# @example IgnoreDuplicateElseBranch: true
|
90
|
+
# # good
|
91
|
+
# if foo
|
92
|
+
# do_foo
|
93
|
+
# elsif bar
|
94
|
+
# do_bar
|
95
|
+
# else
|
96
|
+
# do_foo
|
97
|
+
# end
|
98
|
+
#
|
86
99
|
class DuplicateBranch < Base
|
87
100
|
MSG = 'Duplicate branch body detected.'
|
88
101
|
|
89
102
|
def on_branching_statement(node)
|
90
|
-
branches(node)
|
91
|
-
|
103
|
+
branches = branches(node)
|
104
|
+
branches.each_with_object(Set.new) do |branch, previous|
|
105
|
+
next unless consider_branch?(branches, branch)
|
92
106
|
|
93
107
|
add_offense(offense_range(branch)) unless previous.add?(branch)
|
94
108
|
end
|
95
109
|
end
|
96
|
-
alias on_if on_branching_statement
|
97
110
|
alias on_case on_branching_statement
|
98
111
|
alias on_case_match on_branching_statement
|
99
112
|
alias on_rescue on_branching_statement
|
100
113
|
|
114
|
+
def on_if(node)
|
115
|
+
# Ignore 'elsif' nodes, because we don't want to check them separately whether
|
116
|
+
# the 'else' branch is duplicated. We want to check only on the outermost conditional.
|
117
|
+
on_branching_statement(node) unless node.elsif?
|
118
|
+
end
|
119
|
+
|
101
120
|
private
|
102
121
|
|
103
122
|
def offense_range(duplicate_branch)
|
@@ -118,10 +137,14 @@ module RuboCop
|
|
118
137
|
node.branches.compact
|
119
138
|
end
|
120
139
|
|
121
|
-
def consider_branch?(branch)
|
140
|
+
def consider_branch?(branches, branch)
|
122
141
|
return false if ignore_literal_branches? && literal_branch?(branch)
|
123
142
|
return false if ignore_constant_branches? && const_branch?(branch)
|
124
143
|
|
144
|
+
if ignore_duplicate_else_branches? && duplicate_else_branch?(branches, branch)
|
145
|
+
return false
|
146
|
+
end
|
147
|
+
|
125
148
|
true
|
126
149
|
end
|
127
150
|
|
@@ -133,6 +156,10 @@ module RuboCop
|
|
133
156
|
cop_config.fetch('IgnoreConstantBranches', false)
|
134
157
|
end
|
135
158
|
|
159
|
+
def ignore_duplicate_else_branches?
|
160
|
+
cop_config.fetch('IgnoreDuplicateElseBranch', false)
|
161
|
+
end
|
162
|
+
|
136
163
|
def literal_branch?(branch) # rubocop:disable Metrics/CyclomaticComplexity
|
137
164
|
return false if !branch.literal? || branch.xstr_type?
|
138
165
|
return true if branch.basic_literal?
|
@@ -147,6 +174,14 @@ module RuboCop
|
|
147
174
|
def const_branch?(branch)
|
148
175
|
branch.const_type?
|
149
176
|
end
|
177
|
+
|
178
|
+
def duplicate_else_branch?(branches, branch)
|
179
|
+
return false unless (parent = branch.parent)
|
180
|
+
|
181
|
+
branches.size > 2 &&
|
182
|
+
branch.equal?(branches.last) &&
|
183
|
+
parent.respond_to?(:else?) && parent.else?
|
184
|
+
end
|
150
185
|
end
|
151
186
|
end
|
152
187
|
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) _) ...>)
|
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)
|