rubocop 1.69.0 → 1.79.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 +23 -19
- data/config/default.yml +290 -65
- data/config/internal_affairs.yml +20 -0
- data/config/obsoletion.yml +8 -3
- data/lib/rubocop/cli/command/execute_runner.rb +3 -3
- data/lib/rubocop/cli/command/show_cops.rb +24 -2
- data/lib/rubocop/cli/command/suggest_extensions.rb +7 -1
- data/lib/rubocop/cli.rb +13 -2
- data/lib/rubocop/comment_config.rb +2 -2
- data/lib/rubocop/config.rb +52 -10
- data/lib/rubocop/config_loader.rb +53 -47
- data/lib/rubocop/config_loader_resolver.rb +36 -10
- data/lib/rubocop/config_obsoletion/extracted_cop.rb +4 -3
- data/lib/rubocop/config_obsoletion/renamed_cop.rb +18 -3
- data/lib/rubocop/config_obsoletion.rb +46 -2
- data/lib/rubocop/config_validator.rb +25 -14
- data/lib/rubocop/cop/autocorrect_logic.rb +44 -39
- data/lib/rubocop/cop/base.rb +6 -0
- data/lib/rubocop/cop/bundler/duplicated_gem.rb +2 -2
- data/lib/rubocop/cop/bundler/gem_comment.rb +1 -1
- data/lib/rubocop/cop/bundler/ordered_gems.rb +1 -1
- data/lib/rubocop/cop/correctors/parentheses_corrector.rb +5 -2
- data/lib/rubocop/cop/gemspec/attribute_assignment.rb +91 -0
- data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +37 -15
- data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +1 -1
- data/lib/rubocop/cop/gemspec/require_mfa.rb +15 -1
- data/lib/rubocop/cop/generator.rb +6 -0
- data/lib/rubocop/cop/internal_affairs/cop_enabled.rb +85 -0
- data/lib/rubocop/cop/internal_affairs/example_description.rb +9 -5
- data/lib/rubocop/cop/internal_affairs/location_exists.rb +116 -0
- data/lib/rubocop/cop/internal_affairs/location_expression.rb +2 -1
- data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +1 -0
- data/lib/rubocop/cop/internal_affairs/node_first_or_last_argument.rb +3 -2
- data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +5 -5
- data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_processor.rb +63 -0
- data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_walker.rb +131 -0
- data/lib/rubocop/cop/internal_affairs/node_pattern_groups.rb +231 -0
- data/lib/rubocop/cop/internal_affairs/node_type_group.rb +92 -0
- data/lib/rubocop/cop/internal_affairs/node_type_multiple_predicates.rb +126 -0
- data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +4 -3
- data/lib/rubocop/cop/internal_affairs/on_send_without_on_csend.rb +90 -0
- data/lib/rubocop/cop/internal_affairs/operator_keyword.rb +4 -2
- data/lib/rubocop/cop/internal_affairs/plugin.rb +33 -0
- data/lib/rubocop/cop/internal_affairs/redundant_described_class_as_subject.rb +6 -5
- data/lib/rubocop/cop/internal_affairs/redundant_source_range.rb +3 -1
- data/lib/rubocop/cop/internal_affairs/single_line_comparison.rb +5 -4
- data/lib/rubocop/cop/internal_affairs/undefined_config.rb +13 -2
- data/lib/rubocop/cop/internal_affairs/useless_restrict_on_send.rb +1 -1
- data/lib/rubocop/cop/internal_affairs.rb +6 -16
- data/lib/rubocop/cop/layout/access_modifier_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/argument_alignment.rb +2 -8
- data/lib/rubocop/cop/layout/block_alignment.rb +3 -1
- data/lib/rubocop/cop/layout/block_end_newline.rb +1 -0
- data/lib/rubocop/cop/layout/class_structure.rb +44 -9
- data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +5 -5
- data/lib/rubocop/cop/layout/def_end_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/dot_position.rb +1 -1
- data/lib/rubocop/cop/layout/else_alignment.rb +2 -2
- data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +2 -2
- data/lib/rubocop/cop/layout/empty_line_between_defs.rb +7 -11
- data/lib/rubocop/cop/layout/empty_lines_after_module_inclusion.rb +101 -0
- data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +35 -4
- data/lib/rubocop/cop/layout/empty_lines_around_arguments.rb +8 -29
- data/lib/rubocop/cop/layout/empty_lines_around_begin_body.rb +5 -6
- data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +1 -0
- data/lib/rubocop/cop/layout/empty_lines_around_class_body.rb +1 -1
- data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +1 -1
- data/lib/rubocop/cop/layout/empty_lines_around_method_body.rb +22 -2
- data/lib/rubocop/cop/layout/end_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/extra_spacing.rb +1 -1
- data/lib/rubocop/cop/layout/first_argument_indentation.rb +4 -9
- data/lib/rubocop/cop/layout/first_array_element_indentation.rb +2 -7
- data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +2 -7
- data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +1 -1
- data/lib/rubocop/cop/layout/first_parameter_indentation.rb +2 -2
- data/lib/rubocop/cop/layout/hash_alignment.rb +8 -6
- data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +2 -1
- data/lib/rubocop/cop/layout/indentation_width.rb +1 -0
- data/lib/rubocop/cop/layout/leading_comment_space.rb +13 -1
- data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +11 -2
- data/lib/rubocop/cop/layout/line_continuation_spacing.rb +7 -1
- data/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb +2 -2
- data/lib/rubocop/cop/layout/line_length.rb +35 -9
- data/lib/rubocop/cop/layout/multiline_block_layout.rb +1 -0
- data/lib/rubocop/cop/layout/multiline_hash_key_line_breaks.rb +1 -1
- data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +25 -0
- data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +1 -0
- data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +4 -4
- data/lib/rubocop/cop/layout/multiline_method_parameter_line_breaks.rb +1 -0
- data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/redundant_line_break.rb +16 -11
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +3 -5
- data/lib/rubocop/cop/layout/single_line_block_chain.rb +1 -1
- data/lib/rubocop/cop/layout/space_after_colon.rb +2 -2
- data/lib/rubocop/cop/layout/space_after_comma.rb +1 -1
- data/lib/rubocop/cop/layout/space_after_method_name.rb +1 -1
- data/lib/rubocop/cop/layout/space_after_semicolon.rb +11 -1
- data/lib/rubocop/cop/layout/space_around_keyword.rb +7 -1
- data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +1 -1
- data/lib/rubocop/cop/layout/space_around_operators.rb +15 -4
- data/lib/rubocop/cop/layout/space_before_block_braces.rb +1 -0
- data/lib/rubocop/cop/layout/space_before_brackets.rb +5 -38
- 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 +12 -3
- data/lib/rubocop/cop/layout/space_inside_block_braces.rb +1 -0
- data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +3 -0
- data/lib/rubocop/cop/layout/trailing_whitespace.rb +5 -3
- data/lib/rubocop/cop/lint/ambiguous_block_association.rb +1 -1
- data/lib/rubocop/cop/lint/ambiguous_range.rb +5 -0
- data/lib/rubocop/cop/lint/array_literal_in_regexp.rb +118 -0
- data/lib/rubocop/cop/lint/assignment_in_condition.rb +1 -3
- data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +2 -3
- data/lib/rubocop/cop/lint/boolean_symbol.rb +1 -1
- data/lib/rubocop/cop/lint/circular_argument_reference.rb +4 -3
- data/lib/rubocop/cop/lint/constant_definition_in_block.rb +3 -3
- data/lib/rubocop/cop/lint/constant_reassignment.rb +148 -0
- data/lib/rubocop/cop/lint/cop_directive_syntax.rb +84 -0
- data/lib/rubocop/cop/lint/debugger.rb +3 -3
- data/lib/rubocop/cop/lint/deprecated_class_methods.rb +1 -1
- data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +2 -1
- data/lib/rubocop/cop/lint/duplicate_match_pattern.rb +1 -1
- data/lib/rubocop/cop/lint/duplicate_methods.rb +111 -23
- data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +1 -1
- data/lib/rubocop/cop/lint/duplicate_set_element.rb +20 -7
- data/lib/rubocop/cop/lint/empty_conditional_body.rb +14 -64
- data/lib/rubocop/cop/lint/empty_expression.rb +0 -2
- data/lib/rubocop/cop/lint/empty_interpolation.rb +3 -1
- data/lib/rubocop/cop/lint/erb_new_arguments.rb +0 -6
- data/lib/rubocop/cop/lint/float_comparison.rb +37 -12
- data/lib/rubocop/cop/lint/float_out_of_range.rb +1 -1
- data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +2 -2
- data/lib/rubocop/cop/lint/identity_comparison.rb +19 -15
- data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +1 -1
- data/lib/rubocop/cop/lint/literal_as_condition.rb +125 -10
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +24 -6
- data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +1 -1
- data/lib/rubocop/cop/lint/missing_super.rb +2 -2
- data/lib/rubocop/cop/lint/mixed_case_range.rb +3 -3
- data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +1 -1
- data/lib/rubocop/cop/lint/nested_method_definition.rb +9 -5
- data/lib/rubocop/cop/lint/next_without_accumulator.rb +1 -1
- data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +4 -2
- data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +3 -3
- data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +3 -3
- data/lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +19 -31
- data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +1 -1
- data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +2 -1
- data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +1 -5
- data/lib/rubocop/cop/lint/raise_exception.rb +29 -10
- data/lib/rubocop/cop/lint/redundant_regexp_quantifiers.rb +2 -2
- data/lib/rubocop/cop/lint/redundant_require_statement.rb +0 -21
- data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +101 -2
- data/lib/rubocop/cop/lint/redundant_string_coercion.rb +2 -2
- data/lib/rubocop/cop/lint/redundant_type_conversion.rb +261 -0
- data/lib/rubocop/cop/lint/redundant_with_index.rb +3 -0
- data/lib/rubocop/cop/lint/redundant_with_object.rb +3 -0
- data/lib/rubocop/cop/lint/refinement_import_methods.rb +1 -1
- data/lib/rubocop/cop/lint/require_range_parentheses.rb +1 -1
- data/lib/rubocop/cop/lint/rescue_exception.rb +1 -1
- data/lib/rubocop/cop/lint/rescue_type.rb +1 -1
- data/lib/rubocop/cop/lint/return_in_void_context.rb +9 -11
- data/lib/rubocop/cop/lint/safe_navigation_chain.rb +8 -1
- data/lib/rubocop/cop/lint/self_assignment.rb +25 -0
- data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +13 -1
- data/lib/rubocop/cop/lint/shared_mutable_default.rb +76 -0
- data/lib/rubocop/cop/lint/suppressed_exception.rb +1 -1
- data/lib/rubocop/cop/lint/suppressed_exception_in_number_conversion.rb +111 -0
- data/lib/rubocop/cop/lint/symbol_conversion.rb +1 -1
- data/lib/rubocop/cop/lint/syntax.rb +4 -1
- data/lib/rubocop/cop/lint/to_enum_arguments.rb +1 -1
- data/lib/rubocop/cop/lint/top_level_return_with_argument.rb +1 -1
- data/lib/rubocop/cop/lint/unescaped_bracket_in_regexp.rb +1 -1
- data/lib/rubocop/cop/lint/unexpected_block_arity.rb +3 -1
- data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +1 -1
- data/lib/rubocop/cop/lint/unreachable_code.rb +52 -2
- data/lib/rubocop/cop/lint/unreachable_loop.rb +6 -6
- data/lib/rubocop/cop/lint/useless_access_modifier.rb +34 -8
- data/lib/rubocop/cop/lint/useless_assignment.rb +3 -1
- data/lib/rubocop/cop/lint/useless_constant_scoping.rb +71 -0
- data/lib/rubocop/cop/lint/useless_default_value_argument.rb +90 -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 +3 -1
- data/lib/rubocop/cop/lint/useless_or.rb +98 -0
- data/lib/rubocop/cop/lint/useless_rescue.rb +1 -1
- data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +5 -5
- data/lib/rubocop/cop/lint/utils/nil_receiver_checker.rb +121 -0
- data/lib/rubocop/cop/lint/void.rb +14 -11
- data/lib/rubocop/cop/message_annotator.rb +7 -3
- data/lib/rubocop/cop/metrics/abc_size.rb +1 -1
- data/lib/rubocop/cop/metrics/block_length.rb +1 -0
- data/lib/rubocop/cop/metrics/block_nesting.rb +1 -1
- data/lib/rubocop/cop/metrics/class_length.rb +9 -9
- data/lib/rubocop/cop/metrics/collection_literal_length.rb +7 -0
- data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +1 -1
- data/lib/rubocop/cop/metrics/method_length.rb +9 -1
- data/lib/rubocop/cop/metrics/module_length.rb +1 -1
- data/lib/rubocop/cop/metrics/perceived_complexity.rb +1 -1
- data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +2 -2
- data/lib/rubocop/cop/metrics/utils/repeated_attribute_discount.rb +7 -7
- data/lib/rubocop/cop/mixin/alignment.rb +3 -3
- data/lib/rubocop/cop/mixin/allowed_pattern.rb +4 -4
- data/lib/rubocop/cop/mixin/check_line_breakable.rb +13 -13
- data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +2 -2
- data/lib/rubocop/cop/mixin/comments_help.rb +8 -3
- data/lib/rubocop/cop/mixin/def_node.rb +1 -1
- data/lib/rubocop/cop/mixin/dig_help.rb +1 -1
- data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +1 -1
- data/lib/rubocop/cop/mixin/forbidden_identifiers.rb +20 -0
- data/lib/rubocop/cop/mixin/forbidden_pattern.rb +16 -0
- data/lib/rubocop/cop/mixin/frozen_string_literal.rb +1 -2
- data/lib/rubocop/cop/mixin/gemspec_help.rb +22 -0
- data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +15 -14
- data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +22 -22
- data/lib/rubocop/cop/mixin/hash_subset.rb +203 -0
- data/lib/rubocop/cop/mixin/hash_transform_method.rb +74 -74
- data/lib/rubocop/cop/mixin/line_length_help.rb +27 -10
- data/lib/rubocop/cop/mixin/method_complexity.rb +2 -1
- data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +2 -0
- data/lib/rubocop/cop/mixin/ordered_gem_node.rb +1 -1
- data/lib/rubocop/cop/mixin/percent_literal.rb +1 -1
- data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +68 -30
- data/lib/rubocop/cop/mixin/range_help.rb +15 -3
- data/lib/rubocop/cop/mixin/space_before_punctuation.rb +1 -1
- data/lib/rubocop/cop/mixin/statement_modifier.rb +8 -3
- data/lib/rubocop/cop/mixin/string_help.rb +2 -2
- data/lib/rubocop/cop/mixin/string_literals_help.rb +1 -1
- data/lib/rubocop/cop/mixin/target_ruby_version.rb +1 -1
- data/lib/rubocop/cop/mixin/trailing_comma.rb +21 -5
- data/lib/rubocop/cop/naming/accessor_method_name.rb +6 -6
- data/lib/rubocop/cop/naming/block_forwarding.rb +19 -15
- data/lib/rubocop/cop/naming/file_name.rb +2 -2
- data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +1 -1
- data/lib/rubocop/cop/naming/method_name.rb +185 -15
- data/lib/rubocop/cop/naming/predicate_method.rb +306 -0
- data/lib/rubocop/cop/naming/{predicate_name.rb → predicate_prefix.rb} +48 -4
- data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +4 -4
- data/lib/rubocop/cop/naming/variable_name.rb +51 -6
- data/lib/rubocop/cop/registry.rb +9 -6
- data/lib/rubocop/cop/security/compound_hash.rb +2 -0
- data/lib/rubocop/cop/security/eval.rb +2 -1
- data/lib/rubocop/cop/security/open.rb +1 -0
- data/lib/rubocop/cop/security/yaml_load.rb +3 -2
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +66 -15
- data/lib/rubocop/cop/style/accessor_grouping.rb +32 -6
- data/lib/rubocop/cop/style/and_or.rb +1 -1
- data/lib/rubocop/cop/style/arguments_forwarding.rb +57 -44
- data/lib/rubocop/cop/style/array_first_last.rb +18 -2
- data/lib/rubocop/cop/style/array_intersect.rb +81 -40
- data/lib/rubocop/cop/style/block_delimiters.rb +27 -24
- data/lib/rubocop/cop/style/case_like_if.rb +1 -1
- data/lib/rubocop/cop/style/class_and_module_children.rb +52 -11
- data/lib/rubocop/cop/style/class_equality_comparison.rb +1 -1
- data/lib/rubocop/cop/style/collection_methods.rb +2 -1
- data/lib/rubocop/cop/style/collection_querying.rb +167 -0
- data/lib/rubocop/cop/style/combinable_defined.rb +1 -1
- data/lib/rubocop/cop/style/combinable_loops.rb +3 -2
- data/lib/rubocop/cop/style/command_literal.rb +1 -1
- data/lib/rubocop/cop/style/commented_keyword.rb +12 -5
- data/lib/rubocop/cop/style/comparable_between.rb +78 -0
- data/lib/rubocop/cop/style/concat_array_literals.rb +1 -1
- data/lib/rubocop/cop/style/conditional_assignment.rb +23 -7
- data/lib/rubocop/cop/style/data_inheritance.rb +7 -0
- data/lib/rubocop/cop/style/def_with_parentheses.rb +18 -5
- data/lib/rubocop/cop/style/dig_chain.rb +6 -7
- data/lib/rubocop/cop/style/documentation.rb +1 -1
- data/lib/rubocop/cop/style/double_negation.rb +4 -4
- data/lib/rubocop/cop/style/each_for_simple_loop.rb +4 -7
- data/lib/rubocop/cop/style/each_with_object.rb +2 -3
- data/lib/rubocop/cop/style/empty_else.rb +4 -2
- data/lib/rubocop/cop/style/empty_literal.rb +5 -1
- data/lib/rubocop/cop/style/empty_method.rb +1 -1
- data/lib/rubocop/cop/style/empty_string_inside_interpolation.rb +100 -0
- data/lib/rubocop/cop/style/endless_method.rb +163 -18
- data/lib/rubocop/cop/style/eval_with_location.rb +4 -4
- data/lib/rubocop/cop/style/exact_regexp_match.rb +2 -3
- data/lib/rubocop/cop/style/expand_path_arguments.rb +2 -7
- data/lib/rubocop/cop/style/explicit_block_argument.rb +16 -3
- data/lib/rubocop/cop/style/exponential_notation.rb +6 -5
- data/lib/rubocop/cop/style/fetch_env_var.rb +34 -7
- data/lib/rubocop/cop/style/file_null.rb +20 -4
- data/lib/rubocop/cop/style/float_division.rb +8 -4
- data/lib/rubocop/cop/style/for.rb +1 -0
- data/lib/rubocop/cop/style/format_string_token.rb +38 -11
- data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +3 -2
- data/lib/rubocop/cop/style/global_std_stream.rb +3 -0
- data/lib/rubocop/cop/style/guard_clause.rb +2 -1
- data/lib/rubocop/cop/style/hash_conversion.rb +16 -8
- data/lib/rubocop/cop/style/hash_each_methods.rb +6 -8
- data/lib/rubocop/cop/style/hash_except.rb +35 -147
- data/lib/rubocop/cop/style/hash_fetch_chain.rb +104 -0
- data/lib/rubocop/cop/style/hash_slice.rb +80 -0
- data/lib/rubocop/cop/style/hash_syntax.rb +9 -3
- data/lib/rubocop/cop/style/hash_transform_keys.rb +2 -2
- data/lib/rubocop/cop/style/hash_transform_values.rb +2 -2
- data/lib/rubocop/cop/style/identical_conditional_branches.rb +25 -6
- data/lib/rubocop/cop/style/if_inside_else.rb +10 -13
- data/lib/rubocop/cop/style/if_unless_modifier.rb +36 -9
- data/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +4 -7
- data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +2 -2
- data/lib/rubocop/cop/style/if_with_semicolon.rb +7 -5
- data/lib/rubocop/cop/style/infinite_loop.rb +1 -1
- data/lib/rubocop/cop/style/inverse_methods.rb +16 -12
- data/lib/rubocop/cop/style/invertible_unless_condition.rb +2 -2
- data/lib/rubocop/cop/style/ip_addresses.rb +2 -2
- data/lib/rubocop/cop/style/it_assignment.rb +93 -0
- data/lib/rubocop/cop/style/it_block_parameter.rb +121 -0
- data/lib/rubocop/cop/style/keyword_parameters_order.rb +14 -8
- data/lib/rubocop/cop/style/lambda.rb +1 -0
- data/lib/rubocop/cop/style/lambda_call.rb +10 -3
- data/lib/rubocop/cop/style/line_end_concatenation.rb +10 -4
- data/lib/rubocop/cop/style/map_into_array.rb +5 -2
- data/lib/rubocop/cop/style/map_to_hash.rb +13 -4
- data/lib/rubocop/cop/style/map_to_set.rb +4 -5
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +27 -19
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +18 -0
- data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +3 -2
- data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +3 -4
- data/lib/rubocop/cop/style/method_def_parentheses.rb +1 -1
- data/lib/rubocop/cop/style/min_max_comparison.rb +13 -5
- data/lib/rubocop/cop/style/missing_else.rb +2 -0
- data/lib/rubocop/cop/style/multiline_block_chain.rb +3 -2
- data/lib/rubocop/cop/style/multiline_if_modifier.rb +2 -0
- data/lib/rubocop/cop/style/multiline_method_signature.rb +1 -9
- data/lib/rubocop/cop/style/multiple_comparison.rb +34 -22
- data/lib/rubocop/cop/style/mutable_constant.rb +3 -3
- data/lib/rubocop/cop/style/negated_if_else_condition.rb +1 -1
- data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +1 -1
- data/lib/rubocop/cop/style/next.rb +44 -0
- data/lib/rubocop/cop/style/object_then.rb +15 -15
- data/lib/rubocop/cop/style/open_struct_use.rb +5 -5
- data/lib/rubocop/cop/style/parallel_assignment.rb +33 -25
- data/lib/rubocop/cop/style/parentheses_around_condition.rb +2 -2
- data/lib/rubocop/cop/style/percent_literal_delimiters.rb +1 -1
- data/lib/rubocop/cop/style/percent_q_literals.rb +1 -1
- data/lib/rubocop/cop/style/proc.rb +2 -2
- data/lib/rubocop/cop/style/quoted_symbols.rb +1 -1
- data/lib/rubocop/cop/style/raise_args.rb +14 -12
- data/lib/rubocop/cop/style/random_with_offset.rb +3 -3
- data/lib/rubocop/cop/style/redundant_argument.rb +3 -1
- data/lib/rubocop/cop/style/redundant_array_flatten.rb +50 -0
- data/lib/rubocop/cop/style/redundant_begin.rb +2 -1
- data/lib/rubocop/cop/style/redundant_condition.rb +59 -2
- data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +16 -5
- data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +6 -10
- data/lib/rubocop/cop/style/redundant_each.rb +1 -1
- data/lib/rubocop/cop/style/redundant_exception.rb +2 -2
- data/lib/rubocop/cop/style/redundant_fetch_block.rb +1 -9
- data/lib/rubocop/cop/style/redundant_format.rb +262 -0
- data/lib/rubocop/cop/style/redundant_freeze.rb +4 -4
- data/lib/rubocop/cop/style/redundant_initialize.rb +12 -3
- data/lib/rubocop/cop/style/redundant_interpolation.rb +1 -1
- data/lib/rubocop/cop/style/redundant_line_continuation.rb +39 -22
- data/lib/rubocop/cop/style/redundant_parentheses.rb +85 -17
- data/lib/rubocop/cop/style/redundant_regexp_argument.rb +3 -0
- data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +1 -1
- data/lib/rubocop/cop/style/redundant_regexp_escape.rb +1 -1
- data/lib/rubocop/cop/style/redundant_self.rb +10 -6
- data/lib/rubocop/cop/style/redundant_self_assignment.rb +14 -28
- data/lib/rubocop/cop/style/redundant_sort.rb +2 -2
- data/lib/rubocop/cop/style/redundant_sort_by.rb +17 -1
- data/lib/rubocop/cop/style/redundant_string_escape.rb +2 -2
- data/lib/rubocop/cop/style/regexp_literal.rb +1 -1
- data/lib/rubocop/cop/style/rescue_modifier.rb +3 -0
- data/lib/rubocop/cop/style/return_nil.rb +2 -2
- data/lib/rubocop/cop/style/safe_navigation.rb +46 -16
- data/lib/rubocop/cop/style/select_by_regexp.rb +4 -1
- data/lib/rubocop/cop/style/semicolon.rb +1 -1
- data/lib/rubocop/cop/style/send_with_literal_method_name.rb +2 -1
- data/lib/rubocop/cop/style/single_line_block_params.rb +1 -1
- data/lib/rubocop/cop/style/single_line_do_end_block.rb +4 -3
- data/lib/rubocop/cop/style/single_line_methods.rb +13 -11
- data/lib/rubocop/cop/style/slicing_with_range.rb +40 -11
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +68 -101
- data/lib/rubocop/cop/style/stabby_lambda_parentheses.rb +1 -1
- data/lib/rubocop/cop/style/string_concatenation.rb +15 -14
- data/lib/rubocop/cop/style/string_literals.rb +1 -1
- data/lib/rubocop/cop/style/string_methods.rb +1 -1
- data/lib/rubocop/cop/style/struct_inheritance.rb +8 -1
- data/lib/rubocop/cop/style/super_arguments.rb +66 -19
- data/lib/rubocop/cop/style/symbol_proc.rb +3 -1
- data/lib/rubocop/cop/style/ternary_parentheses.rb +1 -1
- data/lib/rubocop/cop/style/top_level_method_definition.rb +2 -1
- data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +11 -2
- data/lib/rubocop/cop/style/trailing_comma_in_array_literal.rb +47 -6
- data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +1 -1
- data/lib/rubocop/cop/style/trailing_comma_in_hash_literal.rb +48 -6
- data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
- data/lib/rubocop/cop/style/while_until_modifier.rb +0 -1
- data/lib/rubocop/cop/style/yoda_condition.rb +8 -4
- data/lib/rubocop/cop/style/yoda_expression.rb +2 -1
- data/lib/rubocop/cop/team.rb +1 -1
- data/lib/rubocop/cop/util.rb +12 -5
- data/lib/rubocop/cop/utils/format_string.rb +10 -5
- data/lib/rubocop/cop/variable_force/assignment.rb +7 -3
- data/lib/rubocop/cop/variable_force/scope.rb +1 -1
- data/lib/rubocop/cop/variable_force/variable.rb +10 -3
- data/lib/rubocop/cop/variable_force/variable_table.rb +3 -3
- data/lib/rubocop/cop/variable_force.rb +23 -8
- data/lib/rubocop/cops_documentation_generator.rb +32 -16
- data/lib/rubocop/directive_comment.rb +45 -11
- data/lib/rubocop/ext/regexp_node.rb +0 -1
- data/lib/rubocop/formatter/disabled_config_formatter.rb +2 -1
- data/lib/rubocop/formatter/formatter_set.rb +1 -1
- data/lib/rubocop/formatter/fuubar_style_formatter.rb +1 -1
- data/lib/rubocop/formatter/html_formatter.rb +1 -1
- data/lib/rubocop/formatter/markdown_formatter.rb +1 -0
- data/lib/rubocop/formatter/offense_count_formatter.rb +1 -1
- data/lib/rubocop/formatter/pacman_formatter.rb +2 -1
- data/lib/rubocop/lsp/diagnostic.rb +189 -0
- data/lib/rubocop/lsp/logger.rb +2 -2
- data/lib/rubocop/lsp/routes.rb +10 -26
- data/lib/rubocop/lsp/runtime.rb +18 -50
- data/lib/rubocop/lsp/server.rb +0 -2
- data/lib/rubocop/lsp/stdin_runner.rb +85 -0
- data/lib/rubocop/magic_comment.rb +11 -3
- data/lib/rubocop/options.rb +28 -12
- data/lib/rubocop/path_util.rb +15 -8
- data/lib/rubocop/pending_cops_reporter.rb +56 -0
- data/lib/rubocop/plugin/configuration_integrator.rb +143 -0
- data/lib/rubocop/plugin/load_error.rb +26 -0
- data/lib/rubocop/plugin/loader.rb +100 -0
- data/lib/rubocop/plugin/not_supported_error.rb +29 -0
- data/lib/rubocop/plugin.rb +46 -0
- data/lib/rubocop/rake_task.rb +4 -1
- data/lib/rubocop/result_cache.rb +26 -24
- data/lib/rubocop/rspec/cop_helper.rb +13 -1
- data/lib/rubocop/rspec/expect_offense.rb +15 -5
- data/lib/rubocop/rspec/shared_contexts.rb +38 -1
- data/lib/rubocop/rspec/support.rb +4 -2
- data/lib/rubocop/runner.rb +10 -7
- data/lib/rubocop/server/cache.rb +51 -13
- data/lib/rubocop/server/cli.rb +2 -2
- data/lib/rubocop/server/client_command/base.rb +10 -0
- data/lib/rubocop/server/client_command/exec.rb +2 -1
- data/lib/rubocop/server/client_command/start.rb +11 -1
- data/lib/rubocop/target_finder.rb +7 -2
- data/lib/rubocop/target_ruby.rb +16 -1
- data/lib/rubocop/version.rb +30 -8
- data/lib/rubocop.rb +27 -2
- data/lib/ruby_lsp/rubocop/addon.rb +75 -0
- data/lib/ruby_lsp/rubocop/runtime_adapter.rb +65 -0
- metadata +72 -19
- data/lib/rubocop/cop/utils/regexp_ranges.rb +0 -113
- data/lib/rubocop/rspec/host_environment_simulation_helper.rb +0 -28
@@ -8,7 +8,7 @@ module RuboCop
|
|
8
8
|
# Offenses are registered for regexp character classes like `/[A-z]/`
|
9
9
|
# as well as range objects like `('A'..'z')`.
|
10
10
|
#
|
11
|
-
# NOTE: Range objects cannot be autocorrected.
|
11
|
+
# NOTE: `Range` objects cannot be autocorrected.
|
12
12
|
#
|
13
13
|
# @safety
|
14
14
|
# The cop autocorrects regexp character classes
|
@@ -79,7 +79,7 @@ module RuboCop
|
|
79
79
|
end
|
80
80
|
|
81
81
|
def range_pairs(expr)
|
82
|
-
|
82
|
+
expr.expressions.filter_map { |e| [e.expressions[0], e.expressions[1]] if e.type == :set }
|
83
83
|
end
|
84
84
|
|
85
85
|
def unsafe_range?(range_start, range_end)
|
@@ -94,7 +94,7 @@ module RuboCop
|
|
94
94
|
|
95
95
|
def skip_range?(range_start, range_end)
|
96
96
|
[range_start, range_end].any? do |bound|
|
97
|
-
bound
|
97
|
+
bound&.type != :literal
|
98
98
|
end
|
99
99
|
end
|
100
100
|
|
@@ -3,7 +3,7 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module Lint
|
6
|
-
# Do not mix named captures and numbered captures in a Regexp literal
|
6
|
+
# Do not mix named captures and numbered captures in a `Regexp` literal
|
7
7
|
# because numbered capture is ignored if they're mixed.
|
8
8
|
# Replace numbered captures with non-capturing groupings or
|
9
9
|
# named captures.
|
@@ -96,13 +96,13 @@ module RuboCop
|
|
96
96
|
|
97
97
|
def on_def(node)
|
98
98
|
subject, = *node # rubocop:disable InternalAffairs/NodeDestructuring
|
99
|
-
return if node.defs_type? && subject
|
99
|
+
return if node.defs_type? && allowed_subject_type?(subject)
|
100
100
|
|
101
|
-
def_ancestor = node.each_ancestor(:
|
101
|
+
def_ancestor = node.each_ancestor(:any_def).first
|
102
102
|
return unless def_ancestor
|
103
103
|
|
104
104
|
within_scoping_def =
|
105
|
-
node.each_ancestor(:
|
105
|
+
node.each_ancestor(:any_block, :sclass).any? do |ancestor|
|
106
106
|
scoping_method_call?(ancestor)
|
107
107
|
end
|
108
108
|
|
@@ -117,6 +117,10 @@ module RuboCop
|
|
117
117
|
child.class_constructor? || allowed_method_name?(child)
|
118
118
|
end
|
119
119
|
|
120
|
+
def allowed_subject_type?(subject)
|
121
|
+
subject.variable? || subject.const_type? || subject.call_type?
|
122
|
+
end
|
123
|
+
|
120
124
|
def allowed_method_name?(node)
|
121
125
|
name = node.method_name
|
122
126
|
|
@@ -125,12 +129,12 @@ module RuboCop
|
|
125
129
|
|
126
130
|
# @!method eval_call?(node)
|
127
131
|
def_node_matcher :eval_call?, <<~PATTERN
|
128
|
-
(
|
132
|
+
(any_block (send _ {:instance_eval :class_eval :module_eval} ...) ...)
|
129
133
|
PATTERN
|
130
134
|
|
131
135
|
# @!method exec_call?(node)
|
132
136
|
def_node_matcher :exec_call?, <<~PATTERN
|
133
|
-
(
|
137
|
+
(any_block (send _ {:instance_exec :class_exec :module_exec} ...) ...)
|
134
138
|
PATTERN
|
135
139
|
end
|
136
140
|
end
|
@@ -59,12 +59,12 @@ module RuboCop
|
|
59
59
|
|
60
60
|
# @!method send_exist_node(node)
|
61
61
|
def_node_search :send_exist_node, <<~PATTERN
|
62
|
-
$(send (const nil? {:FileTest :File :Dir :Shell}) {:exist? :exists?} ...)
|
62
|
+
$(send (const {cbase nil?} {:FileTest :File :Dir :Shell}) {:exist? :exists?} ...)
|
63
63
|
PATTERN
|
64
64
|
|
65
65
|
# @!method receiver_and_method_name(node)
|
66
66
|
def_node_matcher :receiver_and_method_name, <<~PATTERN
|
67
|
-
(send (const nil? $_) $_ ...)
|
67
|
+
(send (const {cbase nil?} $_) $_ ...)
|
68
68
|
PATTERN
|
69
69
|
|
70
70
|
# @!method force?(node)
|
@@ -78,6 +78,7 @@ module RuboCop
|
|
78
78
|
PATTERN
|
79
79
|
|
80
80
|
def on_send(node)
|
81
|
+
return unless node.receiver&.const_type?
|
81
82
|
return unless if_node_child?(node)
|
82
83
|
return if explicit_not_force?(node)
|
83
84
|
return unless (exist_node = send_exist_node(node.parent).first)
|
@@ -115,6 +116,7 @@ module RuboCop
|
|
115
116
|
|
116
117
|
def message_remove_file_exist_check(node)
|
117
118
|
receiver, method_name = receiver_and_method_name(node)
|
119
|
+
|
118
120
|
format(MSG_REMOVE_FILE_EXIST_CHECK, receiver: receiver, method_name: method_name)
|
119
121
|
end
|
120
122
|
|
@@ -59,11 +59,13 @@ module RuboCop
|
|
59
59
|
#
|
60
60
|
class NonDeterministicRequireOrder < Base
|
61
61
|
extend AutoCorrector
|
62
|
+
extend TargetRubyVersion
|
62
63
|
|
63
64
|
MSG = 'Sort files before requiring them.'
|
64
65
|
|
66
|
+
maximum_target_ruby_version 2.7
|
67
|
+
|
65
68
|
def on_block(node)
|
66
|
-
return if target_ruby_version >= 3.0
|
67
69
|
return unless node.body
|
68
70
|
return unless unsorted_dir_loop?(node.send_node)
|
69
71
|
|
@@ -75,7 +77,6 @@ module RuboCop
|
|
75
77
|
end
|
76
78
|
|
77
79
|
def on_numblock(node)
|
78
|
-
return if target_ruby_version >= 3.0
|
79
80
|
return unless node.body
|
80
81
|
return unless unsorted_dir_loop?(node.send_node)
|
81
82
|
|
@@ -87,7 +88,6 @@ module RuboCop
|
|
87
88
|
end
|
88
89
|
|
89
90
|
def on_block_pass(node)
|
90
|
-
return if target_ruby_version >= 3.0
|
91
91
|
return unless method_require?(node)
|
92
92
|
return unless unsorted_dir_pass?(node.parent)
|
93
93
|
|
@@ -46,7 +46,7 @@ module RuboCop
|
|
46
46
|
def on_return(return_node)
|
47
47
|
return if return_value?(return_node)
|
48
48
|
|
49
|
-
return_node.each_ancestor(:
|
49
|
+
return_node.each_ancestor(:any_block, :any_def) do |node|
|
50
50
|
break if scoped_node?(node)
|
51
51
|
|
52
52
|
# if a proc is passed to `Module#define_method` or
|
@@ -54,7 +54,7 @@ module RuboCop
|
|
54
54
|
# non-local exit error
|
55
55
|
break if define_method?(node.send_node)
|
56
56
|
|
57
|
-
next
|
57
|
+
next if node.argument_list.empty?
|
58
58
|
|
59
59
|
if chained_send?(node.send_node)
|
60
60
|
add_offense(return_node.loc.keyword)
|
@@ -66,7 +66,7 @@ module RuboCop
|
|
66
66
|
private
|
67
67
|
|
68
68
|
def scoped_node?(node)
|
69
|
-
node.
|
69
|
+
node.any_def_type? || node.lambda?
|
70
70
|
end
|
71
71
|
|
72
72
|
def return_value?(return_node)
|
@@ -4,30 +4,27 @@ module RuboCop
|
|
4
4
|
module Cop
|
5
5
|
module Lint
|
6
6
|
# Certain numeric operations have a constant result, usually 0 or 1.
|
7
|
-
#
|
8
|
-
# Additionally, a variable modulo 0 or itself will always return 0.
|
7
|
+
# Multiplying a number by 0 will always return 0.
|
9
8
|
# Dividing a number by itself or raising it to the power of 0 will always return 1.
|
10
9
|
# As such, they can be replaced with that result.
|
11
10
|
# These are probably leftover from debugging, or are mistakes.
|
12
11
|
# Other numeric operations that are similarly leftover from debugging or mistakes
|
13
|
-
# are handled by Lint/UselessNumericOperation
|
12
|
+
# are handled by `Lint/UselessNumericOperation`.
|
13
|
+
#
|
14
|
+
# NOTE: This cop doesn't detect offenses for the `-` and `%` operator because it
|
15
|
+
# can't determine the type of `x`. If `x` is an `Array` or `String`, it doesn't perform
|
16
|
+
# a numeric operation.
|
14
17
|
#
|
15
18
|
# @example
|
16
19
|
#
|
17
20
|
# # bad
|
18
|
-
# x - x
|
19
21
|
# x * 0
|
20
|
-
# x % 1
|
21
|
-
# x % x
|
22
22
|
#
|
23
23
|
# # good
|
24
24
|
# 0
|
25
25
|
#
|
26
26
|
# # bad
|
27
|
-
# x -= x
|
28
27
|
# x *= 0
|
29
|
-
# x %= 1
|
30
|
-
# x %= x
|
31
28
|
#
|
32
29
|
# # good
|
33
30
|
# x = 0
|
@@ -48,58 +45,49 @@ module RuboCop
|
|
48
45
|
#
|
49
46
|
class NumericOperationWithConstantResult < Base
|
50
47
|
extend AutoCorrector
|
48
|
+
|
51
49
|
MSG = 'Numeric operation with a constant result detected.'
|
52
|
-
RESTRICT_ON_SEND = %i[
|
50
|
+
RESTRICT_ON_SEND = %i[* / **].freeze
|
53
51
|
|
54
52
|
# @!method operation_with_constant_result?(node)
|
55
53
|
def_node_matcher :operation_with_constant_result?,
|
56
|
-
'(
|
54
|
+
'(call (call nil? $_lhs) $_operation ({int | call nil?} $_rhs))'
|
57
55
|
|
58
56
|
# @!method abbreviated_assignment_with_constant_result?(node)
|
59
57
|
def_node_matcher :abbreviated_assignment_with_constant_result?,
|
60
|
-
'(op-asgn (lvasgn $
|
58
|
+
'(op-asgn (lvasgn $_lhs) $_operation ({int lvar} $_rhs))'
|
61
59
|
|
62
60
|
def on_send(node)
|
63
|
-
return unless operation_with_constant_result?(node)
|
64
|
-
|
65
|
-
variable, operation, number = operation_with_constant_result?(node)
|
66
|
-
result = constant_result?(variable, operation, number)
|
67
|
-
return unless result
|
61
|
+
return unless (lhs, operation, rhs = operation_with_constant_result?(node))
|
62
|
+
return unless (result = constant_result?(lhs, operation, rhs))
|
68
63
|
|
69
64
|
add_offense(node) do |corrector|
|
70
65
|
corrector.replace(node, result.to_s)
|
71
66
|
end
|
72
67
|
end
|
68
|
+
alias on_csend on_send
|
73
69
|
|
74
70
|
def on_op_asgn(node)
|
75
|
-
return unless abbreviated_assignment_with_constant_result?(node)
|
76
|
-
|
77
|
-
variable, operation, number = abbreviated_assignment_with_constant_result?(node)
|
78
|
-
result = constant_result?(variable, operation, number)
|
79
|
-
return unless result
|
71
|
+
return unless (lhs, operation, rhs = abbreviated_assignment_with_constant_result?(node))
|
72
|
+
return unless (result = constant_result?(lhs, operation, rhs))
|
80
73
|
|
81
74
|
add_offense(node) do |corrector|
|
82
|
-
corrector.replace(node, "#{
|
75
|
+
corrector.replace(node, "#{lhs} = #{result}")
|
83
76
|
end
|
84
77
|
end
|
85
78
|
|
86
79
|
private
|
87
80
|
|
88
|
-
|
89
|
-
|
90
|
-
if number.to_s == '0'
|
81
|
+
def constant_result?(lhs, operation, rhs)
|
82
|
+
if rhs.to_s == '0'
|
91
83
|
return 0 if operation == :*
|
92
84
|
return 1 if operation == :**
|
93
|
-
elsif
|
94
|
-
return 0 if operation == :%
|
95
|
-
elsif number == variable
|
96
|
-
return 0 if %i[- %].include?(operation)
|
85
|
+
elsif rhs == lhs
|
97
86
|
return 1 if operation == :/
|
98
87
|
end
|
99
88
|
# If we weren't able to find any matches, return false so we can bail out.
|
100
89
|
false
|
101
90
|
end
|
102
|
-
# rubocop :enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
103
91
|
end
|
104
92
|
end
|
105
93
|
end
|
@@ -3,7 +3,7 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module Lint
|
6
|
-
# Looks for references of Regexp captures that are out of range
|
6
|
+
# Looks for references of `Regexp` captures that are out of range
|
7
7
|
# and thus always returns nil.
|
8
8
|
#
|
9
9
|
# @safety
|
@@ -61,6 +61,7 @@ module RuboCop
|
|
61
61
|
check_regexp(node.receiver)
|
62
62
|
end
|
63
63
|
end
|
64
|
+
alias after_csend after_send
|
64
65
|
|
65
66
|
def on_when(node)
|
66
67
|
regexp_conditions = node.conditions.select(&:regexp_type?)
|
@@ -38,16 +38,12 @@ module RuboCop
|
|
38
38
|
|
39
39
|
def valid_context?(node)
|
40
40
|
return true unless node.arguments.one? && node.first_argument.parenthesized_call?
|
41
|
-
return true if
|
41
|
+
return true if node.first_argument.any_block_type?
|
42
42
|
|
43
43
|
node.operator_method? || node.setter_method? || chained_calls?(node) ||
|
44
44
|
valid_first_argument?(node.first_argument)
|
45
45
|
end
|
46
46
|
|
47
|
-
def first_argument_block_type?(first_arg)
|
48
|
-
first_arg.block_type? || first_arg.numblock_type?
|
49
|
-
end
|
50
|
-
|
51
47
|
def valid_first_argument?(first_arg)
|
52
48
|
first_arg.operator_keyword? || first_arg.hash_type? || ternary_expression?(first_arg) ||
|
53
49
|
compound_range?(first_arg)
|
@@ -3,15 +3,18 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module Lint
|
6
|
-
# Checks for `raise` or `fail` statements which
|
7
|
-
#
|
6
|
+
# Checks for `raise` or `fail` statements which raise `Exception` or
|
7
|
+
# `Exception.new`. Use `StandardError` or a specific exception class instead.
|
8
8
|
#
|
9
|
-
#
|
10
|
-
#
|
11
|
-
#
|
12
|
-
#
|
13
|
-
#
|
14
|
-
#
|
9
|
+
# If you have defined your own namespaced `Exception` class, it is possible
|
10
|
+
# to configure the cop to allow it by setting `AllowedImplicitNamespaces` to
|
11
|
+
# an array with the names of the namespaces to allow. By default, this is set to
|
12
|
+
# `['Gem']`, which allows `Gem::Exception` to be raised without an explicit namespace.
|
13
|
+
# If not allowed, a false positive may be registered if `raise Exception` is called
|
14
|
+
# within the namespace.
|
15
|
+
#
|
16
|
+
# Alternatively, use a fully qualified name with `raise`/`fail`
|
17
|
+
# (eg. `raise Namespace::Exception`).
|
15
18
|
#
|
16
19
|
# @safety
|
17
20
|
# This cop is unsafe because it will change the exception class being
|
@@ -20,15 +23,31 @@ module RuboCop
|
|
20
23
|
# @example
|
21
24
|
# # bad
|
22
25
|
# raise Exception, 'Error message here'
|
26
|
+
# raise Exception.new('Error message here')
|
23
27
|
#
|
24
28
|
# # good
|
25
29
|
# raise StandardError, 'Error message here'
|
30
|
+
# raise MyError.new, 'Error message here'
|
31
|
+
#
|
32
|
+
# @example AllowedImplicitNamespaces: ['Gem'] (default)
|
33
|
+
# # bad - `Foo` is not an allowed implicit namespace
|
34
|
+
# module Foo
|
35
|
+
# def self.foo
|
36
|
+
# raise Exception # This is qualified to `Foo::Exception`.
|
37
|
+
# end
|
38
|
+
# end
|
26
39
|
#
|
27
|
-
# @example AllowedImplicitNamespaces: ['Gem']
|
28
40
|
# # good
|
29
41
|
# module Gem
|
30
42
|
# def self.foo
|
31
|
-
# raise Exception # This
|
43
|
+
# raise Exception # This is qualified to `Gem::Exception`.
|
44
|
+
# end
|
45
|
+
# end
|
46
|
+
#
|
47
|
+
# # good
|
48
|
+
# module Foo
|
49
|
+
# def self.foo
|
50
|
+
# raise Foo::Exception
|
32
51
|
# end
|
33
52
|
# end
|
34
53
|
class RaiseException < Base
|
@@ -3,7 +3,7 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module Lint
|
6
|
-
# Checks for redundant quantifiers inside Regexp literals.
|
6
|
+
# Checks for redundant quantifiers inside `Regexp` literals.
|
7
7
|
#
|
8
8
|
# It is always allowed when interpolation is used in a regexp literal,
|
9
9
|
# because it's unknown what kind of string will be expanded as a result:
|
@@ -73,7 +73,7 @@ module RuboCop
|
|
73
73
|
end
|
74
74
|
|
75
75
|
def redundant_group?(expr)
|
76
|
-
expr.is?(:passive, :group) && expr.
|
76
|
+
expr.is?(:passive, :group) && expr.one? { |child| child.type != :free_space }
|
77
77
|
end
|
78
78
|
|
79
79
|
def redundantly_quantifiable?(node)
|
@@ -17,17 +17,12 @@ module RuboCop
|
|
17
17
|
# * 2.0+ ... `enumerator`
|
18
18
|
# * 2.1+ ... `thread`
|
19
19
|
# * 2.2+ ... Add `rational` and `complex` above
|
20
|
-
# * 2.5+ ... Add `pp` above
|
21
20
|
# * 2.7+ ... Add `ruby2_keywords` above
|
22
21
|
# * 3.1+ ... Add `fiber` above
|
23
22
|
# * 3.2+ ... `set`
|
24
23
|
#
|
25
24
|
# This cop target those features.
|
26
25
|
#
|
27
|
-
# @safety
|
28
|
-
# This cop's autocorrection is unsafe because if `require 'pp'` is removed from one file,
|
29
|
-
# `NameError` can be encountered when another file uses `PP.pp`.
|
30
|
-
#
|
31
26
|
# @example
|
32
27
|
# # bad
|
33
28
|
# require 'unloaded_feature'
|
@@ -42,10 +37,6 @@ module RuboCop
|
|
42
37
|
MSG = 'Remove unnecessary `require` statement.'
|
43
38
|
RESTRICT_ON_SEND = %i[require].freeze
|
44
39
|
RUBY_22_LOADED_FEATURES = %w[rational complex].freeze
|
45
|
-
PRETTY_PRINT_METHODS = %i[
|
46
|
-
pretty_inspect pretty_print pretty_print_cycle
|
47
|
-
pretty_print_inspect pretty_print_instance_variables
|
48
|
-
].freeze
|
49
40
|
|
50
41
|
# @!method redundant_require_statement?(node)
|
51
42
|
def_node_matcher :redundant_require_statement?, <<~PATTERN
|
@@ -53,11 +44,6 @@ module RuboCop
|
|
53
44
|
(str #redundant_feature?))
|
54
45
|
PATTERN
|
55
46
|
|
56
|
-
# @!method pp_const?(node)
|
57
|
-
def_node_matcher :pp_const?, <<~PATTERN
|
58
|
-
(const {nil? cbase} :PP)
|
59
|
-
PATTERN
|
60
|
-
|
61
47
|
def on_send(node)
|
62
48
|
return unless redundant_require_statement?(node)
|
63
49
|
|
@@ -81,18 +67,11 @@ module RuboCop
|
|
81
67
|
feature_name == 'enumerator' ||
|
82
68
|
(target_ruby_version >= 2.1 && feature_name == 'thread') ||
|
83
69
|
(target_ruby_version >= 2.2 && RUBY_22_LOADED_FEATURES.include?(feature_name)) ||
|
84
|
-
(target_ruby_version >= 2.5 && feature_name == 'pp' && !need_to_require_pp?) ||
|
85
70
|
(target_ruby_version >= 2.7 && feature_name == 'ruby2_keywords') ||
|
86
71
|
(target_ruby_version >= 3.1 && feature_name == 'fiber') ||
|
87
72
|
(target_ruby_version >= 3.2 && feature_name == 'set')
|
88
73
|
end
|
89
74
|
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
90
|
-
|
91
|
-
def need_to_require_pp?
|
92
|
-
processed_source.ast.each_descendant(:send).any? do |node|
|
93
|
-
pp_const?(node.receiver) || PRETTY_PRINT_METHODS.include?(node.method_name)
|
94
|
-
end
|
95
|
-
end
|
96
75
|
end
|
97
76
|
end
|
98
77
|
end
|
@@ -20,6 +20,15 @@ module RuboCop
|
|
20
20
|
# In the example below, the safe navigation operator (`&.`) is unnecessary
|
21
21
|
# because `NilClass` has methods like `respond_to?` and `is_a?`.
|
22
22
|
#
|
23
|
+
# The `InferNonNilReceiver` option specifies whether to look into previous code
|
24
|
+
# paths to infer if the receiver can't be nil. This check is unsafe because the receiver
|
25
|
+
# can be redefined between the safe navigation call and previous regular method call.
|
26
|
+
# It does the inference only in the current scope, e.g. within the same method definition etc.
|
27
|
+
#
|
28
|
+
# The `AdditionalNilMethods` option specifies additional custom methods which are
|
29
|
+
# defined on `NilClass`. When `InferNonNilReceiver` is set, they are used to determine
|
30
|
+
# whether the receiver can be nil.
|
31
|
+
#
|
23
32
|
# @safety
|
24
33
|
# This cop is unsafe, because autocorrection can change the return type of
|
25
34
|
# the expression. An offending expression that previously could return `nil`
|
@@ -33,6 +42,20 @@ module RuboCop
|
|
33
42
|
# CamelCaseConst.do_something
|
34
43
|
#
|
35
44
|
# # bad
|
45
|
+
# foo.to_s&.strip
|
46
|
+
# foo.to_i&.zero?
|
47
|
+
# foo.to_f&.zero?
|
48
|
+
# foo.to_a&.size
|
49
|
+
# foo.to_h&.size
|
50
|
+
#
|
51
|
+
# # good
|
52
|
+
# foo.to_s.strip
|
53
|
+
# foo.to_i.zero?
|
54
|
+
# foo.to_f.zero?
|
55
|
+
# foo.to_a.size
|
56
|
+
# foo.to_h.size
|
57
|
+
#
|
58
|
+
# # bad
|
36
59
|
# do_something if attrs&.respond_to?(:[])
|
37
60
|
#
|
38
61
|
# # good
|
@@ -81,17 +104,59 @@ module RuboCop
|
|
81
104
|
# do_something if attrs.nil_safe_method(:[])
|
82
105
|
# do_something if attrs&.not_nil_safe_method(:[])
|
83
106
|
#
|
107
|
+
# @example InferNonNilReceiver: false (default)
|
108
|
+
# # good
|
109
|
+
# foo.bar
|
110
|
+
# foo&.baz
|
111
|
+
#
|
112
|
+
# @example InferNonNilReceiver: true
|
113
|
+
# # bad
|
114
|
+
# foo.bar
|
115
|
+
# foo&.baz # would raise on previous line if `foo` is nil
|
116
|
+
#
|
117
|
+
# # good
|
118
|
+
# foo.bar
|
119
|
+
# foo.baz
|
120
|
+
#
|
121
|
+
# # bad
|
122
|
+
# if foo.condition?
|
123
|
+
# foo&.bar
|
124
|
+
# end
|
125
|
+
#
|
126
|
+
# # good
|
127
|
+
# if foo.condition?
|
128
|
+
# foo.bar
|
129
|
+
# end
|
130
|
+
#
|
131
|
+
# # good (different scopes)
|
132
|
+
# def method1
|
133
|
+
# foo.bar
|
134
|
+
# end
|
135
|
+
#
|
136
|
+
# def method2
|
137
|
+
# foo&.bar
|
138
|
+
# end
|
139
|
+
#
|
140
|
+
# @example AdditionalNilMethods: [present?]
|
141
|
+
# # good
|
142
|
+
# foo.present?
|
143
|
+
# foo&.bar
|
144
|
+
#
|
84
145
|
class RedundantSafeNavigation < Base
|
85
146
|
include AllowedMethods
|
86
147
|
extend AutoCorrector
|
87
148
|
|
88
149
|
MSG = 'Redundant safe navigation detected, use `.` instead.'
|
89
150
|
MSG_LITERAL = 'Redundant safe navigation with default literal detected.'
|
151
|
+
MSG_NON_NIL = 'Redundant safe navigation on non-nil receiver (detected by analyzing ' \
|
152
|
+
'previous code/method invocations).'
|
90
153
|
|
91
154
|
NIL_SPECIFIC_METHODS = (nil.methods - Object.new.methods).to_set.freeze
|
92
155
|
|
93
156
|
SNAKE_CASE = /\A[[:digit:][:upper:]_]+\z/.freeze
|
94
157
|
|
158
|
+
GUARANTEED_INSTANCE_METHODS = %i[to_s to_i to_f to_a to_h].freeze
|
159
|
+
|
95
160
|
# @!method respond_to_nil_specific_method?(node)
|
96
161
|
def_node_matcher :respond_to_nil_specific_method?, <<~PATTERN
|
97
162
|
(csend _ :respond_to? (sym %NIL_SPECIFIC_METHODS))
|
@@ -111,15 +176,27 @@ module RuboCop
|
|
111
176
|
|
112
177
|
# rubocop:disable Metrics/AbcSize
|
113
178
|
def on_csend(node)
|
179
|
+
range = node.loc.dot
|
180
|
+
|
181
|
+
if infer_non_nil_receiver?
|
182
|
+
checker = Lint::Utils::NilReceiverChecker.new(node.receiver, additional_nil_methods)
|
183
|
+
|
184
|
+
if checker.cant_be_nil?
|
185
|
+
add_offense(range, message: MSG_NON_NIL) { |corrector| corrector.replace(range, '.') }
|
186
|
+
return
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
114
190
|
unless assume_receiver_instance_exists?(node.receiver)
|
115
|
-
return
|
191
|
+
return if !guaranteed_instance?(node.receiver) && !check?(node)
|
116
192
|
return if respond_to_nil_specific_method?(node)
|
117
193
|
end
|
118
194
|
|
119
|
-
range = node.loc.dot
|
120
195
|
add_offense(range) { |corrector| corrector.replace(range, '.') }
|
121
196
|
end
|
197
|
+
# rubocop:enable Metrics/AbcSize
|
122
198
|
|
199
|
+
# rubocop:disable Metrics/AbcSize
|
123
200
|
def on_or(node)
|
124
201
|
conversion_with_default?(node) do |send_node|
|
125
202
|
range = send_node.loc.dot.begin.join(node.source_range.end)
|
@@ -142,7 +219,20 @@ module RuboCop
|
|
142
219
|
receiver.self_type? || (receiver.literal? && !receiver.nil_type?)
|
143
220
|
end
|
144
221
|
|
222
|
+
def guaranteed_instance?(node)
|
223
|
+
receiver = if node.any_block_type?
|
224
|
+
node.send_node
|
225
|
+
else
|
226
|
+
node
|
227
|
+
end
|
228
|
+
return false unless receiver.send_type?
|
229
|
+
|
230
|
+
GUARANTEED_INSTANCE_METHODS.include?(receiver.method_name)
|
231
|
+
end
|
232
|
+
|
145
233
|
def check?(node)
|
234
|
+
return false unless allowed_method?(node.method_name)
|
235
|
+
|
146
236
|
parent = node.parent
|
147
237
|
return false unless parent
|
148
238
|
|
@@ -154,6 +244,15 @@ module RuboCop
|
|
154
244
|
def condition?(parent, node)
|
155
245
|
(parent.conditional? || parent.post_condition_loop?) && parent.condition == node
|
156
246
|
end
|
247
|
+
|
248
|
+
def infer_non_nil_receiver?
|
249
|
+
cop_config['InferNonNilReceiver']
|
250
|
+
end
|
251
|
+
|
252
|
+
def additional_nil_methods
|
253
|
+
@additional_nil_methods ||=
|
254
|
+
Array(cop_config.fetch('AdditionalNilMethods', []).map(&:to_sym))
|
255
|
+
end
|
157
256
|
end
|
158
257
|
end
|
159
258
|
end
|
@@ -29,7 +29,7 @@ module RuboCop
|
|
29
29
|
RESTRICT_ON_SEND = %i[print puts warn].freeze
|
30
30
|
|
31
31
|
# @!method to_s_without_args?(node)
|
32
|
-
def_node_matcher :to_s_without_args?, '(
|
32
|
+
def_node_matcher :to_s_without_args?, '(call _ :to_s)'
|
33
33
|
|
34
34
|
def on_interpolation(begin_node)
|
35
35
|
final_node = begin_node.children.last
|
@@ -42,7 +42,7 @@ module RuboCop
|
|
42
42
|
def on_send(node)
|
43
43
|
return if node.receiver
|
44
44
|
|
45
|
-
node.each_child_node(:
|
45
|
+
node.each_child_node(:call) do |child|
|
46
46
|
next if !child.method?(:to_s) || child.arguments.any?
|
47
47
|
|
48
48
|
register_offense(child, "`#{node.method_name}`")
|