rubocop 1.67.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 +315 -53
- data/config/internal_affairs.yml +20 -0
- data/config/obsoletion.yml +8 -3
- 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 +51 -26
- 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/bundler/ordered_gems.rb +1 -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 +50 -6
- data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +1 -1
- 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 +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/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 +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 +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 +36 -6
- 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 +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 +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/empty_interpolation.rb +3 -1
- 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 +47 -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/identity_comparison.rb +19 -15
- 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 +110 -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 +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 +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_default_value_argument.rb +87 -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_or.rb +98 -0
- 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/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 -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_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 +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/def_with_parentheses.rb +18 -5
- 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/empty_string_inside_interpolation.rb +100 -0
- 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 -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 +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 +119 -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 +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 +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_array_flatten.rb +50 -0
- 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 +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 +54 -18
- data/lib/rubocop/cop/style/redundant_parentheses.rb +68 -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 +56 -16
- 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/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 +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 +15 -5
- 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 +38 -2
- data/lib/ruby_lsp/rubocop/addon.rb +75 -0
- data/lib/ruby_lsp/rubocop/runtime_adapter.rb +65 -0
- metadata +85 -21
- data/lib/rubocop/cop/utils/regexp_ranges.rb +0 -113
- data/lib/rubocop/rspec/host_environment_simulation_helper.rb +0 -28
@@ -0,0 +1,93 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Lint
|
6
|
+
# Certain numeric operations have a constant result, usually 0 or 1.
|
7
|
+
# Multiplying a number by 0 will always return 0.
|
8
|
+
# Dividing a number by itself or raising it to the power of 0 will always return 1.
|
9
|
+
# As such, they can be replaced with that result.
|
10
|
+
# These are probably leftover from debugging, or are mistakes.
|
11
|
+
# Other numeric operations that are similarly leftover from debugging or mistakes
|
12
|
+
# are handled by `Lint/UselessNumericOperation`.
|
13
|
+
#
|
14
|
+
# NOTE: This cop doesn't detect offenses for the `-` and `%` operator because it
|
15
|
+
# can't determine the type of `x`. If `x` is an `Array` or `String`, it doesn't perform
|
16
|
+
# a numeric operation.
|
17
|
+
#
|
18
|
+
# @example
|
19
|
+
#
|
20
|
+
# # bad
|
21
|
+
# x * 0
|
22
|
+
#
|
23
|
+
# # good
|
24
|
+
# 0
|
25
|
+
#
|
26
|
+
# # bad
|
27
|
+
# x *= 0
|
28
|
+
#
|
29
|
+
# # good
|
30
|
+
# x = 0
|
31
|
+
#
|
32
|
+
# # bad
|
33
|
+
# x / x
|
34
|
+
# x ** 0
|
35
|
+
#
|
36
|
+
# # good
|
37
|
+
# 1
|
38
|
+
#
|
39
|
+
# # bad
|
40
|
+
# x /= x
|
41
|
+
# x **= 0
|
42
|
+
#
|
43
|
+
# # good
|
44
|
+
# x = 1
|
45
|
+
#
|
46
|
+
class NumericOperationWithConstantResult < Base
|
47
|
+
extend AutoCorrector
|
48
|
+
MSG = 'Numeric operation with a constant result detected.'
|
49
|
+
RESTRICT_ON_SEND = %i[* / **].freeze
|
50
|
+
|
51
|
+
# @!method operation_with_constant_result?(node)
|
52
|
+
def_node_matcher :operation_with_constant_result?,
|
53
|
+
'(call (call nil? $_lhs) $_operation ({int | call nil?} $_rhs))'
|
54
|
+
|
55
|
+
# @!method abbreviated_assignment_with_constant_result?(node)
|
56
|
+
def_node_matcher :abbreviated_assignment_with_constant_result?,
|
57
|
+
'(op-asgn (lvasgn $_lhs) $_operation ({int lvar} $_rhs))'
|
58
|
+
|
59
|
+
def on_send(node)
|
60
|
+
return unless (lhs, operation, rhs = operation_with_constant_result?(node))
|
61
|
+
return unless (result = constant_result?(lhs, operation, rhs))
|
62
|
+
|
63
|
+
add_offense(node) do |corrector|
|
64
|
+
corrector.replace(node, result.to_s)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
alias on_csend on_send
|
68
|
+
|
69
|
+
def on_op_asgn(node)
|
70
|
+
return unless (lhs, operation, rhs = abbreviated_assignment_with_constant_result?(node))
|
71
|
+
return unless (result = constant_result?(lhs, operation, rhs))
|
72
|
+
|
73
|
+
add_offense(node) do |corrector|
|
74
|
+
corrector.replace(node, "#{lhs} = #{result}")
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
private
|
79
|
+
|
80
|
+
def constant_result?(lhs, operation, rhs)
|
81
|
+
if rhs.to_s == '0'
|
82
|
+
return 0 if operation == :*
|
83
|
+
return 1 if operation == :**
|
84
|
+
elsif rhs == lhs
|
85
|
+
return 1 if operation == :/
|
86
|
+
end
|
87
|
+
# If we weren't able to find any matches, return false so we can bail out.
|
88
|
+
false
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -27,11 +27,10 @@ module RuboCop
|
|
27
27
|
MSG = 'Avoid using or-assignment with constants.'
|
28
28
|
|
29
29
|
def on_or_asgn(node)
|
30
|
-
|
31
|
-
return unless lhs&.casgn_type?
|
30
|
+
return unless node.lhs&.casgn_type?
|
32
31
|
|
33
32
|
add_offense(node.loc.operator) do |corrector|
|
34
|
-
next if node.each_ancestor(:
|
33
|
+
next if node.each_ancestor(:any_def).any?
|
35
34
|
|
36
35
|
corrector.replace(node.loc.operator, '=')
|
37
36
|
end
|
@@ -3,7 +3,7 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module Lint
|
6
|
-
# Looks for references of Regexp captures that are out of range
|
6
|
+
# Looks for references of `Regexp` captures that are out of range
|
7
7
|
# and thus always returns nil.
|
8
8
|
#
|
9
9
|
# @safety
|
@@ -61,6 +61,7 @@ module RuboCop
|
|
61
61
|
check_regexp(node.receiver)
|
62
62
|
end
|
63
63
|
end
|
64
|
+
alias after_csend after_send
|
64
65
|
|
65
66
|
def on_when(node)
|
66
67
|
regexp_conditions = node.conditions.select(&:regexp_type?)
|
@@ -75,7 +76,7 @@ module RuboCop
|
|
75
76
|
end
|
76
77
|
|
77
78
|
def on_nth_ref(node)
|
78
|
-
backref
|
79
|
+
backref = node.children.first
|
79
80
|
return if @valid_ref.nil? || backref <= @valid_ref
|
80
81
|
|
81
82
|
message = format(
|
@@ -38,16 +38,12 @@ module RuboCop
|
|
38
38
|
|
39
39
|
def valid_context?(node)
|
40
40
|
return true unless node.arguments.one? && node.first_argument.parenthesized_call?
|
41
|
-
return true if
|
41
|
+
return true if node.first_argument.any_block_type?
|
42
42
|
|
43
43
|
node.operator_method? || node.setter_method? || chained_calls?(node) ||
|
44
44
|
valid_first_argument?(node.first_argument)
|
45
45
|
end
|
46
46
|
|
47
|
-
def first_argument_block_type?(first_arg)
|
48
|
-
first_arg.block_type? || first_arg.numblock_type?
|
49
|
-
end
|
50
|
-
|
51
47
|
def valid_first_argument?(first_arg)
|
52
48
|
first_arg.operator_keyword? || first_arg.hash_type? || ternary_expression?(first_arg) ||
|
53
49
|
compound_range?(first_arg)
|
@@ -3,15 +3,18 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module Lint
|
6
|
-
# Checks for `raise` or `fail` statements which
|
7
|
-
#
|
6
|
+
# Checks for `raise` or `fail` statements which raise `Exception` or
|
7
|
+
# `Exception.new`. Use `StandardError` or a specific exception class instead.
|
8
8
|
#
|
9
|
-
#
|
10
|
-
#
|
11
|
-
#
|
12
|
-
#
|
13
|
-
#
|
14
|
-
#
|
9
|
+
# If you have defined your own namespaced `Exception` class, it is possible
|
10
|
+
# to configure the cop to allow it by setting `AllowedImplicitNamespaces` to
|
11
|
+
# an array with the names of the namespaces to allow. By default, this is set to
|
12
|
+
# `['Gem']`, which allows `Gem::Exception` to be raised without an explicit namespace.
|
13
|
+
# If not allowed, a false positive may be registered if `raise Exception` is called
|
14
|
+
# within the namespace.
|
15
|
+
#
|
16
|
+
# Alternatively, use a fully qualified name with `raise`/`fail`
|
17
|
+
# (eg. `raise Namespace::Exception`).
|
15
18
|
#
|
16
19
|
# @safety
|
17
20
|
# This cop is unsafe because it will change the exception class being
|
@@ -20,15 +23,31 @@ module RuboCop
|
|
20
23
|
# @example
|
21
24
|
# # bad
|
22
25
|
# raise Exception, 'Error message here'
|
26
|
+
# raise Exception.new('Error message here')
|
23
27
|
#
|
24
28
|
# # good
|
25
29
|
# raise StandardError, 'Error message here'
|
30
|
+
# raise MyError.new, 'Error message here'
|
31
|
+
#
|
32
|
+
# @example AllowedImplicitNamespaces: ['Gem'] (default)
|
33
|
+
# # bad - `Foo` is not an allowed implicit namespace
|
34
|
+
# module Foo
|
35
|
+
# def self.foo
|
36
|
+
# raise Exception # This is qualified to `Foo::Exception`.
|
37
|
+
# end
|
38
|
+
# end
|
26
39
|
#
|
27
|
-
# @example AllowedImplicitNamespaces: ['Gem']
|
28
40
|
# # good
|
29
41
|
# module Gem
|
30
42
|
# def self.foo
|
31
|
-
# raise Exception # This
|
43
|
+
# raise Exception # This is qualified to `Gem::Exception`.
|
44
|
+
# end
|
45
|
+
# end
|
46
|
+
#
|
47
|
+
# # good
|
48
|
+
# module Foo
|
49
|
+
# def self.foo
|
50
|
+
# raise Foo::Exception
|
32
51
|
# end
|
33
52
|
# end
|
34
53
|
class RaiseException < Base
|
@@ -111,7 +111,7 @@ module RuboCop
|
|
111
111
|
range_between(start + begin_pos - 1, start + end_pos)
|
112
112
|
end
|
113
113
|
|
114
|
-
# If the list of cops is comma-separated, but without
|
114
|
+
# If the list of cops is comma-separated, but without an empty space after the comma,
|
115
115
|
# we should **not** remove the prepending empty space, thus begin_pos += 1
|
116
116
|
def range_with_comma_after(comment, start, begin_pos, end_pos)
|
117
117
|
begin_pos += 1 if comment.source[end_pos + 1] != ' '
|
@@ -3,7 +3,7 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module Lint
|
6
|
-
# Checks for redundant quantifiers inside Regexp literals.
|
6
|
+
# Checks for redundant quantifiers inside `Regexp` literals.
|
7
7
|
#
|
8
8
|
# It is always allowed when interpolation is used in a regexp literal,
|
9
9
|
# because it's unknown what kind of string will be expanded as a result:
|
@@ -17,17 +17,12 @@ module RuboCop
|
|
17
17
|
# * 2.0+ ... `enumerator`
|
18
18
|
# * 2.1+ ... `thread`
|
19
19
|
# * 2.2+ ... Add `rational` and `complex` above
|
20
|
-
# * 2.5+ ... Add `pp` above
|
21
20
|
# * 2.7+ ... Add `ruby2_keywords` above
|
22
21
|
# * 3.1+ ... Add `fiber` above
|
23
22
|
# * 3.2+ ... `set`
|
24
23
|
#
|
25
24
|
# This cop target those features.
|
26
25
|
#
|
27
|
-
# @safety
|
28
|
-
# This cop's autocorrection is unsafe because if `require 'pp'` is removed from one file,
|
29
|
-
# `NameError` can be encountered when another file uses `PP.pp`.
|
30
|
-
#
|
31
26
|
# @example
|
32
27
|
# # bad
|
33
28
|
# require 'unloaded_feature'
|
@@ -42,10 +37,6 @@ module RuboCop
|
|
42
37
|
MSG = 'Remove unnecessary `require` statement.'
|
43
38
|
RESTRICT_ON_SEND = %i[require].freeze
|
44
39
|
RUBY_22_LOADED_FEATURES = %w[rational complex].freeze
|
45
|
-
PRETTY_PRINT_METHODS = %i[
|
46
|
-
pretty_inspect pretty_print pretty_print_cycle
|
47
|
-
pretty_print_inspect pretty_print_instance_variables
|
48
|
-
].freeze
|
49
40
|
|
50
41
|
# @!method redundant_require_statement?(node)
|
51
42
|
def_node_matcher :redundant_require_statement?, <<~PATTERN
|
@@ -53,11 +44,6 @@ module RuboCop
|
|
53
44
|
(str #redundant_feature?))
|
54
45
|
PATTERN
|
55
46
|
|
56
|
-
# @!method pp_const?(node)
|
57
|
-
def_node_matcher :pp_const?, <<~PATTERN
|
58
|
-
(const {nil? cbase} :PP)
|
59
|
-
PATTERN
|
60
|
-
|
61
47
|
def on_send(node)
|
62
48
|
return unless redundant_require_statement?(node)
|
63
49
|
|
@@ -81,18 +67,11 @@ module RuboCop
|
|
81
67
|
feature_name == 'enumerator' ||
|
82
68
|
(target_ruby_version >= 2.1 && feature_name == 'thread') ||
|
83
69
|
(target_ruby_version >= 2.2 && RUBY_22_LOADED_FEATURES.include?(feature_name)) ||
|
84
|
-
(target_ruby_version >= 2.5 && feature_name == 'pp' && !need_to_require_pp?) ||
|
85
70
|
(target_ruby_version >= 2.7 && feature_name == 'ruby2_keywords') ||
|
86
71
|
(target_ruby_version >= 3.1 && feature_name == 'fiber') ||
|
87
72
|
(target_ruby_version >= 3.2 && feature_name == 'set')
|
88
73
|
end
|
89
74
|
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
90
|
-
|
91
|
-
def need_to_require_pp?
|
92
|
-
processed_source.ast.each_descendant(:send).any? do |node|
|
93
|
-
pp_const?(node.receiver) || PRETTY_PRINT_METHODS.include?(node.method_name)
|
94
|
-
end
|
95
|
-
end
|
96
75
|
end
|
97
76
|
end
|
98
77
|
end
|
@@ -6,7 +6,7 @@ module RuboCop
|
|
6
6
|
# Checks for redundant safe navigation calls.
|
7
7
|
# Use cases where a constant, named in camel case for classes and modules is `nil` are rare,
|
8
8
|
# and an offense is not detected when the receiver is a constant. The detection also applies
|
9
|
-
# to literal receivers, except for `nil`.
|
9
|
+
# to `self`, and to literal receivers, except for `nil`.
|
10
10
|
#
|
11
11
|
# For all receivers, the `instance_of?`, `kind_of?`, `is_a?`, `eql?`, `respond_to?`,
|
12
12
|
# and `equal?` methods are checked by default.
|
@@ -29,6 +29,9 @@ module RuboCop
|
|
29
29
|
# # bad
|
30
30
|
# CamelCaseConst&.do_something
|
31
31
|
#
|
32
|
+
# # good
|
33
|
+
# CamelCaseConst.do_something
|
34
|
+
#
|
32
35
|
# # bad
|
33
36
|
# do_something if attrs&.respond_to?(:[])
|
34
37
|
#
|
@@ -41,9 +44,6 @@ module RuboCop
|
|
41
44
|
# end
|
42
45
|
#
|
43
46
|
# # good
|
44
|
-
# CamelCaseConst.do_something
|
45
|
-
#
|
46
|
-
# # good
|
47
47
|
# while node.is_a?(BeginNode)
|
48
48
|
# node = node.parent
|
49
49
|
# end
|
@@ -67,6 +67,12 @@ module RuboCop
|
|
67
67
|
# foo.to_f
|
68
68
|
# foo.to_s
|
69
69
|
#
|
70
|
+
# # bad
|
71
|
+
# self&.foo
|
72
|
+
#
|
73
|
+
# # good
|
74
|
+
# self.foo
|
75
|
+
#
|
70
76
|
# @example AllowedMethods: [nil_safe_method]
|
71
77
|
# # bad
|
72
78
|
# do_something if attrs&.nil_safe_method(:[])
|
@@ -133,7 +139,7 @@ module RuboCop
|
|
133
139
|
def assume_receiver_instance_exists?(receiver)
|
134
140
|
return true if receiver.const_type? && !receiver.short_name.match?(SNAKE_CASE)
|
135
141
|
|
136
|
-
receiver.literal? && !receiver.nil_type?
|
142
|
+
receiver.self_type? || (receiver.literal? && !receiver.nil_type?)
|
137
143
|
end
|
138
144
|
|
139
145
|
def check?(node)
|
@@ -141,8 +147,7 @@ module RuboCop
|
|
141
147
|
return false unless parent
|
142
148
|
|
143
149
|
condition?(parent, node) ||
|
144
|
-
parent.
|
145
|
-
parent.or_type? ||
|
150
|
+
parent.operator_keyword? ||
|
146
151
|
(parent.send_type? && parent.negation_method?)
|
147
152
|
end
|
148
153
|
|
@@ -135,10 +135,10 @@ module RuboCop
|
|
135
135
|
grandparent.array_type? && grandparent.children.size > 1
|
136
136
|
end
|
137
137
|
|
138
|
+
# rubocop:disable Metrics/AbcSize
|
138
139
|
def replacement_range_and_content(node)
|
139
|
-
variable
|
140
|
-
|
141
|
-
expression = loc.expression
|
140
|
+
variable = node.children.first
|
141
|
+
expression = node.source_range
|
142
142
|
|
143
143
|
if array_new?(variable)
|
144
144
|
expression = node.parent.source_range if node.parent.array_type?
|
@@ -148,16 +148,17 @@ module RuboCop
|
|
148
148
|
elsif redundant_brackets?(node)
|
149
149
|
[expression, remove_brackets(variable)]
|
150
150
|
else
|
151
|
-
[loc.operator, '']
|
151
|
+
[node.loc.operator, '']
|
152
152
|
end
|
153
153
|
end
|
154
|
+
# rubocop:enable Metrics/AbcSize
|
154
155
|
|
155
156
|
def array_splat?(node)
|
156
157
|
node.children.first.array_type?
|
157
158
|
end
|
158
159
|
|
159
160
|
def method_argument?(node)
|
160
|
-
node.parent.
|
161
|
+
node.parent.call_type?
|
161
162
|
end
|
162
163
|
|
163
164
|
def part_of_an_array?(node)
|
@@ -171,7 +172,7 @@ module RuboCop
|
|
171
172
|
parent = node.parent
|
172
173
|
grandparent = node.parent.parent
|
173
174
|
|
174
|
-
parent.when_type? ||
|
175
|
+
parent.when_type? || method_argument?(node) || part_of_an_array?(node) ||
|
175
176
|
grandparent&.resbody_type?
|
176
177
|
end
|
177
178
|
|
@@ -196,7 +197,7 @@ module RuboCop
|
|
196
197
|
def use_percent_literal_array_argument?(node)
|
197
198
|
argument = node.children.first
|
198
199
|
|
199
|
-
node
|
200
|
+
method_argument?(node) &&
|
200
201
|
(argument.percent_literal?(:string) || argument.percent_literal?(:symbol))
|
201
202
|
end
|
202
203
|
|
@@ -29,7 +29,7 @@ module RuboCop
|
|
29
29
|
RESTRICT_ON_SEND = %i[print puts warn].freeze
|
30
30
|
|
31
31
|
# @!method to_s_without_args?(node)
|
32
|
-
def_node_matcher :to_s_without_args?, '(
|
32
|
+
def_node_matcher :to_s_without_args?, '(call _ :to_s)'
|
33
33
|
|
34
34
|
def on_interpolation(begin_node)
|
35
35
|
final_node = begin_node.children.last
|
@@ -42,7 +42,7 @@ module RuboCop
|
|
42
42
|
def on_send(node)
|
43
43
|
return if node.receiver
|
44
44
|
|
45
|
-
node.each_child_node(:
|
45
|
+
node.each_child_node(:call) do |child|
|
46
46
|
next if !child.method?(:to_s) || child.arguments.any?
|
47
47
|
|
48
48
|
register_offense(child, "`#{node.method_name}`")
|
@@ -0,0 +1,261 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Lint
|
6
|
+
# Checks for redundant uses of `to_s`, `to_sym`, `to_i`, `to_f`, `to_d`, `to_r`, `to_c`,
|
7
|
+
# `to_a`, `to_h`, and `to_set`.
|
8
|
+
#
|
9
|
+
# When one of these methods is called on an object of the same type, that object
|
10
|
+
# is returned, making the call unnecessary. The cop detects conversion methods called
|
11
|
+
# on object literals, class constructors, class `[]` methods, and the `Kernel` methods
|
12
|
+
# `String()`, `Integer()`, `Float()`, BigDecimal(), `Rational()`, `Complex()`, and `Array()`.
|
13
|
+
#
|
14
|
+
# Specifically, these cases are detected for each conversion method:
|
15
|
+
#
|
16
|
+
# * `to_s` when called on a string literal, interpolated string, heredoc,
|
17
|
+
# or with `String.new` or `String()`.
|
18
|
+
# * `to_sym` when called on a symbol literal or interpolated symbol.
|
19
|
+
# * `to_i` when called on an integer literal or with `Integer()`.
|
20
|
+
# * `to_f` when called on a float literal of with `Float()`.
|
21
|
+
# * `to_r` when called on a rational literal or with `Rational()`.
|
22
|
+
# * `to_c` when called on a complex literal of with `Complex()`.
|
23
|
+
# * `to_a` when called on an array literal, or with `Array.new`, `Array()` or `Array[]`.
|
24
|
+
# * `to_h` when called on a hash literal, or with `Hash.new`, `Hash()` or `Hash[]`.
|
25
|
+
# * `to_set` when called on `Set.new` or `Set[]`.
|
26
|
+
#
|
27
|
+
# In all cases, chaining one same `to_*` conversion methods listed above is redundant.
|
28
|
+
#
|
29
|
+
# The cop can also register an offense for chaining conversion methods on methods that are
|
30
|
+
# expected to return a specific type regardless of receiver (eg. `foo.inspect.to_s` and
|
31
|
+
# `foo.to_json.to_s`).
|
32
|
+
#
|
33
|
+
# @example
|
34
|
+
# # bad
|
35
|
+
# "text".to_s
|
36
|
+
# :sym.to_sym
|
37
|
+
# 42.to_i
|
38
|
+
# 8.5.to_f
|
39
|
+
# 12r.to_r
|
40
|
+
# 1i.to_c
|
41
|
+
# [].to_a
|
42
|
+
# {}.to_h
|
43
|
+
# Set.new.to_set
|
44
|
+
#
|
45
|
+
# # good
|
46
|
+
# "text"
|
47
|
+
# :sym
|
48
|
+
# 42
|
49
|
+
# 8.5
|
50
|
+
# 12r
|
51
|
+
# 1i
|
52
|
+
# []
|
53
|
+
# {}
|
54
|
+
# Set.new
|
55
|
+
#
|
56
|
+
# # bad
|
57
|
+
# Integer(var).to_i
|
58
|
+
#
|
59
|
+
# # good
|
60
|
+
# Integer(var)
|
61
|
+
#
|
62
|
+
# # good - chaining to a type constructor with exceptions suppressed
|
63
|
+
# # in this case, `Integer()` could return `nil`
|
64
|
+
# Integer(var, exception: false).to_i
|
65
|
+
#
|
66
|
+
# # bad - chaining the same conversion
|
67
|
+
# foo.to_s.to_s
|
68
|
+
#
|
69
|
+
# # good
|
70
|
+
# foo.to_s
|
71
|
+
#
|
72
|
+
# # bad - chaining a conversion to a method that is expected to return the same type
|
73
|
+
# foo.inspect.to_s
|
74
|
+
# foo.to_json.to_s
|
75
|
+
#
|
76
|
+
# # good
|
77
|
+
# foo.inspect
|
78
|
+
# foo.to_json
|
79
|
+
#
|
80
|
+
class RedundantTypeConversion < Base
|
81
|
+
extend AutoCorrector
|
82
|
+
|
83
|
+
MSG = 'Redundant `%<method>s` detected.'
|
84
|
+
|
85
|
+
# Maps conversion methods to the node types for the literals of that type
|
86
|
+
LITERAL_NODE_TYPES = {
|
87
|
+
to_s: %i[str dstr],
|
88
|
+
to_sym: %i[sym dsym],
|
89
|
+
to_i: %i[int],
|
90
|
+
to_f: %i[float],
|
91
|
+
to_r: %i[rational],
|
92
|
+
to_c: %i[complex],
|
93
|
+
to_a: %i[array],
|
94
|
+
to_h: %i[hash],
|
95
|
+
to_set: [] # sets don't have a literal or node type
|
96
|
+
}.freeze
|
97
|
+
|
98
|
+
# Maps each conversion method to the pattern matcher for that type's constructors
|
99
|
+
# Not every type has a constructor, for instance Symbol.
|
100
|
+
CONSTRUCTOR_MAPPING = {
|
101
|
+
to_s: 'string_constructor?',
|
102
|
+
to_i: 'integer_constructor?',
|
103
|
+
to_f: 'float_constructor?',
|
104
|
+
to_d: 'bigdecimal_constructor?',
|
105
|
+
to_r: 'rational_constructor?',
|
106
|
+
to_c: 'complex_constructor?',
|
107
|
+
to_a: 'array_constructor?',
|
108
|
+
to_h: 'hash_constructor?',
|
109
|
+
to_set: 'set_constructor?'
|
110
|
+
}.freeze
|
111
|
+
|
112
|
+
# Methods that already are expected to return a given type, which makes a further
|
113
|
+
# conversion redundant.
|
114
|
+
TYPED_METHODS = { to_s: %i[inspect to_json] }.freeze
|
115
|
+
|
116
|
+
CONVERSION_METHODS = Set[*LITERAL_NODE_TYPES.keys].freeze
|
117
|
+
RESTRICT_ON_SEND = CONVERSION_METHODS + [:to_d]
|
118
|
+
|
119
|
+
private_constant :LITERAL_NODE_TYPES, :CONSTRUCTOR_MAPPING
|
120
|
+
|
121
|
+
# @!method type_constructor?(node, type_symbol)
|
122
|
+
def_node_matcher :type_constructor?, <<~PATTERN
|
123
|
+
(send {nil? (const {cbase nil?} :Kernel)} %1 ...)
|
124
|
+
PATTERN
|
125
|
+
|
126
|
+
# @!method string_constructor?(node)
|
127
|
+
def_node_matcher :string_constructor?, <<~PATTERN
|
128
|
+
{
|
129
|
+
(send (const {cbase nil?} :String) :new ...)
|
130
|
+
#type_constructor?(:String)
|
131
|
+
}
|
132
|
+
PATTERN
|
133
|
+
|
134
|
+
# @!method integer_constructor?(node)
|
135
|
+
def_node_matcher :integer_constructor?, <<~PATTERN
|
136
|
+
#type_constructor?(:Integer)
|
137
|
+
PATTERN
|
138
|
+
|
139
|
+
# @!method float_constructor?(node)
|
140
|
+
def_node_matcher :float_constructor?, <<~PATTERN
|
141
|
+
#type_constructor?(:Float)
|
142
|
+
PATTERN
|
143
|
+
|
144
|
+
# @!method bigdecimal_constructor?(node)
|
145
|
+
def_node_matcher :bigdecimal_constructor?, <<~PATTERN
|
146
|
+
#type_constructor?(:BigDecimal)
|
147
|
+
PATTERN
|
148
|
+
|
149
|
+
# @!method rational_constructor?(node)
|
150
|
+
def_node_matcher :rational_constructor?, <<~PATTERN
|
151
|
+
#type_constructor?(:Rational)
|
152
|
+
PATTERN
|
153
|
+
|
154
|
+
# @!method complex_constructor?(node)
|
155
|
+
def_node_matcher :complex_constructor?, <<~PATTERN
|
156
|
+
#type_constructor?(:Complex)
|
157
|
+
PATTERN
|
158
|
+
|
159
|
+
# @!method array_constructor?(node)
|
160
|
+
def_node_matcher :array_constructor?, <<~PATTERN
|
161
|
+
{
|
162
|
+
(send (const {cbase nil?} :Array) {:new :[]} ...)
|
163
|
+
#type_constructor?(:Array)
|
164
|
+
}
|
165
|
+
PATTERN
|
166
|
+
|
167
|
+
# @!method hash_constructor?(node)
|
168
|
+
def_node_matcher :hash_constructor?, <<~PATTERN
|
169
|
+
{
|
170
|
+
(block (send (const {cbase nil?} :Hash) :new) ...)
|
171
|
+
(send (const {cbase nil?} :Hash) {:new :[]} ...)
|
172
|
+
(send {nil? (const {cbase nil?} :Kernel)} :Hash ...)
|
173
|
+
}
|
174
|
+
PATTERN
|
175
|
+
|
176
|
+
# @!method set_constructor?(node)
|
177
|
+
def_node_matcher :set_constructor?, <<~PATTERN
|
178
|
+
{
|
179
|
+
(send (const {cbase nil?} :Set) {:new :[]} ...)
|
180
|
+
}
|
181
|
+
PATTERN
|
182
|
+
|
183
|
+
# @!method exception_false_keyword_argument?(node)
|
184
|
+
def_node_matcher :exception_false_keyword_argument?, <<~PATTERN
|
185
|
+
(hash (pair (sym :exception) false))
|
186
|
+
PATTERN
|
187
|
+
|
188
|
+
# rubocop:disable Metrics/AbcSize
|
189
|
+
def on_send(node)
|
190
|
+
return if hash_or_set_with_block?(node)
|
191
|
+
|
192
|
+
receiver = find_receiver(node)
|
193
|
+
return unless literal_receiver?(node, receiver) ||
|
194
|
+
constructor?(node, receiver) ||
|
195
|
+
chained_conversion?(node, receiver) ||
|
196
|
+
chained_to_typed_method?(node, receiver)
|
197
|
+
|
198
|
+
message = format(MSG, method: node.method_name)
|
199
|
+
|
200
|
+
add_offense(node.loc.selector, message: message) do |corrector|
|
201
|
+
corrector.remove(node.loc.dot.join(node.loc.selector))
|
202
|
+
end
|
203
|
+
end
|
204
|
+
# rubocop:enable Metrics/AbcSize
|
205
|
+
alias on_csend on_send
|
206
|
+
|
207
|
+
private
|
208
|
+
|
209
|
+
def hash_or_set_with_block?(node)
|
210
|
+
return false if !node.method?(:to_h) && !node.method?(:to_set)
|
211
|
+
|
212
|
+
node.parent&.any_block_type? || node.last_argument&.block_pass_type?
|
213
|
+
end
|
214
|
+
|
215
|
+
def find_receiver(node)
|
216
|
+
receiver = node.receiver
|
217
|
+
return unless receiver
|
218
|
+
|
219
|
+
while receiver.begin_type?
|
220
|
+
break unless receiver.children.one?
|
221
|
+
|
222
|
+
receiver = receiver.children.first
|
223
|
+
end
|
224
|
+
|
225
|
+
receiver
|
226
|
+
end
|
227
|
+
|
228
|
+
def literal_receiver?(node, receiver)
|
229
|
+
return false unless receiver
|
230
|
+
|
231
|
+
receiver.type?(*LITERAL_NODE_TYPES[node.method_name])
|
232
|
+
end
|
233
|
+
|
234
|
+
def constructor?(node, receiver)
|
235
|
+
matcher = CONSTRUCTOR_MAPPING[node.method_name]
|
236
|
+
return false unless matcher
|
237
|
+
|
238
|
+
public_send(matcher, receiver) && !constructor_suppresses_exceptions?(receiver)
|
239
|
+
end
|
240
|
+
|
241
|
+
def constructor_suppresses_exceptions?(receiver)
|
242
|
+
# If the constructor suppresses exceptions with `exception: false`, it is possible
|
243
|
+
# it could return `nil`, and therefore a chained conversion is not redundant.
|
244
|
+
receiver.arguments.any? { |arg| exception_false_keyword_argument?(arg) }
|
245
|
+
end
|
246
|
+
|
247
|
+
def chained_conversion?(node, receiver)
|
248
|
+
return false unless receiver&.call_type?
|
249
|
+
|
250
|
+
receiver.method?(node.method_name)
|
251
|
+
end
|
252
|
+
|
253
|
+
def chained_to_typed_method?(node, receiver)
|
254
|
+
return false unless receiver&.call_type?
|
255
|
+
|
256
|
+
TYPED_METHODS.fetch(node.method_name, []).include?(receiver.method_name)
|
257
|
+
end
|
258
|
+
end
|
259
|
+
end
|
260
|
+
end
|
261
|
+
end
|