rubocop 1.66.0 → 1.72.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 +2 -2
- data/config/default.yml +160 -14
- data/config/internal_affairs.yml +11 -0
- data/lib/rubocop/cached_data.rb +12 -4
- data/lib/rubocop/cli/command/auto_generate_config.rb +6 -7
- data/lib/rubocop/cli/command/execute_runner.rb +4 -4
- data/lib/rubocop/cli/command/lsp.rb +2 -2
- 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/comment_config.rb +6 -10
- data/lib/rubocop/config.rb +21 -20
- data/lib/rubocop/config_loader.rb +62 -16
- data/lib/rubocop/config_loader_resolver.rb +36 -11
- data/lib/rubocop/config_validator.rb +25 -18
- data/lib/rubocop/cop/autocorrect_logic.rb +36 -19
- data/lib/rubocop/cop/base.rb +13 -3
- 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/gem_version.rb +1 -0
- data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +0 -1
- data/lib/rubocop/cop/cop.rb +8 -0
- 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/parentheses_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/required_ruby_version.rb +0 -2
- data/lib/rubocop/cop/generator.rb +6 -0
- data/lib/rubocop/cop/internal_affairs/cop_description.rb +0 -4
- data/lib/rubocop/cop/internal_affairs/cop_enabled.rb +85 -0
- 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 +2 -2
- 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 +229 -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_message_argument.rb +6 -21
- data/lib/rubocop/cop/internal_affairs/redundant_source_range.rb +11 -2
- 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 +7 -1
- data/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +0 -5
- data/lib/rubocop/cop/internal_affairs.rb +6 -0
- data/lib/rubocop/cop/layout/access_modifier_indentation.rb +6 -2
- 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/class_structure.rb +9 -9
- 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 +3 -3
- data/lib/rubocop/cop/layout/empty_lines_around_begin_body.rb +5 -6
- 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_method_argument_line_break.rb +8 -0
- data/lib/rubocop/cop/layout/first_parameter_indentation.rb +2 -2
- data/lib/rubocop/cop/layout/hash_alignment.rb +6 -4
- data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +2 -1
- data/lib/rubocop/cop/layout/indentation_width.rb +11 -12
- data/lib/rubocop/cop/layout/leading_comment_space.rb +71 -1
- data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +11 -2
- data/lib/rubocop/cop/layout/line_continuation_spacing.rb +7 -1
- data/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb +2 -2
- data/lib/rubocop/cop/layout/line_length.rb +119 -4
- 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_operation_indentation.rb +2 -3
- data/lib/rubocop/cop/layout/parameter_alignment.rb +3 -4
- data/lib/rubocop/cop/layout/redundant_line_break.rb +10 -41
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +4 -3
- data/lib/rubocop/cop/layout/single_line_block_chain.rb +1 -1
- data/lib/rubocop/cop/layout/space_after_colon.rb +2 -2
- data/lib/rubocop/cop/layout/space_after_comma.rb +1 -1
- data/lib/rubocop/cop/layout/space_after_method_name.rb +1 -1
- data/lib/rubocop/cop/layout/space_after_semicolon.rb +1 -1
- data/lib/rubocop/cop/layout/space_around_keyword.rb +2 -1
- data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +1 -1
- data/lib/rubocop/cop/layout/space_around_operators.rb +19 -20
- data/lib/rubocop/cop/layout/space_before_brackets.rb +5 -5
- 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 +6 -0
- data/lib/rubocop/cop/layout/space_inside_block_braces.rb +4 -0
- data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +4 -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/ambiguous_range.rb +4 -1
- data/lib/rubocop/cop/lint/array_literal_in_regexp.rb +119 -0
- data/lib/rubocop/cop/lint/assignment_in_condition.rb +1 -3
- data/lib/rubocop/cop/lint/big_decimal_new.rb +4 -7
- 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 +6 -0
- 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 +1 -1
- data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +2 -1
- 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_regexp_character_class_element.rb +1 -1
- data/lib/rubocop/cop/lint/duplicate_set_element.rb +87 -0
- 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 -4
- data/lib/rubocop/cop/lint/erb_new_arguments.rb +1 -1
- data/lib/rubocop/cop/lint/float_comparison.rb +20 -9
- 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 +11 -5
- data/lib/rubocop/cop/lint/interpolation_check.rb +9 -0
- data/lib/rubocop/cop/lint/it_without_arguments_in_block.rb +8 -14
- data/lib/rubocop/cop/lint/literal_as_condition.rb +1 -0
- data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +1 -1
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +49 -8
- data/lib/rubocop/cop/lint/missing_super.rb +2 -2
- data/lib/rubocop/cop/lint/mixed_case_range.rb +3 -6
- data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +1 -1
- data/lib/rubocop/cop/lint/nested_method_definition.rb +9 -5
- data/lib/rubocop/cop/lint/next_without_accumulator.rb +1 -1
- data/lib/rubocop/cop/lint/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 +1 -1
- 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 +1 -2
- data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +3 -2
- data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +6 -11
- 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_safe_navigation.rb +13 -8
- 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 +231 -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/safe_navigation_chain.rb +17 -1
- data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +109 -41
- 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/shared_mutable_default.rb +65 -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 +2 -2
- data/lib/rubocop/cop/lint/syntax.rb +4 -1
- data/lib/rubocop/cop/lint/unescaped_bracket_in_regexp.rb +88 -0
- data/lib/rubocop/cop/lint/unexpected_block_arity.rb +1 -1
- data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +1 -1
- data/lib/rubocop/cop/lint/unreachable_code.rb +51 -2
- data/lib/rubocop/cop/lint/unreachable_loop.rb +1 -1
- data/lib/rubocop/cop/lint/unused_method_argument.rb +18 -2
- data/lib/rubocop/cop/lint/uri_regexp.rb +25 -7
- data/lib/rubocop/cop/lint/useless_access_modifier.rb +4 -4
- data/lib/rubocop/cop/lint/useless_assignment.rb +1 -1
- data/lib/rubocop/cop/lint/useless_constant_scoping.rb +74 -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 +1 -1
- 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 +8 -11
- 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 +8 -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 +2 -3
- 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/check_assignment.rb +4 -12
- data/lib/rubocop/cop/mixin/check_line_breakable.rb +20 -10
- 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/dig_help.rb +27 -0
- data/lib/rubocop/cop/mixin/endless_method_rewriter.rb +24 -0
- data/lib/rubocop/cop/mixin/frozen_string_literal.rb +4 -2
- data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +22 -22
- data/lib/rubocop/cop/mixin/hash_subset.rb +188 -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 +1 -1
- data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +5 -9
- data/lib/rubocop/cop/mixin/percent_array.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 +3 -4
- data/lib/rubocop/cop/mixin/space_before_punctuation.rb +1 -1
- data/lib/rubocop/cop/mixin/statement_modifier.rb +11 -5
- 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 +3 -3
- 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/inclusive_language.rb +12 -3
- data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +11 -12
- data/lib/rubocop/cop/naming/predicate_name.rb +45 -1
- data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +6 -14
- data/lib/rubocop/cop/naming/variable_name.rb +3 -4
- data/lib/rubocop/cop/naming/variable_number.rb +2 -3
- data/lib/rubocop/cop/offense.rb +4 -5
- 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 +96 -28
- data/lib/rubocop/cop/style/accessor_grouping.rb +10 -2
- 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 +78 -22
- data/lib/rubocop/cop/style/array_first_last.rb +18 -2
- data/lib/rubocop/cop/style/array_intersect.rb +5 -4
- data/lib/rubocop/cop/style/bitwise_predicate.rb +100 -0
- data/lib/rubocop/cop/style/block_delimiters.rb +49 -19
- data/lib/rubocop/cop/style/case_like_if.rb +8 -11
- data/lib/rubocop/cop/style/class_and_module_children.rb +6 -3
- data/lib/rubocop/cop/style/collection_compact.rb +10 -10
- data/lib/rubocop/cop/style/collection_methods.rb +1 -1
- data/lib/rubocop/cop/style/combinable_defined.rb +115 -0
- data/lib/rubocop/cop/style/combinable_loops.rb +9 -2
- data/lib/rubocop/cop/style/commented_keyword.rb +17 -1
- data/lib/rubocop/cop/style/concat_array_literals.rb +1 -1
- data/lib/rubocop/cop/style/conditional_assignment.rb +26 -26
- data/lib/rubocop/cop/style/constant_visibility.rb +3 -12
- data/lib/rubocop/cop/style/data_inheritance.rb +1 -1
- 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 +3 -3
- 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 +5 -2
- data/lib/rubocop/cop/style/empty_literal.rb +2 -2
- data/lib/rubocop/cop/style/empty_method.rb +1 -1
- data/lib/rubocop/cop/style/endless_method.rb +1 -14
- data/lib/rubocop/cop/style/eval_with_location.rb +2 -2
- data/lib/rubocop/cop/style/exact_regexp_match.rb +2 -3
- data/lib/rubocop/cop/style/explicit_block_argument.rb +15 -2
- data/lib/rubocop/cop/style/exponential_notation.rb +1 -1
- 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 +0 -1
- data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +1 -1
- data/lib/rubocop/cop/style/global_vars.rb +1 -3
- data/lib/rubocop/cop/style/guard_clause.rb +16 -3
- data/lib/rubocop/cop/style/hash_conversion.rb +1 -2
- data/lib/rubocop/cop/style/hash_each_methods.rb +9 -6
- data/lib/rubocop/cop/style/hash_except.rb +35 -147
- data/lib/rubocop/cop/style/hash_slice.rb +80 -0
- data/lib/rubocop/cop/style/hash_syntax.rb +8 -5
- data/lib/rubocop/cop/style/identical_conditional_branches.rb +22 -3
- data/lib/rubocop/cop/style/if_inside_else.rb +1 -2
- data/lib/rubocop/cop/style/if_unless_modifier.rb +3 -3
- data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +2 -3
- data/lib/rubocop/cop/style/if_with_semicolon.rb +28 -6
- data/lib/rubocop/cop/style/infinite_loop.rb +1 -1
- data/lib/rubocop/cop/style/inverse_methods.rb +6 -7
- data/lib/rubocop/cop/style/it_assignment.rb +36 -0
- data/lib/rubocop/cop/style/keyword_arguments_merging.rb +67 -0
- data/lib/rubocop/cop/style/keyword_parameters_order.rb +1 -1
- data/lib/rubocop/cop/style/lambda.rb +1 -1
- data/lib/rubocop/cop/style/lambda_call.rb +3 -2
- data/lib/rubocop/cop/style/magic_comment_format.rb +3 -8
- data/lib/rubocop/cop/style/map_into_array.rb +61 -12
- 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 +32 -20
- 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 +2 -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 +1 -1
- data/lib/rubocop/cop/style/multiline_memoization.rb +2 -2
- 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_modifier.rb +1 -1
- data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +2 -2
- data/lib/rubocop/cop/style/nested_ternary_operator.rb +5 -4
- data/lib/rubocop/cop/style/not.rb +1 -1
- data/lib/rubocop/cop/style/object_then.rb +14 -15
- data/lib/rubocop/cop/style/one_line_conditional.rb +29 -4
- data/lib/rubocop/cop/style/open_struct_use.rb +5 -5
- data/lib/rubocop/cop/style/operator_method_call.rb +25 -7
- 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/proc.rb +1 -2
- data/lib/rubocop/cop/style/quoted_symbols.rb +1 -1
- data/lib/rubocop/cop/style/raise_args.rb +7 -5
- 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 +5 -1
- data/lib/rubocop/cop/style/redundant_condition.rb +39 -24
- data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +2 -1
- 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 +222 -0
- data/lib/rubocop/cop/style/redundant_freeze.rb +2 -2
- data/lib/rubocop/cop/style/redundant_initialize.rb +12 -3
- data/lib/rubocop/cop/style/redundant_interpolation_unfreeze.rb +1 -1
- data/lib/rubocop/cop/style/redundant_line_continuation.rb +56 -17
- data/lib/rubocop/cop/style/redundant_parentheses.rb +38 -24
- 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 +8 -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_string_escape.rb +2 -2
- data/lib/rubocop/cop/style/require_order.rb +1 -1
- data/lib/rubocop/cop/style/rescue_modifier.rb +15 -4
- data/lib/rubocop/cop/style/return_nil.rb +1 -1
- data/lib/rubocop/cop/style/return_nil_in_predicate_method_definition.rb +54 -12
- data/lib/rubocop/cop/style/safe_navigation.rb +105 -51
- data/lib/rubocop/cop/style/safe_navigation_chain_length.rb +52 -0
- data/lib/rubocop/cop/style/select_by_regexp.rb +10 -7
- data/lib/rubocop/cop/style/self_assignment.rb +11 -17
- data/lib/rubocop/cop/style/semicolon.rb +2 -2
- 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 +12 -3
- data/lib/rubocop/cop/style/single_line_methods.rb +3 -4
- data/lib/rubocop/cop/style/slicing_with_range.rb +40 -11
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +4 -5
- data/lib/rubocop/cop/style/special_global_vars.rb +1 -1
- data/lib/rubocop/cop/style/string_concatenation.rb +14 -13
- 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 +1 -1
- data/lib/rubocop/cop/style/super_arguments.rb +65 -17
- data/lib/rubocop/cop/style/swap_values.rb +4 -15
- data/lib/rubocop/cop/style/ternary_parentheses.rb +26 -5
- data/lib/rubocop/cop/style/top_level_method_definition.rb +1 -1
- data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +4 -1
- 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 +8 -1
- data/lib/rubocop/cop/util.rb +12 -5
- data/lib/rubocop/cop/utils/format_string.rb +7 -5
- data/lib/rubocop/cop/variable_force/assignment.rb +18 -3
- data/lib/rubocop/cop/variable_force/branch.rb +1 -1
- data/lib/rubocop/cop/variable_force/variable.rb +18 -2
- data/lib/rubocop/cop/variable_force/variable_table.rb +5 -5
- data/lib/rubocop/cop/variable_force.rb +4 -10
- data/lib/rubocop/cops_documentation_generator.rb +100 -51
- data/lib/rubocop/directive_comment.rb +44 -10
- data/lib/rubocop/file_finder.rb +9 -4
- data/lib/rubocop/formatter/disabled_config_formatter.rb +1 -1
- data/lib/rubocop/formatter/formatter_set.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 -48
- data/lib/rubocop/lsp/server.rb +0 -3
- data/lib/rubocop/lsp/stdin_runner.rb +83 -0
- data/lib/rubocop/magic_comment.rb +3 -3
- data/lib/rubocop/options.rb +28 -12
- data/lib/rubocop/path_util.rb +15 -8
- data/lib/rubocop/plugin/configuration_integrator.rb +141 -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 +39 -0
- data/lib/rubocop/rake_task.rb +4 -1
- data/lib/rubocop/result_cache.rb +13 -13
- data/lib/rubocop/rspec/cop_helper.rb +7 -0
- data/lib/rubocop/rspec/expect_offense.rb +7 -2
- data/lib/rubocop/rspec/shared_contexts.rb +4 -1
- data/lib/rubocop/rspec/support.rb +1 -2
- data/lib/rubocop/runner.rb +22 -12
- data/lib/rubocop/server/cache.rb +39 -1
- data/lib/rubocop/server/cli.rb +2 -2
- data/lib/rubocop/server/core.rb +1 -0
- data/lib/rubocop/target_finder.rb +1 -0
- data/lib/rubocop/target_ruby.rb +28 -13
- data/lib/rubocop/version.rb +42 -6
- data/lib/rubocop/yaml_duplication_checker.rb +20 -26
- data/lib/rubocop.rb +29 -0
- data/lib/ruby_lsp/rubocop/addon.rb +75 -0
- data/lib/ruby_lsp/rubocop/runtime_adapter.rb +47 -0
- metadata +75 -19
- data/lib/rubocop/rspec/host_environment_simulation_helper.rb +0 -28
@@ -14,7 +14,7 @@ module RuboCop
|
|
14
14
|
# passed multiple arguments.
|
15
15
|
#
|
16
16
|
# The exploded style has an `AllowedCompactTypes` configuration
|
17
|
-
# option that takes an Array of exception name Strings.
|
17
|
+
# option that takes an `Array` of exception name Strings.
|
18
18
|
#
|
19
19
|
# @safety
|
20
20
|
# This cop is unsafe because `raise Foo` calls `Foo.exception`, not `Foo.new`.
|
@@ -50,6 +50,9 @@ module RuboCop
|
|
50
50
|
|
51
51
|
EXPLODED_MSG = 'Provide an exception class and message as arguments to `%<method>s`.'
|
52
52
|
COMPACT_MSG = 'Provide an exception object as an argument to `%<method>s`.'
|
53
|
+
ACCEPTABLE_ARG_TYPES = %i[
|
54
|
+
hash forwarded_restarg splat forwarded_restarg forwarded_args
|
55
|
+
].freeze
|
53
56
|
|
54
57
|
RESTRICT_ON_SEND = %i[raise fail].freeze
|
55
58
|
|
@@ -138,9 +141,8 @@ module RuboCop
|
|
138
141
|
|
139
142
|
arg = args.first
|
140
143
|
|
141
|
-
# Allow
|
142
|
-
|
143
|
-
arg.hash_type? || arg.splat_type?
|
144
|
+
# Allow nodes that may forward more than one argument
|
145
|
+
ACCEPTABLE_ARG_TYPES.include?(arg.type)
|
144
146
|
end
|
145
147
|
|
146
148
|
def allowed_non_exploded_type?(arg)
|
@@ -150,7 +152,7 @@ module RuboCop
|
|
150
152
|
end
|
151
153
|
|
152
154
|
def requires_parens?(parent)
|
153
|
-
parent.
|
155
|
+
parent.operator_keyword? || (parent.if_type? && parent.ternary?)
|
154
156
|
end
|
155
157
|
end
|
156
158
|
end
|
@@ -36,7 +36,7 @@ module RuboCop
|
|
36
36
|
(send
|
37
37
|
{nil? (const {nil? cbase} :Random) (const {nil? cbase} :Kernel)}
|
38
38
|
:rand
|
39
|
-
{int (
|
39
|
+
{int (range int int)}))
|
40
40
|
PATTERN
|
41
41
|
|
42
42
|
# @!method rand_op_integer?(node)
|
@@ -45,7 +45,7 @@ module RuboCop
|
|
45
45
|
(send
|
46
46
|
{nil? (const {nil? cbase} :Random) (const {nil? cbase} :Kernel)}
|
47
47
|
:rand
|
48
|
-
{int (
|
48
|
+
{int (range int int)})
|
49
49
|
{:+ :-}
|
50
50
|
int)
|
51
51
|
PATTERN
|
@@ -56,7 +56,7 @@ module RuboCop
|
|
56
56
|
(send
|
57
57
|
{nil? (const {nil? cbase} :Random) (const {nil? cbase} :Kernel)}
|
58
58
|
:rand
|
59
|
-
{int (
|
59
|
+
{int (range int int)})
|
60
60
|
{:succ :pred :next})
|
61
61
|
PATTERN
|
62
62
|
|
@@ -118,7 +118,9 @@ module RuboCop
|
|
118
118
|
end
|
119
119
|
|
120
120
|
def exclude_cntrl_character?(target_argument, redundant_argument)
|
121
|
-
|
121
|
+
return true unless (target_argument_string = target_argument.to_s).valid_encoding?
|
122
|
+
|
123
|
+
!target_argument_string.sub(/\A'/, '"').sub(/'\z/, '"').match?(/[[:cntrl:]]/) ||
|
122
124
|
!redundant_argument.match?(/[[:cntrl:]]/)
|
123
125
|
end
|
124
126
|
end
|
@@ -68,6 +68,10 @@ module RuboCop
|
|
68
68
|
|
69
69
|
MSG = 'Redundant `begin` block detected.'
|
70
70
|
|
71
|
+
def self.autocorrect_incompatible_with
|
72
|
+
[Style::BlockDelimiters]
|
73
|
+
end
|
74
|
+
|
71
75
|
# @!method offensive_kwbegins(node)
|
72
76
|
def_node_search :offensive_kwbegins, <<~PATTERN
|
73
77
|
[(kwbegin ...) !#allowable_kwbegin?]
|
@@ -181,7 +185,7 @@ module RuboCop
|
|
181
185
|
def contain_rescue_or_ensure?(node)
|
182
186
|
first_child = node.children.first
|
183
187
|
|
184
|
-
first_child.
|
188
|
+
first_child.type?(:rescue, :ensure)
|
185
189
|
end
|
186
190
|
|
187
191
|
def valid_context_using_only_begin?(node)
|
@@ -5,6 +5,19 @@ module RuboCop
|
|
5
5
|
module Style
|
6
6
|
# Checks for unnecessary conditional expressions.
|
7
7
|
#
|
8
|
+
# NOTE: Since the intention of the comment cannot be automatically determined,
|
9
|
+
# autocorrection is not applied when a comment is used, as shown below:
|
10
|
+
#
|
11
|
+
# [source,ruby]
|
12
|
+
# -----
|
13
|
+
# if b
|
14
|
+
# # Important note.
|
15
|
+
# b
|
16
|
+
# else
|
17
|
+
# c
|
18
|
+
# end
|
19
|
+
# -----
|
20
|
+
#
|
8
21
|
# @example
|
9
22
|
# # bad
|
10
23
|
# a = b ? b : c
|
@@ -30,6 +43,7 @@ module RuboCop
|
|
30
43
|
# end
|
31
44
|
#
|
32
45
|
class RedundantCondition < Base
|
46
|
+
include CommentsHelp
|
33
47
|
include RangeHelp
|
34
48
|
extend AutoCorrector
|
35
49
|
|
@@ -39,25 +53,15 @@ module RuboCop
|
|
39
53
|
splat block_pass forwarded_restarg forwarded_kwrestarg forwarded_args
|
40
54
|
].freeze
|
41
55
|
|
42
|
-
# rubocop:disable Metrics/AbcSize
|
43
56
|
def on_if(node)
|
44
57
|
return if node.modifier_form? || node.elsif_conditional? || !offense?(node)
|
45
58
|
|
46
59
|
message = message(node)
|
47
60
|
|
48
61
|
add_offense(range_of_offense(node), message: message) do |corrector|
|
49
|
-
|
50
|
-
correct_ternary(corrector, node)
|
51
|
-
elsif redundant_condition?(node)
|
52
|
-
corrector.replace(node, node.if_branch.source)
|
53
|
-
else
|
54
|
-
corrected = make_ternary_form(node)
|
55
|
-
|
56
|
-
corrector.replace(node, corrected)
|
57
|
-
end
|
62
|
+
autocorrect(corrector, node)
|
58
63
|
end
|
59
64
|
end
|
60
|
-
# rubocop:enable Metrics/AbcSize
|
61
65
|
|
62
66
|
private
|
63
67
|
|
@@ -69,6 +73,20 @@ module RuboCop
|
|
69
73
|
end
|
70
74
|
end
|
71
75
|
|
76
|
+
def autocorrect(corrector, node)
|
77
|
+
return if node.each_descendant.any? { |descendant| contains_comments?(descendant) }
|
78
|
+
|
79
|
+
if node.ternary? && !branches_have_method?(node)
|
80
|
+
correct_ternary(corrector, node)
|
81
|
+
elsif redundant_condition?(node)
|
82
|
+
corrector.replace(node, node.if_branch.source)
|
83
|
+
else
|
84
|
+
corrected = make_ternary_form(node)
|
85
|
+
|
86
|
+
corrector.replace(node, corrected)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
72
90
|
def range_of_offense(node)
|
73
91
|
return node.source_range unless node.ternary?
|
74
92
|
return node.source_range if node.ternary? && branches_have_method?(node)
|
@@ -77,8 +95,7 @@ module RuboCop
|
|
77
95
|
end
|
78
96
|
|
79
97
|
def offense?(node)
|
80
|
-
_condition, _if_branch, else_branch = *node
|
81
|
-
|
98
|
+
_condition, _if_branch, else_branch = *node # rubocop:disable InternalAffairs/NodeDestructuring
|
82
99
|
return false if use_if_branch?(else_branch) || use_hash_key_assignment?(else_branch)
|
83
100
|
|
84
101
|
synonymous_condition_and_branch?(node) && !node.elsif? &&
|
@@ -94,7 +111,7 @@ module RuboCop
|
|
94
111
|
end
|
95
112
|
|
96
113
|
def use_hash_key_assignment?(else_branch)
|
97
|
-
else_branch&.send_type? && else_branch
|
114
|
+
else_branch&.send_type? && else_branch.method?(:[]=)
|
98
115
|
end
|
99
116
|
|
100
117
|
def use_hash_key_access?(node)
|
@@ -102,7 +119,7 @@ module RuboCop
|
|
102
119
|
end
|
103
120
|
|
104
121
|
def synonymous_condition_and_branch?(node)
|
105
|
-
condition, if_branch, _else_branch = *node
|
122
|
+
condition, if_branch, _else_branch = *node # rubocop:disable InternalAffairs/NodeDestructuring
|
106
123
|
# e.g.
|
107
124
|
# if var
|
108
125
|
# var
|
@@ -130,7 +147,7 @@ module RuboCop
|
|
130
147
|
end
|
131
148
|
|
132
149
|
def branches_have_assignment?(node)
|
133
|
-
_condition, if_branch, else_branch = *node
|
150
|
+
_condition, if_branch, else_branch = *node # rubocop:disable InternalAffairs/NodeDestructuring
|
134
151
|
|
135
152
|
return false unless if_branch && else_branch
|
136
153
|
|
@@ -140,16 +157,14 @@ module RuboCop
|
|
140
157
|
end
|
141
158
|
|
142
159
|
def asgn_type?(node)
|
143
|
-
node.
|
160
|
+
node.type?(:lvasgn, :ivasgn, :cvasgn, :gvasgn)
|
144
161
|
end
|
145
162
|
|
146
163
|
def branches_have_method?(node)
|
147
|
-
|
148
|
-
|
149
|
-
return false unless if_branch && else_branch
|
164
|
+
return false unless node.if_branch && node.else_branch
|
150
165
|
|
151
|
-
single_argument_method?(if_branch) && single_argument_method?(else_branch) &&
|
152
|
-
same_method?(if_branch, else_branch)
|
166
|
+
single_argument_method?(node.if_branch) && single_argument_method?(node.else_branch) &&
|
167
|
+
same_method?(node.if_branch, node.else_branch)
|
153
168
|
end
|
154
169
|
|
155
170
|
def single_argument_method?(node)
|
@@ -169,7 +184,7 @@ module RuboCop
|
|
169
184
|
return false unless argument.hash_type?
|
170
185
|
return false unless (node = argument.children.first)
|
171
186
|
|
172
|
-
node.
|
187
|
+
node.type?(:kwsplat, :forwarded_kwrestarg)
|
173
188
|
end
|
174
189
|
|
175
190
|
def if_source(if_branch, arithmetic_operation)
|
@@ -221,7 +236,7 @@ module RuboCop
|
|
221
236
|
end
|
222
237
|
|
223
238
|
def make_ternary_form(node)
|
224
|
-
_condition, if_branch, else_branch = *node
|
239
|
+
_condition, if_branch, else_branch = *node # rubocop:disable InternalAffairs/NodeDestructuring
|
225
240
|
arithmetic_operation = use_arithmetic_operation?(if_branch)
|
226
241
|
|
227
242
|
ternary_form = [
|
@@ -25,11 +25,11 @@ module RuboCop
|
|
25
25
|
MSG = 'Remove the redundant double splat and braces, use keyword arguments directly.'
|
26
26
|
MERGE_METHODS = %i[merge merge!].freeze
|
27
27
|
|
28
|
-
# rubocop:disable Metrics/
|
28
|
+
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
29
29
|
def on_hash(node)
|
30
30
|
return if node.pairs.empty? || node.pairs.any?(&:hash_rocket?)
|
31
31
|
return unless (parent = node.parent)
|
32
|
-
return unless parent.
|
32
|
+
return unless parent.type?(:call, :kwsplat)
|
33
33
|
return unless mergeable?(parent)
|
34
34
|
return unless (kwsplat = node.each_ancestor(:kwsplat).first)
|
35
35
|
return if !node.braces? || allowed_double_splat_receiver?(kwsplat)
|
@@ -38,13 +38,13 @@ module RuboCop
|
|
38
38
|
autocorrect(corrector, node, kwsplat)
|
39
39
|
end
|
40
40
|
end
|
41
|
-
# rubocop:enable Metrics/
|
41
|
+
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
42
42
|
|
43
43
|
private
|
44
44
|
|
45
45
|
def allowed_double_splat_receiver?(kwsplat)
|
46
46
|
first_child = kwsplat.children.first
|
47
|
-
return true if first_child.
|
47
|
+
return true if first_child.any_block_type?
|
48
48
|
return false unless first_child.call_type?
|
49
49
|
|
50
50
|
root_receiver = root_receiver(first_child)
|
@@ -73,7 +73,7 @@ module RuboCop
|
|
73
73
|
end
|
74
74
|
|
75
75
|
def select_merge_method_nodes(kwsplat)
|
76
|
-
|
76
|
+
kwsplat.each_descendant(:call).select do |node|
|
77
77
|
mergeable?(node)
|
78
78
|
end
|
79
79
|
end
|
@@ -89,7 +89,7 @@ module RuboCop
|
|
89
89
|
def autocorrect_merge_methods(corrector, merge_methods, kwsplat)
|
90
90
|
range = range_of_merge_methods(merge_methods)
|
91
91
|
|
92
|
-
new_kwsplat_arguments =
|
92
|
+
new_kwsplat_arguments = kwsplat.each_descendant(:call).map do |descendant|
|
93
93
|
convert_to_new_arguments(descendant)
|
94
94
|
end
|
95
95
|
new_source = new_kwsplat_arguments.compact.reverse.unshift('').join(', ')
|
@@ -104,10 +104,6 @@ module RuboCop
|
|
104
104
|
begin_merge_method.loc.dot.begin.join(end_merge_method.source_range.end)
|
105
105
|
end
|
106
106
|
|
107
|
-
def extract_send_methods(kwsplat)
|
108
|
-
kwsplat.each_descendant(:send, :csend)
|
109
|
-
end
|
110
|
-
|
111
107
|
def convert_to_new_arguments(node)
|
112
108
|
return unless mergeable?(node)
|
113
109
|
|
@@ -65,7 +65,7 @@ module RuboCop
|
|
65
65
|
return if node.last_argument&.block_pass_type?
|
66
66
|
|
67
67
|
if node.method?(:each) && !node.parent&.block_type?
|
68
|
-
ancestor_node = node.each_ancestor(:
|
68
|
+
ancestor_node = node.each_ancestor(:call).detect do |ancestor|
|
69
69
|
ancestor.receiver == node &&
|
70
70
|
(RESTRICT_ON_SEND.include?(ancestor.method_name) || ancestor.method?(:reverse_each))
|
71
71
|
end
|
@@ -3,7 +3,7 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module Style
|
6
|
-
# Checks for RuntimeError as the argument of raise
|
6
|
+
# Checks for `RuntimeError` as the argument of `raise`/`fail`.
|
7
7
|
#
|
8
8
|
# @example
|
9
9
|
# # bad
|
@@ -51,7 +51,7 @@ module RuboCop
|
|
51
51
|
end
|
52
52
|
|
53
53
|
def string_message?(message)
|
54
|
-
message.
|
54
|
+
message.type?(:str, :dstr, :xstr)
|
55
55
|
end
|
56
56
|
|
57
57
|
def fix_compact(node)
|
@@ -0,0 +1,222 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Style
|
6
|
+
# Checks for calls to `Kernel#format` or `Kernel#sprintf` that are redundant.
|
7
|
+
#
|
8
|
+
# Calling `format` with only a single string argument is redundant, as it can be
|
9
|
+
# replaced by the string itself.
|
10
|
+
#
|
11
|
+
# Also looks for `format` calls where the arguments are literals that can be
|
12
|
+
# inlined into a string easily. This applies to the `%s`, `%d`, `%i`, `%u`, and
|
13
|
+
# `%f` format specifiers.
|
14
|
+
#
|
15
|
+
# @example
|
16
|
+
#
|
17
|
+
# # bad
|
18
|
+
# format('the quick brown fox jumps over the lazy dog.')
|
19
|
+
# sprintf('the quick brown fox jumps over the lazy dog.')
|
20
|
+
#
|
21
|
+
# # good
|
22
|
+
# 'the quick brown fox jumps over the lazy dog.'
|
23
|
+
#
|
24
|
+
# # bad
|
25
|
+
# format('%s %s', 'foo', 'bar')
|
26
|
+
# sprintf('%s %s', 'foo', 'bar')
|
27
|
+
#
|
28
|
+
# # good
|
29
|
+
# 'foo bar'
|
30
|
+
#
|
31
|
+
class RedundantFormat < Base
|
32
|
+
extend AutoCorrector
|
33
|
+
|
34
|
+
MSG = 'Redundant `%<method_name>s` can be removed.'
|
35
|
+
|
36
|
+
RESTRICT_ON_SEND = %i[format sprintf].to_set.freeze
|
37
|
+
ACCEPTABLE_LITERAL_TYPES = %i[str dstr sym dsym numeric boolean nil].freeze
|
38
|
+
|
39
|
+
# @!method format_without_additional_args?(node)
|
40
|
+
def_node_matcher :format_without_additional_args?, <<~PATTERN
|
41
|
+
(send {(const {nil? cbase} :Kernel) nil?} %RESTRICT_ON_SEND ${str dstr})
|
42
|
+
PATTERN
|
43
|
+
|
44
|
+
# @!method rational_number?(node)
|
45
|
+
def_node_matcher :rational_number?, <<~PATTERN
|
46
|
+
{rational (send int :/ rational) (begin rational) (begin (send int :/ rational))}
|
47
|
+
PATTERN
|
48
|
+
|
49
|
+
# @!method complex_number?(node)
|
50
|
+
def_node_matcher :complex_number?, <<~PATTERN
|
51
|
+
{complex (send int :+ complex) (begin complex) (begin (send int :+ complex))}
|
52
|
+
PATTERN
|
53
|
+
|
54
|
+
# @!method find_hash_value_node(node, name)
|
55
|
+
def_node_search :find_hash_value_node, <<~PATTERN
|
56
|
+
(pair (sym %1) $_)
|
57
|
+
PATTERN
|
58
|
+
|
59
|
+
def on_send(node)
|
60
|
+
format_without_additional_args?(node) do |value|
|
61
|
+
add_offense(node, message: message(node)) do |corrector|
|
62
|
+
corrector.replace(node, value.source)
|
63
|
+
end
|
64
|
+
return
|
65
|
+
end
|
66
|
+
|
67
|
+
detect_unnecessary_fields(node)
|
68
|
+
end
|
69
|
+
|
70
|
+
private
|
71
|
+
|
72
|
+
def message(node)
|
73
|
+
format(MSG, method_name: node.method_name)
|
74
|
+
end
|
75
|
+
|
76
|
+
def detect_unnecessary_fields(node)
|
77
|
+
return unless node.first_argument&.str_type?
|
78
|
+
|
79
|
+
string = node.first_argument.value
|
80
|
+
arguments = node.arguments[1..]
|
81
|
+
|
82
|
+
return unless string && arguments.any?
|
83
|
+
return if arguments.any?(&:splat_type?)
|
84
|
+
|
85
|
+
register_all_fields_literal(node, string, arguments)
|
86
|
+
end
|
87
|
+
|
88
|
+
def register_all_fields_literal(node, string, arguments)
|
89
|
+
return unless all_fields_literal?(string, arguments.dup)
|
90
|
+
|
91
|
+
add_offense(node, message: message(node)) do |corrector|
|
92
|
+
replacement = format(string, *argument_values(arguments))
|
93
|
+
corrector.replace(node, quote(replacement, node))
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def all_fields_literal?(string, arguments)
|
98
|
+
count = 0
|
99
|
+
sequences = RuboCop::Cop::Utils::FormatString.new(string).format_sequences
|
100
|
+
return false unless sequences.any?
|
101
|
+
|
102
|
+
sequences.each do |sequence|
|
103
|
+
next if sequence.percent?
|
104
|
+
|
105
|
+
hash = arguments.detect(&:hash_type?)
|
106
|
+
argument = find_argument(sequence, arguments, hash)
|
107
|
+
next unless matching_argument?(sequence, argument)
|
108
|
+
|
109
|
+
count += 1
|
110
|
+
end
|
111
|
+
|
112
|
+
sequences.size == count
|
113
|
+
end
|
114
|
+
|
115
|
+
def find_argument(sequence, arguments, hash)
|
116
|
+
if sequence.annotated? || sequence.template?
|
117
|
+
find_hash_value_node(hash, sequence.name.to_sym).first
|
118
|
+
elsif sequence.arg_number
|
119
|
+
arguments[sequence.arg_number.to_i - 1]
|
120
|
+
else
|
121
|
+
# If the specifier contains `*`, the following arguments will be used
|
122
|
+
# to specify the width and can be ignored.
|
123
|
+
(sequence.arity - 1).times { arguments.shift }
|
124
|
+
arguments.shift
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def matching_argument?(sequence, argument)
|
129
|
+
# Template specifiers don't give a type, any acceptable literal type is ok.
|
130
|
+
return argument.type?(*ACCEPTABLE_LITERAL_TYPES) if sequence.template?
|
131
|
+
|
132
|
+
# An argument matches a specifier if it can be easily converted
|
133
|
+
# to that type.
|
134
|
+
case sequence.type
|
135
|
+
when 's'
|
136
|
+
argument.type?(*ACCEPTABLE_LITERAL_TYPES)
|
137
|
+
when 'd', 'i', 'u'
|
138
|
+
integer?(argument)
|
139
|
+
when 'f'
|
140
|
+
float?(argument)
|
141
|
+
else
|
142
|
+
false
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
def numeric?(argument)
|
147
|
+
argument.type?(:numeric, :str) ||
|
148
|
+
rational_number?(argument) ||
|
149
|
+
complex_number?(argument)
|
150
|
+
end
|
151
|
+
|
152
|
+
def integer?(argument)
|
153
|
+
numeric?(argument) && Integer(argument_value(argument), exception: false)
|
154
|
+
end
|
155
|
+
|
156
|
+
def float?(argument)
|
157
|
+
numeric?(argument) && Float(argument_value(argument), exception: false)
|
158
|
+
end
|
159
|
+
|
160
|
+
# Add correct quotes to the formatted string, preferring retaining the existing
|
161
|
+
# quotes if possible.
|
162
|
+
def quote(string, node)
|
163
|
+
str_node = node.first_argument
|
164
|
+
start_delimiter = str_node.loc.begin.source
|
165
|
+
end_delimiter = str_node.loc.end.source
|
166
|
+
|
167
|
+
# If there is any interpolation, the delimiters need to be changed potentially
|
168
|
+
if node.each_descendant(:dstr, :dsym).any?
|
169
|
+
case start_delimiter
|
170
|
+
when "'"
|
171
|
+
start_delimiter = end_delimiter = '"'
|
172
|
+
when /\A%q(.)/
|
173
|
+
start_delimiter = "%Q#{Regexp.last_match[1]}"
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
"#{start_delimiter}#{string}#{end_delimiter}"
|
178
|
+
end
|
179
|
+
|
180
|
+
def argument_values(arguments)
|
181
|
+
arguments.map { |argument| argument_value(argument) }
|
182
|
+
end
|
183
|
+
|
184
|
+
def argument_value(argument)
|
185
|
+
argument = argument.children.first if argument.begin_type?
|
186
|
+
|
187
|
+
if argument.dsym_type?
|
188
|
+
dsym_value(argument)
|
189
|
+
elsif argument.hash_type?
|
190
|
+
hash_value(argument)
|
191
|
+
elsif rational_number?(argument)
|
192
|
+
rational_value(argument)
|
193
|
+
elsif complex_number?(argument)
|
194
|
+
complex_value(argument)
|
195
|
+
elsif argument.respond_to?(:value)
|
196
|
+
argument.value
|
197
|
+
else
|
198
|
+
argument.source
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
def dsym_value(dsym_node)
|
203
|
+
dsym_node.children.first.source
|
204
|
+
end
|
205
|
+
|
206
|
+
def hash_value(hash_node)
|
207
|
+
hash_node.each_pair.with_object({}) do |pair, hash|
|
208
|
+
hash[pair.key.value] = argument_value(pair.value)
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
def rational_value(rational_node)
|
213
|
+
rational_node.source.to_r
|
214
|
+
end
|
215
|
+
|
216
|
+
def complex_value(complex_node)
|
217
|
+
Complex(complex_node.source)
|
218
|
+
end
|
219
|
+
end
|
220
|
+
end
|
221
|
+
end
|
222
|
+
end
|
@@ -5,7 +5,7 @@ module RuboCop
|
|
5
5
|
module Style
|
6
6
|
# Check for uses of `Object#freeze` on immutable objects.
|
7
7
|
#
|
8
|
-
# NOTE: Regexp and Range literals are frozen objects since Ruby 3.0.
|
8
|
+
# NOTE: `Regexp` and `Range` literals are frozen objects since Ruby 3.0.
|
9
9
|
#
|
10
10
|
# NOTE: From Ruby 3.0, this cop allows explicit freezing of interpolated
|
11
11
|
# string literals when `# frozen-string-literal: true` is used.
|
@@ -42,7 +42,7 @@ module RuboCop
|
|
42
42
|
return true if node.immutable_literal?
|
43
43
|
return true if frozen_string_literal?(node)
|
44
44
|
|
45
|
-
target_ruby_version >= 3.0 &&
|
45
|
+
target_ruby_version >= 3.0 && node.type?(:regexp, :range)
|
46
46
|
end
|
47
47
|
|
48
48
|
def strip_parenthesis(node)
|
@@ -11,6 +11,9 @@ module RuboCop
|
|
11
11
|
# will not register an offense, because it allows the initializer to take a different
|
12
12
|
# number of arguments as its superclass potentially does.
|
13
13
|
#
|
14
|
+
# NOTE: If an initializer takes any arguments and has an empty body, RuboCop
|
15
|
+
# assumes it to *not* be redundant. This is to prevent potential `ArgumentError`.
|
16
|
+
#
|
14
17
|
# NOTE: If an initializer argument has a default value, RuboCop assumes it
|
15
18
|
# to *not* be redundant.
|
16
19
|
#
|
@@ -19,8 +22,10 @@ module RuboCop
|
|
19
22
|
# initializer.
|
20
23
|
#
|
21
24
|
# @safety
|
22
|
-
# This cop is unsafe because
|
23
|
-
#
|
25
|
+
# This cop is unsafe because removing an empty initializer may alter
|
26
|
+
# the behavior of the code, particularly if the superclass initializer
|
27
|
+
# raises an exception. In such cases, the empty initializer may act as
|
28
|
+
# a safeguard to prevent unintended errors from propagating.
|
24
29
|
#
|
25
30
|
# @example
|
26
31
|
# # bad
|
@@ -69,6 +74,10 @@ module RuboCop
|
|
69
74
|
# end
|
70
75
|
#
|
71
76
|
# # good (changes the parameter requirements)
|
77
|
+
# def initialize(_)
|
78
|
+
# end
|
79
|
+
#
|
80
|
+
# # good (changes the parameter requirements)
|
72
81
|
# def initialize(*)
|
73
82
|
# end
|
74
83
|
#
|
@@ -111,7 +120,7 @@ module RuboCop
|
|
111
120
|
return if acceptable?(node)
|
112
121
|
|
113
122
|
if node.body.nil?
|
114
|
-
register_offense(node, MSG_EMPTY)
|
123
|
+
register_offense(node, MSG_EMPTY) if node.arguments.empty?
|
115
124
|
else
|
116
125
|
return if node.body.begin_type?
|
117
126
|
|