rubocop 1.66.1 → 1.72.2
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 +162 -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 +2 -2
- data/lib/rubocop/config.rb +17 -4
- data/lib/rubocop/config_loader.rb +48 -8
- data/lib/rubocop/config_loader_resolver.rb +36 -11
- data/lib/rubocop/config_validator.rb +20 -9
- 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/example_description.rb +4 -2
- 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 +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 +80 -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/allowed_pattern.rb +4 -4
- 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 +4 -2
- data/lib/rubocop/cop/style/empty_literal.rb +1 -1
- 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 +26 -11
- 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/map_into_array.rb +60 -9
- 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 +238 -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_line_continuation.rb +56 -17
- data/lib/rubocop/cop/style/redundant_parentheses.rb +37 -25
- 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 +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 +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 +9 -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 -27
- 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
@@ -43,23 +43,21 @@ module RuboCop
|
|
43
43
|
alias on_csend on_send
|
44
44
|
|
45
45
|
def on_lvasgn(node)
|
46
|
-
|
47
|
-
return unless rhs
|
46
|
+
return unless node.rhs
|
48
47
|
|
49
48
|
rhs_type = ASSIGNMENT_TYPE_TO_RHS_TYPE[node.type]
|
50
49
|
|
51
|
-
add_offense(node) if rhs.type == rhs_type && rhs.source == lhs.to_s
|
50
|
+
add_offense(node) if node.rhs.type == rhs_type && node.rhs.source == node.lhs.to_s
|
52
51
|
end
|
53
52
|
alias on_ivasgn on_lvasgn
|
54
53
|
alias on_cvasgn on_lvasgn
|
55
54
|
alias on_gvasgn on_lvasgn
|
56
55
|
|
57
56
|
def on_casgn(node)
|
58
|
-
|
59
|
-
return unless rhs&.const_type?
|
57
|
+
return unless node.rhs&.const_type?
|
60
58
|
|
61
|
-
|
62
|
-
|
59
|
+
add_offense(node) if node.namespace == node.rhs.namespace &&
|
60
|
+
node.short_name == node.rhs.short_name
|
63
61
|
end
|
64
62
|
|
65
63
|
def on_masgn(node)
|
@@ -67,15 +65,15 @@ module RuboCop
|
|
67
65
|
end
|
68
66
|
|
69
67
|
def on_or_asgn(node)
|
70
|
-
|
71
|
-
add_offense(node) if rhs_matches_lhs?(rhs, lhs)
|
68
|
+
add_offense(node) if rhs_matches_lhs?(node.rhs, node.lhs)
|
72
69
|
end
|
73
70
|
alias on_and_asgn on_or_asgn
|
74
71
|
|
75
72
|
private
|
76
73
|
|
77
74
|
def multiple_self_assignment?(node)
|
78
|
-
lhs
|
75
|
+
lhs = node.lhs
|
76
|
+
rhs = node.rhs
|
79
77
|
return false unless rhs.array_type?
|
80
78
|
return false unless lhs.children.size == rhs.children.size
|
81
79
|
|
@@ -67,7 +67,7 @@ module RuboCop
|
|
67
67
|
def on_rescue(node)
|
68
68
|
return if rescue_modifier?(node)
|
69
69
|
|
70
|
-
|
70
|
+
rescues = node.resbody_branches
|
71
71
|
rescued_groups = rescued_groups_for(rescues)
|
72
72
|
|
73
73
|
rescue_group_rescues_multiple_levels = rescued_groups.any? do |group|
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Lint
|
6
|
+
# Checks for `Hash` creation with a mutable default value.
|
7
|
+
# Creating a `Hash` in such a way will share the default value
|
8
|
+
# across all keys, causing unexpected behavior when modifying it.
|
9
|
+
#
|
10
|
+
# For example, when the `Hash` was created with an `Array` as the argument,
|
11
|
+
# calling `hash[:foo] << 'bar'` will also change the value of all
|
12
|
+
# other keys that have not been explicitly assigned to.
|
13
|
+
#
|
14
|
+
# @example
|
15
|
+
# # bad
|
16
|
+
# Hash.new([])
|
17
|
+
# Hash.new({})
|
18
|
+
# Hash.new(Array.new)
|
19
|
+
# Hash.new(Hash.new)
|
20
|
+
#
|
21
|
+
# # okay -- In rare cases that intentionally have this behavior,
|
22
|
+
# # without disabling the cop, you can set the default explicitly.
|
23
|
+
# h = Hash.new
|
24
|
+
# h.default = []
|
25
|
+
# h[:a] << 1
|
26
|
+
# h[:b] << 2
|
27
|
+
# h # => {:a => [1, 2], :b => [1, 2]}
|
28
|
+
#
|
29
|
+
# # okay -- beware this will discard mutations and only remember assignments
|
30
|
+
# Hash.new { Array.new }
|
31
|
+
# Hash.new { Hash.new }
|
32
|
+
# Hash.new { {} }
|
33
|
+
# Hash.new { [] }
|
34
|
+
#
|
35
|
+
# # good - frozen solution will raise an error when mutation attempted
|
36
|
+
# Hash.new([].freeze)
|
37
|
+
# Hash.new({}.freeze)
|
38
|
+
#
|
39
|
+
# # good - using a proc will create a new object for each key
|
40
|
+
# h = Hash.new
|
41
|
+
# h.default_proc = ->(h, k) { [] }
|
42
|
+
# h.default_proc = ->(h, k) { {} }
|
43
|
+
#
|
44
|
+
# # good - using a block will create a new object for each key
|
45
|
+
# Hash.new { |h, k| h[k] = [] }
|
46
|
+
# Hash.new { |h, k| h[k] = {} }
|
47
|
+
class SharedMutableDefault < Base
|
48
|
+
MSG = 'Do not create a Hash with a mutable default value ' \
|
49
|
+
'as the default value can accidentally be changed.'
|
50
|
+
RESTRICT_ON_SEND = %i[new].freeze
|
51
|
+
|
52
|
+
# @!method hash_initialized_with_mutable_shared_object?(node)
|
53
|
+
def_node_matcher :hash_initialized_with_mutable_shared_object?, <<~PATTERN
|
54
|
+
(send (const {nil? cbase} :Hash) :new {array hash (send (const {nil? cbase} {:Array :Hash}) :new)})
|
55
|
+
PATTERN
|
56
|
+
|
57
|
+
def on_send(node)
|
58
|
+
return unless hash_initialized_with_mutable_shared_object?(node)
|
59
|
+
|
60
|
+
add_offense(node)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -116,7 +116,7 @@ module RuboCop
|
|
116
116
|
private
|
117
117
|
|
118
118
|
def comment_between_rescue_and_end?(node)
|
119
|
-
ancestor = node.each_ancestor(:kwbegin, :def, :defs, :
|
119
|
+
ancestor = node.each_ancestor(:kwbegin, :def, :defs, :any_block).first
|
120
120
|
return false unless ancestor
|
121
121
|
|
122
122
|
end_line = ancestor.loc.end&.line || ancestor.loc.last_line
|
@@ -0,0 +1,111 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Lint
|
6
|
+
# Checks for cases where exceptions unrelated to the numeric constructors `Integer()`,
|
7
|
+
# `Float()`, `BigDecimal()`, `Complex()`, and `Rational()` may be unintentionally swallowed.
|
8
|
+
#
|
9
|
+
# @safety
|
10
|
+
# The cop is unsafe for autocorrection because unexpected errors occurring in the argument
|
11
|
+
# passed to numeric constructor (e.g., `Integer()`) can lead to incompatible behavior.
|
12
|
+
# For example, changing it to `Integer(potential_exception_method_call, exception: false)`
|
13
|
+
# ensures that exceptions raised by `potential_exception_method_call` are not ignored.
|
14
|
+
#
|
15
|
+
# [source,ruby]
|
16
|
+
# ----
|
17
|
+
# Integer(potential_exception_method_call) rescue nil
|
18
|
+
# ----
|
19
|
+
#
|
20
|
+
# @example
|
21
|
+
#
|
22
|
+
# # bad
|
23
|
+
# Integer(arg) rescue nil
|
24
|
+
#
|
25
|
+
# # bad
|
26
|
+
# begin
|
27
|
+
# Integer(arg)
|
28
|
+
# rescue
|
29
|
+
# nil
|
30
|
+
# end
|
31
|
+
#
|
32
|
+
# # bad
|
33
|
+
# begin
|
34
|
+
# Integer(arg)
|
35
|
+
# rescue
|
36
|
+
# end
|
37
|
+
#
|
38
|
+
# # good
|
39
|
+
# Integer(arg, exception: false)
|
40
|
+
#
|
41
|
+
class SuppressedExceptionInNumberConversion < Base
|
42
|
+
extend AutoCorrector
|
43
|
+
extend TargetRubyVersion
|
44
|
+
|
45
|
+
MSG = 'Use `%<prefer>s` instead.'
|
46
|
+
EXPECTED_EXCEPTION_CLASSES = %w[ArgumentError TypeError ::ArgumentError ::TypeError].freeze
|
47
|
+
|
48
|
+
# @!method numeric_constructor_rescue_nil(node)
|
49
|
+
def_node_matcher :numeric_constructor_rescue_nil, <<~PATTERN
|
50
|
+
(rescue
|
51
|
+
$#numeric_method?
|
52
|
+
(resbody nil? nil? (nil)) nil?)
|
53
|
+
PATTERN
|
54
|
+
|
55
|
+
# @!method begin_numeric_constructor_rescue_nil(node)
|
56
|
+
def_node_matcher :begin_numeric_constructor_rescue_nil, <<~PATTERN
|
57
|
+
(kwbegin
|
58
|
+
(rescue
|
59
|
+
$#numeric_method?
|
60
|
+
(resbody $_? nil?
|
61
|
+
{(nil) nil?}) nil?))
|
62
|
+
PATTERN
|
63
|
+
|
64
|
+
# @!method numeric_method?(node)
|
65
|
+
def_node_matcher :numeric_method?, <<~PATTERN
|
66
|
+
{
|
67
|
+
(call #constructor_receiver? {:Integer :BigDecimal :Complex :Rational}
|
68
|
+
_ _?)
|
69
|
+
(call #constructor_receiver? :Float
|
70
|
+
_)
|
71
|
+
}
|
72
|
+
PATTERN
|
73
|
+
|
74
|
+
# @!method constructor_receiver?(node)
|
75
|
+
def_node_matcher :constructor_receiver?, <<~PATTERN
|
76
|
+
{nil? (const {nil? cbase} :Kernel)}
|
77
|
+
PATTERN
|
78
|
+
|
79
|
+
minimum_target_ruby_version 2.6
|
80
|
+
|
81
|
+
# rubocop:disable Metrics/AbcSize
|
82
|
+
def on_rescue(node)
|
83
|
+
if (method, exception_classes = begin_numeric_constructor_rescue_nil(node.parent))
|
84
|
+
return unless expected_exception_classes_only?(exception_classes)
|
85
|
+
|
86
|
+
node = node.parent
|
87
|
+
else
|
88
|
+
return unless (method = numeric_constructor_rescue_nil(node))
|
89
|
+
end
|
90
|
+
|
91
|
+
arguments = method.arguments.map(&:source) << 'exception: false'
|
92
|
+
prefer = "#{method.method_name}(#{arguments.join(', ')})"
|
93
|
+
prefer = "#{method.receiver.source}#{method.loc.dot.source}#{prefer}" if method.receiver
|
94
|
+
|
95
|
+
add_offense(node, message: format(MSG, prefer: prefer)) do |corrector|
|
96
|
+
corrector.replace(node, prefer)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
# rubocop:enable Metrics/AbcSize
|
100
|
+
|
101
|
+
private
|
102
|
+
|
103
|
+
def expected_exception_classes_only?(exception_classes)
|
104
|
+
return true unless (arguments = exception_classes.first)
|
105
|
+
|
106
|
+
(arguments.values.map(&:source) - EXPECTED_EXCEPTION_CLASSES).none?
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
@@ -78,7 +78,7 @@ module RuboCop
|
|
78
78
|
def on_send(node)
|
79
79
|
return unless node.receiver
|
80
80
|
|
81
|
-
if node.receiver.
|
81
|
+
if node.receiver.type?(:str, :sym)
|
82
82
|
register_offense(node, correction: node.receiver.value.to_sym.inspect)
|
83
83
|
elsif node.receiver.dstr_type?
|
84
84
|
register_offense(node, correction: ":\"#{node.receiver.value.to_sym}\"")
|
@@ -141,7 +141,7 @@ module RuboCop
|
|
141
141
|
end
|
142
142
|
|
143
143
|
def in_percent_literal_array?(node)
|
144
|
-
node.parent&.array_type? && node.parent
|
144
|
+
node.parent&.array_type? && node.parent.percent_literal?
|
145
145
|
end
|
146
146
|
|
147
147
|
def correct_hash_key(node)
|
@@ -6,9 +6,12 @@ module RuboCop
|
|
6
6
|
# Repacks Parser's diagnostics/errors
|
7
7
|
# into RuboCop's offenses.
|
8
8
|
class Syntax < Base
|
9
|
+
LEVELS = %i[error fatal].freeze
|
10
|
+
|
9
11
|
def on_other_file
|
10
12
|
add_offense_from_error(processed_source.parser_error) if processed_source.parser_error
|
11
|
-
processed_source.diagnostics.
|
13
|
+
syntax_errors = processed_source.diagnostics.select { |d| LEVELS.include?(d.level) }
|
14
|
+
syntax_errors.each do |diagnostic|
|
12
15
|
add_offense_from_diagnostic(diagnostic, processed_source.ruby_version)
|
13
16
|
end
|
14
17
|
super
|
@@ -0,0 +1,88 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Lint
|
6
|
+
# Checks for Regexpes (both literals and via `Regexp.new` / `Regexp.compile`)
|
7
|
+
# that contain unescaped `]` characters.
|
8
|
+
#
|
9
|
+
# It emulates the following Ruby warning:
|
10
|
+
#
|
11
|
+
# [source,ruby]
|
12
|
+
# ----
|
13
|
+
# $ ruby -e '/abc]123/'
|
14
|
+
# -e:1: warning: regular expression has ']' without escape: /abc]123/
|
15
|
+
# ----
|
16
|
+
#
|
17
|
+
# @example
|
18
|
+
# # bad
|
19
|
+
# /abc]123/
|
20
|
+
# %r{abc]123}
|
21
|
+
# Regexp.new('abc]123')
|
22
|
+
# Regexp.compile('abc]123')
|
23
|
+
#
|
24
|
+
# # good
|
25
|
+
# /abc\]123/
|
26
|
+
# %r{abc\]123}
|
27
|
+
# Regexp.new('abc\]123')
|
28
|
+
# Regexp.compile('abc\]123')
|
29
|
+
#
|
30
|
+
class UnescapedBracketInRegexp < Base
|
31
|
+
extend AutoCorrector
|
32
|
+
|
33
|
+
MSG = 'Regular expression has `]` without escape.'
|
34
|
+
RESTRICT_ON_SEND = %i[new compile].freeze
|
35
|
+
|
36
|
+
# @!method regexp_constructor(node)
|
37
|
+
def_node_search :regexp_constructor, <<~PATTERN
|
38
|
+
(send
|
39
|
+
(const {nil? cbase} :Regexp) {:new :compile}
|
40
|
+
$str
|
41
|
+
...
|
42
|
+
)
|
43
|
+
PATTERN
|
44
|
+
|
45
|
+
def on_regexp(node)
|
46
|
+
RuboCop::Util.silence_warnings do
|
47
|
+
node.parsed_tree&.each_expression do |expr|
|
48
|
+
detect_offenses(node, expr)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def on_send(node)
|
54
|
+
# Ignore nodes that contain interpolation
|
55
|
+
return if node.each_descendant(:dstr).any?
|
56
|
+
|
57
|
+
regexp_constructor(node) do |text|
|
58
|
+
parse_regexp(text.value)&.each_expression do |expr|
|
59
|
+
detect_offenses(text, expr)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
def detect_offenses(node, expr)
|
67
|
+
return unless expr.type?(:literal)
|
68
|
+
|
69
|
+
expr.text.scan(/(?<!\\)\]/) do
|
70
|
+
pos = Regexp.last_match.begin(0)
|
71
|
+
next if pos.zero? # if the unescaped bracket is the first character, Ruby does not warn
|
72
|
+
|
73
|
+
location = range_at_index(node, expr.ts, pos)
|
74
|
+
|
75
|
+
add_offense(location) do |corrector|
|
76
|
+
corrector.replace(location, '\]')
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def range_at_index(node, index, offset)
|
82
|
+
adjustment = index + offset
|
83
|
+
node.loc.begin.end.adjust(begin_pos: adjustment, end_pos: adjustment + 1)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -130,7 +130,7 @@ module RuboCop
|
|
130
130
|
|
131
131
|
block_body_node.each_descendant(:next, :break) do |n|
|
132
132
|
# Ignore `next`/`break` inside an inner block
|
133
|
-
next if n.each_ancestor(:
|
133
|
+
next if n.each_ancestor(:any_block).first != block_body_node.parent
|
134
134
|
next unless n.first_argument
|
135
135
|
|
136
136
|
nodes << n.first_argument
|
@@ -32,6 +32,22 @@ module RuboCop
|
|
32
32
|
class UnreachableCode < Base
|
33
33
|
MSG = 'Unreachable code detected.'
|
34
34
|
|
35
|
+
def initialize(config = nil, options = nil)
|
36
|
+
super
|
37
|
+
@redefined = []
|
38
|
+
@instance_eval_count = 0
|
39
|
+
end
|
40
|
+
|
41
|
+
def on_block(node)
|
42
|
+
@instance_eval_count += 1 if instance_eval_block?(node)
|
43
|
+
end
|
44
|
+
|
45
|
+
alias on_numblock on_block
|
46
|
+
|
47
|
+
def after_block(node)
|
48
|
+
@instance_eval_count -= 1 if instance_eval_block?(node)
|
49
|
+
end
|
50
|
+
|
35
51
|
def on_begin(node)
|
36
52
|
expressions = *node
|
37
53
|
|
@@ -46,19 +62,23 @@ module RuboCop
|
|
46
62
|
|
47
63
|
private
|
48
64
|
|
65
|
+
def redefinable_flow_method?(method)
|
66
|
+
%i[raise fail throw exit exit! abort].include? method
|
67
|
+
end
|
68
|
+
|
49
69
|
# @!method flow_command?(node)
|
50
70
|
def_node_matcher :flow_command?, <<~PATTERN
|
51
71
|
{
|
52
72
|
return next break retry redo
|
53
73
|
(send
|
54
74
|
{nil? (const {nil? cbase} :Kernel)}
|
55
|
-
|
75
|
+
#redefinable_flow_method?
|
56
76
|
...)
|
57
77
|
}
|
58
78
|
PATTERN
|
59
79
|
|
60
80
|
def flow_expression?(node)
|
61
|
-
return
|
81
|
+
return report_on_flow_command?(node) if flow_command?(node)
|
62
82
|
|
63
83
|
case node.type
|
64
84
|
when :begin, :kwbegin
|
@@ -68,6 +88,8 @@ module RuboCop
|
|
68
88
|
check_if(node)
|
69
89
|
when :case, :case_match
|
70
90
|
check_case(node)
|
91
|
+
when :def
|
92
|
+
register_redefinition(node)
|
71
93
|
else
|
72
94
|
false
|
73
95
|
end
|
@@ -88,6 +110,33 @@ module RuboCop
|
|
88
110
|
|
89
111
|
branches.all? { |branch| branch.body && flow_expression?(branch.body) }
|
90
112
|
end
|
113
|
+
|
114
|
+
def register_redefinition(node)
|
115
|
+
@redefined << node.method_name if redefinable_flow_method? node.method_name
|
116
|
+
false
|
117
|
+
end
|
118
|
+
|
119
|
+
def instance_eval_block?(node)
|
120
|
+
node.any_block_type? && node.method?(:instance_eval)
|
121
|
+
end
|
122
|
+
|
123
|
+
def report_on_flow_command?(node)
|
124
|
+
return true unless node.send_type?
|
125
|
+
|
126
|
+
# By the contract of this function, this case means that
|
127
|
+
# the method is called on `Kernel` in which case we
|
128
|
+
# always want to report a warning.
|
129
|
+
return true if node.receiver
|
130
|
+
|
131
|
+
# Inside an `instance_eval` we have no way to tell the
|
132
|
+
# type of `self` just by looking at the AST, so we can't
|
133
|
+
# tell if the give function that's called has been
|
134
|
+
# redefined or not, so to avoid false positives, we silence
|
135
|
+
# the warning.
|
136
|
+
return false if @instance_eval_count.positive?
|
137
|
+
|
138
|
+
!@redefined.include? node.method_name
|
139
|
+
end
|
91
140
|
end
|
92
141
|
end
|
93
142
|
end
|
@@ -108,7 +108,7 @@ module RuboCop
|
|
108
108
|
private
|
109
109
|
|
110
110
|
def loop_method?(node)
|
111
|
-
return false unless node.
|
111
|
+
return false unless node.any_block_type?
|
112
112
|
|
113
113
|
send_node = node.send_node
|
114
114
|
loopable = send_node.enumerable_method? || send_node.enumerator_method? ||
|
@@ -39,6 +39,8 @@ module RuboCop
|
|
39
39
|
# end
|
40
40
|
#
|
41
41
|
# @example IgnoreNotImplementedMethods: true (default)
|
42
|
+
# # with default value of `NotImplementedExceptions: ['NotImplementedError']`
|
43
|
+
#
|
42
44
|
# # good
|
43
45
|
# def do_something(unused)
|
44
46
|
# raise NotImplementedError
|
@@ -48,6 +50,14 @@ module RuboCop
|
|
48
50
|
# fail "TODO"
|
49
51
|
# end
|
50
52
|
#
|
53
|
+
# @example IgnoreNotImplementedMethods: true
|
54
|
+
# # with `NotImplementedExceptions: ['AbstractMethodError']`
|
55
|
+
#
|
56
|
+
# # good
|
57
|
+
# def do_something(unused)
|
58
|
+
# raise AbstractMethodError
|
59
|
+
# end
|
60
|
+
#
|
51
61
|
# @example IgnoreNotImplementedMethods: false
|
52
62
|
# # bad
|
53
63
|
# def do_something(unused)
|
@@ -57,14 +67,13 @@ module RuboCop
|
|
57
67
|
# def do_something_else(unused)
|
58
68
|
# fail "TODO"
|
59
69
|
# end
|
60
|
-
#
|
61
70
|
class UnusedMethodArgument < Base
|
62
71
|
include UnusedArgument
|
63
72
|
extend AutoCorrector
|
64
73
|
|
65
74
|
# @!method not_implemented?(node)
|
66
75
|
def_node_matcher :not_implemented?, <<~PATTERN
|
67
|
-
{(send nil? :raise
|
76
|
+
{(send nil? :raise #allowed_exception_class? ...)
|
68
77
|
(send nil? :fail ...)}
|
69
78
|
PATTERN
|
70
79
|
|
@@ -115,6 +124,13 @@ module RuboCop
|
|
115
124
|
|
116
125
|
message
|
117
126
|
end
|
127
|
+
|
128
|
+
def allowed_exception_class?(node)
|
129
|
+
return false unless node.const_type?
|
130
|
+
|
131
|
+
allowed_class_names = Array(cop_config.fetch('NotImplementedExceptions', []))
|
132
|
+
allowed_class_names.include?(node.const_name)
|
133
|
+
end
|
118
134
|
end
|
119
135
|
end
|
120
136
|
end
|
@@ -3,29 +3,47 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module Lint
|
6
|
-
# Identifies places where `URI.regexp` is obsolete and should
|
7
|
-
#
|
6
|
+
# Identifies places where `URI.regexp` is obsolete and should not be used.
|
7
|
+
#
|
8
|
+
# For Ruby 3.3 or lower, use `URI::DEFAULT_PARSER.make_regexp`.
|
9
|
+
# For Ruby 3.4 or higher, use `URI::RFC2396_PARSER.make_regexp`.
|
10
|
+
#
|
11
|
+
# NOTE: If you need to support both Ruby 3.3 and lower as well as Ruby 3.4 and higher,
|
12
|
+
# consider manually changing the code as follows:
|
13
|
+
#
|
14
|
+
# [source,ruby]
|
15
|
+
# ----
|
16
|
+
# defined?(URI::RFC2396_PARSER) ? URI::RFC2396_PARSER : URI::DEFAULT_PARSER
|
17
|
+
# ----
|
8
18
|
#
|
9
19
|
# @example
|
10
20
|
# # bad
|
11
21
|
# URI.regexp('http://example.com')
|
12
22
|
#
|
13
|
-
# # good
|
23
|
+
# # good - Ruby 3.3 or lower
|
14
24
|
# URI::DEFAULT_PARSER.make_regexp('http://example.com')
|
15
25
|
#
|
26
|
+
# # good - Ruby 3.4 or higher
|
27
|
+
# URI::RFC2396_PARSER.make_regexp('http://example.com')
|
28
|
+
#
|
16
29
|
class UriRegexp < Base
|
17
30
|
extend AutoCorrector
|
18
31
|
|
19
32
|
MSG = '`%<current>s` is obsolete and should not be used. Instead, use `%<preferred>s`.'
|
20
|
-
URI_CONSTANTS = ['URI', '::URI'].freeze
|
21
33
|
RESTRICT_ON_SEND = %i[regexp].freeze
|
22
34
|
|
35
|
+
# @!method uri_constant?(node)
|
36
|
+
def_node_matcher :uri_constant?, <<~PATTERN
|
37
|
+
(const {cbase nil?} :URI)
|
38
|
+
PATTERN
|
39
|
+
|
23
40
|
def on_send(node)
|
24
|
-
return unless node.receiver
|
25
|
-
return unless URI_CONSTANTS.include?(node.receiver.source)
|
41
|
+
return unless uri_constant?(node.receiver)
|
26
42
|
|
43
|
+
parser = target_ruby_version >= 3.4 ? 'RFC2396_PARSER' : 'DEFAULT_PARSER'
|
27
44
|
argument = node.first_argument ? "(#{node.first_argument.source})" : ''
|
28
|
-
|
45
|
+
|
46
|
+
preferred_method = "#{node.receiver.source}::#{parser}.make_regexp#{argument}"
|
29
47
|
message = format(MSG, current: node.source, preferred: preferred_method)
|
30
48
|
|
31
49
|
add_offense(node.loc.selector, message: message) do |corrector|
|
@@ -159,12 +159,12 @@ module RuboCop
|
|
159
159
|
|
160
160
|
# @!method dynamic_method_definition?(node)
|
161
161
|
def_node_matcher :dynamic_method_definition?, <<~PATTERN
|
162
|
-
{(send nil? :define_method ...) (
|
162
|
+
{(send nil? :define_method ...) (any_block (send nil? :define_method ...) ...)}
|
163
163
|
PATTERN
|
164
164
|
|
165
165
|
# @!method class_or_instance_eval?(node)
|
166
166
|
def_node_matcher :class_or_instance_eval?, <<~PATTERN
|
167
|
-
(
|
167
|
+
(any_block (send _ {:class_eval :instance_eval}) ...)
|
168
168
|
PATTERN
|
169
169
|
|
170
170
|
def check_node(node)
|
@@ -268,7 +268,7 @@ module RuboCop
|
|
268
268
|
end
|
269
269
|
|
270
270
|
def start_of_new_scope?(child)
|
271
|
-
child.
|
271
|
+
child.type?(:module, :class, :sclass) || eval_call?(child)
|
272
272
|
end
|
273
273
|
|
274
274
|
def eval_call?(child)
|
@@ -282,7 +282,7 @@ module RuboCop
|
|
282
282
|
matcher_name = :"#{m}_block?"
|
283
283
|
unless respond_to?(matcher_name)
|
284
284
|
self.class.def_node_matcher matcher_name, <<~PATTERN
|
285
|
-
(
|
285
|
+
(any_block (send {nil? const} {:#{m}} ...) ...)
|
286
286
|
PATTERN
|
287
287
|
end
|
288
288
|
|
@@ -17,7 +17,7 @@ module RuboCop
|
|
17
17
|
# rescue, ensure, etc.
|
18
18
|
#
|
19
19
|
# This cop's autocorrection avoids cases like `a ||= 1` because removing assignment from
|
20
|
-
# operator assignment can cause NameError if this assignment has been used to declare
|
20
|
+
# operator assignment can cause `NameError` if this assignment has been used to declare
|
21
21
|
# a local variable. For example, replacing `a ||= 1` with `a || 1` may cause
|
22
22
|
# "undefined local variable or method `a' for main:Object (NameError)".
|
23
23
|
#
|