rubocop 1.67.0 → 1.76.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/LICENSE.txt +1 -1
- data/README.md +22 -16
- data/config/default.yml +315 -53
- data/config/internal_affairs.yml +20 -0
- data/config/obsoletion.yml +8 -3
- data/lib/rubocop/cached_data.rb +12 -4
- data/lib/rubocop/cli/command/execute_runner.rb +4 -4
- data/lib/rubocop/cli/command/show_cops.rb +24 -2
- data/lib/rubocop/cli/command/suggest_extensions.rb +7 -1
- data/lib/rubocop/cli/command/version.rb +2 -2
- data/lib/rubocop/cli.rb +1 -1
- data/lib/rubocop/comment_config.rb +2 -2
- data/lib/rubocop/config.rb +52 -10
- data/lib/rubocop/config_loader.rb +52 -9
- data/lib/rubocop/config_loader_resolver.rb +36 -10
- data/lib/rubocop/config_obsoletion/extracted_cop.rb +4 -3
- data/lib/rubocop/config_obsoletion/renamed_cop.rb +18 -3
- data/lib/rubocop/config_obsoletion.rb +46 -2
- data/lib/rubocop/config_validator.rb +25 -14
- data/lib/rubocop/cop/autocorrect_logic.rb +51 -26
- data/lib/rubocop/cop/base.rb +7 -1
- data/lib/rubocop/cop/bundler/duplicated_gem.rb +2 -2
- data/lib/rubocop/cop/bundler/gem_comment.rb +1 -1
- data/lib/rubocop/cop/bundler/gem_filename.rb +0 -1
- data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +0 -1
- data/lib/rubocop/cop/bundler/ordered_gems.rb +1 -1
- data/lib/rubocop/cop/correctors/alignment_corrector.rb +1 -12
- data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +1 -1
- data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +10 -0
- data/lib/rubocop/cop/gemspec/deprecated_attribute_assignment.rb +1 -2
- data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +50 -6
- data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +1 -1
- data/lib/rubocop/cop/gemspec/required_ruby_version.rb +0 -2
- data/lib/rubocop/cop/generator.rb +6 -0
- data/lib/rubocop/cop/internal_affairs/cop_enabled.rb +85 -0
- data/lib/rubocop/cop/internal_affairs/example_description.rb +8 -4
- data/lib/rubocop/cop/internal_affairs/location_exists.rb +116 -0
- data/lib/rubocop/cop/internal_affairs/location_expression.rb +2 -1
- data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +3 -4
- data/lib/rubocop/cop/internal_affairs/node_first_or_last_argument.rb +3 -2
- data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_processor.rb +63 -0
- data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_walker.rb +131 -0
- data/lib/rubocop/cop/internal_affairs/node_pattern_groups.rb +231 -0
- data/lib/rubocop/cop/internal_affairs/node_type_group.rb +91 -0
- data/lib/rubocop/cop/internal_affairs/node_type_multiple_predicates.rb +126 -0
- data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +4 -3
- data/lib/rubocop/cop/internal_affairs/numblock_handler.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/on_send_without_on_csend.rb +90 -0
- data/lib/rubocop/cop/internal_affairs/operator_keyword.rb +48 -0
- data/lib/rubocop/cop/internal_affairs/plugin.rb +33 -0
- data/lib/rubocop/cop/internal_affairs/redundant_described_class_as_subject.rb +6 -5
- data/lib/rubocop/cop/internal_affairs/redundant_source_range.rb +3 -1
- data/lib/rubocop/cop/internal_affairs/single_line_comparison.rb +5 -4
- data/lib/rubocop/cop/internal_affairs/style_detected_api_use.rb +0 -2
- data/lib/rubocop/cop/internal_affairs/undefined_config.rb +13 -2
- data/lib/rubocop/cop/internal_affairs.rb +7 -16
- data/lib/rubocop/cop/layout/access_modifier_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/argument_alignment.rb +2 -9
- data/lib/rubocop/cop/layout/array_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/begin_end_alignment.rb +0 -1
- data/lib/rubocop/cop/layout/block_alignment.rb +3 -2
- data/lib/rubocop/cop/layout/block_end_newline.rb +1 -0
- data/lib/rubocop/cop/layout/class_structure.rb +44 -9
- data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +4 -4
- data/lib/rubocop/cop/layout/def_end_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/dot_position.rb +1 -1
- data/lib/rubocop/cop/layout/else_alignment.rb +2 -2
- data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +3 -3
- data/lib/rubocop/cop/layout/empty_line_between_defs.rb +7 -11
- data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +36 -6
- data/lib/rubocop/cop/layout/empty_lines_around_begin_body.rb +5 -6
- data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +1 -0
- data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +4 -5
- data/lib/rubocop/cop/layout/empty_lines_around_method_body.rb +23 -1
- data/lib/rubocop/cop/layout/end_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/extra_spacing.rb +1 -1
- data/lib/rubocop/cop/layout/first_argument_indentation.rb +4 -9
- data/lib/rubocop/cop/layout/first_array_element_indentation.rb +2 -7
- data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +2 -7
- data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +1 -1
- data/lib/rubocop/cop/layout/first_parameter_indentation.rb +2 -2
- data/lib/rubocop/cop/layout/hash_alignment.rb +8 -6
- data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +2 -1
- data/lib/rubocop/cop/layout/indentation_width.rb +8 -7
- data/lib/rubocop/cop/layout/leading_comment_space.rb +57 -2
- data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +11 -2
- data/lib/rubocop/cop/layout/line_continuation_spacing.rb +7 -1
- data/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb +2 -2
- data/lib/rubocop/cop/layout/line_length.rb +123 -4
- data/lib/rubocop/cop/layout/multiline_block_layout.rb +1 -0
- data/lib/rubocop/cop/layout/multiline_hash_key_line_breaks.rb +1 -1
- data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +25 -0
- data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +2 -1
- data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +4 -4
- data/lib/rubocop/cop/layout/multiline_method_definition_brace_layout.rb +1 -1
- data/lib/rubocop/cop/layout/multiline_method_parameter_line_breaks.rb +1 -0
- data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +3 -4
- data/lib/rubocop/cop/layout/parameter_alignment.rb +3 -4
- data/lib/rubocop/cop/layout/redundant_line_break.rb +19 -46
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +6 -7
- data/lib/rubocop/cop/layout/single_line_block_chain.rb +1 -1
- data/lib/rubocop/cop/layout/space_after_colon.rb +2 -2
- data/lib/rubocop/cop/layout/space_after_comma.rb +1 -1
- data/lib/rubocop/cop/layout/space_after_method_name.rb +1 -1
- data/lib/rubocop/cop/layout/space_after_semicolon.rb +11 -1
- data/lib/rubocop/cop/layout/space_around_keyword.rb +2 -1
- data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +1 -1
- data/lib/rubocop/cop/layout/space_around_operators.rb +23 -21
- data/lib/rubocop/cop/layout/space_before_block_braces.rb +1 -0
- data/lib/rubocop/cop/layout/space_before_brackets.rb +8 -34
- data/lib/rubocop/cop/layout/space_before_comma.rb +1 -1
- data/lib/rubocop/cop/layout/space_before_semicolon.rb +1 -1
- data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +11 -1
- data/lib/rubocop/cop/layout/space_inside_block_braces.rb +5 -0
- data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +7 -0
- data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +0 -1
- data/lib/rubocop/cop/layout/trailing_whitespace.rb +5 -3
- data/lib/rubocop/cop/lint/ambiguous_block_association.rb +1 -1
- data/lib/rubocop/cop/lint/array_literal_in_regexp.rb +118 -0
- data/lib/rubocop/cop/lint/assignment_in_condition.rb +1 -3
- data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +10 -12
- data/lib/rubocop/cop/lint/boolean_symbol.rb +1 -1
- data/lib/rubocop/cop/lint/circular_argument_reference.rb +4 -1
- data/lib/rubocop/cop/lint/constant_definition_in_block.rb +3 -3
- data/lib/rubocop/cop/lint/constant_reassignment.rb +148 -0
- data/lib/rubocop/cop/lint/cop_directive_syntax.rb +84 -0
- data/lib/rubocop/cop/lint/debugger.rb +3 -3
- data/lib/rubocop/cop/lint/deprecated_class_methods.rb +1 -1
- data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +3 -2
- data/lib/rubocop/cop/lint/duplicate_branch.rb +39 -4
- data/lib/rubocop/cop/lint/duplicate_match_pattern.rb +1 -1
- data/lib/rubocop/cop/lint/duplicate_methods.rb +86 -19
- data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +1 -1
- data/lib/rubocop/cop/lint/duplicate_set_element.rb +20 -7
- data/lib/rubocop/cop/lint/empty_conditional_body.rb +14 -64
- data/lib/rubocop/cop/lint/empty_ensure.rb +1 -1
- data/lib/rubocop/cop/lint/empty_expression.rb +0 -2
- data/lib/rubocop/cop/lint/empty_file.rb +0 -2
- data/lib/rubocop/cop/lint/empty_interpolation.rb +3 -1
- data/lib/rubocop/cop/lint/ensure_return.rb +1 -1
- data/lib/rubocop/cop/lint/erb_new_arguments.rb +0 -6
- data/lib/rubocop/cop/lint/float_comparison.rb +47 -14
- data/lib/rubocop/cop/lint/float_out_of_range.rb +2 -4
- data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +2 -2
- data/lib/rubocop/cop/lint/hash_new_with_keyword_arguments_as_default.rb +55 -0
- data/lib/rubocop/cop/lint/identity_comparison.rb +19 -15
- data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +1 -1
- data/lib/rubocop/cop/lint/interpolation_check.rb +9 -0
- data/lib/rubocop/cop/lint/it_without_arguments_in_block.rb +3 -0
- data/lib/rubocop/cop/lint/literal_as_condition.rb +110 -9
- data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +1 -1
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +24 -6
- data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +1 -1
- data/lib/rubocop/cop/lint/missing_super.rb +2 -2
- data/lib/rubocop/cop/lint/mixed_case_range.rb +5 -8
- data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +1 -1
- data/lib/rubocop/cop/lint/nested_method_definition.rb +10 -6
- data/lib/rubocop/cop/lint/next_without_accumulator.rb +1 -1
- data/lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +2 -2
- data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +12 -3
- data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +3 -3
- data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +3 -3
- data/lib/rubocop/cop/lint/number_conversion.rb +0 -1
- data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +1 -2
- data/lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +93 -0
- data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +2 -3
- data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +3 -2
- data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +1 -5
- data/lib/rubocop/cop/lint/raise_exception.rb +29 -10
- data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +1 -1
- data/lib/rubocop/cop/lint/redundant_regexp_quantifiers.rb +1 -1
- data/lib/rubocop/cop/lint/redundant_require_statement.rb +0 -21
- data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +12 -7
- data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +8 -7
- data/lib/rubocop/cop/lint/redundant_string_coercion.rb +2 -2
- data/lib/rubocop/cop/lint/redundant_type_conversion.rb +261 -0
- data/lib/rubocop/cop/lint/redundant_with_index.rb +3 -0
- data/lib/rubocop/cop/lint/redundant_with_object.rb +3 -0
- data/lib/rubocop/cop/lint/refinement_import_methods.rb +1 -1
- data/lib/rubocop/cop/lint/regexp_as_condition.rb +0 -1
- data/lib/rubocop/cop/lint/rescue_exception.rb +1 -1
- data/lib/rubocop/cop/lint/rescue_type.rb +3 -7
- data/lib/rubocop/cop/lint/return_in_void_context.rb +9 -11
- data/lib/rubocop/cop/lint/safe_navigation_chain.rb +17 -1
- data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +5 -1
- data/lib/rubocop/cop/lint/self_assignment.rb +8 -10
- data/lib/rubocop/cop/lint/shadowed_exception.rb +1 -1
- data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +13 -1
- data/lib/rubocop/cop/lint/shared_mutable_default.rb +76 -0
- data/lib/rubocop/cop/lint/suppressed_exception.rb +1 -1
- data/lib/rubocop/cop/lint/suppressed_exception_in_number_conversion.rb +111 -0
- data/lib/rubocop/cop/lint/symbol_conversion.rb +1 -1
- data/lib/rubocop/cop/lint/syntax.rb +4 -1
- data/lib/rubocop/cop/lint/to_enum_arguments.rb +1 -1
- data/lib/rubocop/cop/lint/top_level_return_with_argument.rb +1 -1
- data/lib/rubocop/cop/lint/unescaped_bracket_in_regexp.rb +88 -0
- data/lib/rubocop/cop/lint/unexpected_block_arity.rb +3 -1
- data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +1 -1
- data/lib/rubocop/cop/lint/unreachable_code.rb +52 -2
- data/lib/rubocop/cop/lint/unreachable_loop.rb +6 -6
- data/lib/rubocop/cop/lint/unused_method_argument.rb +18 -2
- data/lib/rubocop/cop/lint/useless_access_modifier.rb +5 -4
- data/lib/rubocop/cop/lint/useless_assignment.rb +3 -1
- data/lib/rubocop/cop/lint/useless_constant_scoping.rb +71 -0
- data/lib/rubocop/cop/lint/useless_default_value_argument.rb +87 -0
- data/lib/rubocop/cop/lint/useless_defined.rb +55 -0
- data/lib/rubocop/cop/lint/useless_else_without_rescue.rb +4 -0
- data/lib/rubocop/cop/lint/useless_method_definition.rb +1 -1
- data/lib/rubocop/cop/lint/useless_numeric_operation.rb +2 -1
- data/lib/rubocop/cop/lint/useless_or.rb +98 -0
- data/lib/rubocop/cop/lint/useless_rescue.rb +2 -2
- data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +2 -2
- data/lib/rubocop/cop/lint/useless_setter_call.rb +14 -25
- data/lib/rubocop/cop/lint/void.rb +16 -12
- data/lib/rubocop/cop/message_annotator.rb +7 -3
- data/lib/rubocop/cop/metrics/abc_size.rb +1 -1
- data/lib/rubocop/cop/metrics/block_length.rb +1 -0
- data/lib/rubocop/cop/metrics/block_nesting.rb +1 -1
- data/lib/rubocop/cop/metrics/class_length.rb +9 -9
- data/lib/rubocop/cop/metrics/collection_literal_length.rb +7 -0
- data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +5 -2
- data/lib/rubocop/cop/metrics/method_length.rb +9 -1
- data/lib/rubocop/cop/metrics/module_length.rb +1 -1
- data/lib/rubocop/cop/metrics/perceived_complexity.rb +1 -1
- data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +1 -1
- data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +3 -4
- data/lib/rubocop/cop/metrics/utils/repeated_attribute_discount.rb +7 -7
- data/lib/rubocop/cop/mixin/alignment.rb +2 -2
- data/lib/rubocop/cop/mixin/allowed_pattern.rb +4 -4
- data/lib/rubocop/cop/mixin/check_assignment.rb +4 -12
- data/lib/rubocop/cop/mixin/check_line_breakable.rb +22 -12
- data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +49 -0
- data/lib/rubocop/cop/mixin/comments_help.rb +8 -3
- data/lib/rubocop/cop/mixin/def_node.rb +1 -1
- data/lib/rubocop/cop/mixin/dig_help.rb +27 -0
- data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +1 -1
- data/lib/rubocop/cop/mixin/endless_method_rewriter.rb +24 -0
- data/lib/rubocop/cop/mixin/forbidden_identifiers.rb +20 -0
- data/lib/rubocop/cop/mixin/forbidden_pattern.rb +16 -0
- data/lib/rubocop/cop/mixin/frozen_string_literal.rb +3 -2
- data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +15 -14
- data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +22 -22
- data/lib/rubocop/cop/mixin/hash_subset.rb +203 -0
- data/lib/rubocop/cop/mixin/hash_transform_method.rb +74 -74
- data/lib/rubocop/cop/mixin/line_length_help.rb +5 -4
- data/lib/rubocop/cop/mixin/method_complexity.rb +2 -1
- data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +7 -9
- data/lib/rubocop/cop/mixin/ordered_gem_node.rb +1 -1
- data/lib/rubocop/cop/mixin/percent_literal.rb +1 -1
- data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +68 -30
- data/lib/rubocop/cop/mixin/range_help.rb +15 -4
- data/lib/rubocop/cop/mixin/space_before_punctuation.rb +1 -1
- data/lib/rubocop/cop/mixin/statement_modifier.rb +8 -3
- data/lib/rubocop/cop/mixin/string_help.rb +2 -2
- data/lib/rubocop/cop/mixin/string_literals_help.rb +1 -1
- data/lib/rubocop/cop/mixin/target_ruby_version.rb +17 -1
- data/lib/rubocop/cop/mixin/trailing_comma.rb +21 -5
- data/lib/rubocop/cop/naming/accessor_method_name.rb +6 -6
- data/lib/rubocop/cop/naming/block_forwarding.rb +20 -16
- data/lib/rubocop/cop/naming/constant_name.rb +6 -7
- data/lib/rubocop/cop/naming/file_name.rb +0 -2
- data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +12 -13
- data/lib/rubocop/cop/naming/method_name.rb +64 -8
- data/lib/rubocop/cop/naming/predicate_method.rb +216 -0
- data/lib/rubocop/cop/naming/{predicate_name.rb → predicate_prefix.rb} +46 -2
- data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +6 -14
- data/lib/rubocop/cop/naming/variable_name.rb +50 -6
- data/lib/rubocop/cop/naming/variable_number.rb +2 -3
- data/lib/rubocop/cop/offense.rb +2 -3
- data/lib/rubocop/cop/registry.rb +9 -6
- data/lib/rubocop/cop/security/compound_hash.rb +2 -0
- data/lib/rubocop/cop/security/yaml_load.rb +3 -2
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +114 -34
- data/lib/rubocop/cop/style/accessor_grouping.rb +19 -5
- data/lib/rubocop/cop/style/ambiguous_endless_method_definition.rb +79 -0
- data/lib/rubocop/cop/style/and_or.rb +1 -1
- data/lib/rubocop/cop/style/arguments_forwarding.rb +47 -28
- data/lib/rubocop/cop/style/array_first_last.rb +18 -2
- data/lib/rubocop/cop/style/array_intersect.rb +42 -30
- data/lib/rubocop/cop/style/bitwise_predicate.rb +100 -0
- data/lib/rubocop/cop/style/block_delimiters.rb +43 -25
- data/lib/rubocop/cop/style/case_like_if.rb +8 -11
- data/lib/rubocop/cop/style/class_and_module_children.rb +52 -11
- data/lib/rubocop/cop/style/class_equality_comparison.rb +1 -1
- data/lib/rubocop/cop/style/collection_methods.rb +2 -1
- data/lib/rubocop/cop/style/combinable_defined.rb +115 -0
- data/lib/rubocop/cop/style/combinable_loops.rb +3 -2
- data/lib/rubocop/cop/style/command_literal.rb +1 -1
- data/lib/rubocop/cop/style/commented_keyword.rb +20 -3
- data/lib/rubocop/cop/style/comparable_between.rb +78 -0
- data/lib/rubocop/cop/style/concat_array_literals.rb +1 -1
- data/lib/rubocop/cop/style/conditional_assignment.rb +39 -27
- data/lib/rubocop/cop/style/constant_visibility.rb +3 -12
- data/lib/rubocop/cop/style/data_inheritance.rb +7 -0
- data/lib/rubocop/cop/style/def_with_parentheses.rb +18 -5
- data/lib/rubocop/cop/style/dig_chain.rb +89 -0
- data/lib/rubocop/cop/style/documentation.rb +1 -1
- data/lib/rubocop/cop/style/double_negation.rb +4 -4
- data/lib/rubocop/cop/style/each_for_simple_loop.rb +4 -7
- data/lib/rubocop/cop/style/each_with_object.rb +2 -3
- data/lib/rubocop/cop/style/empty_else.rb +4 -2
- data/lib/rubocop/cop/style/empty_literal.rb +5 -1
- data/lib/rubocop/cop/style/empty_method.rb +1 -1
- data/lib/rubocop/cop/style/empty_string_inside_interpolation.rb +100 -0
- data/lib/rubocop/cop/style/endless_method.rb +150 -18
- data/lib/rubocop/cop/style/eval_with_location.rb +4 -4
- data/lib/rubocop/cop/style/exact_regexp_match.rb +2 -3
- data/lib/rubocop/cop/style/expand_path_arguments.rb +2 -7
- data/lib/rubocop/cop/style/explicit_block_argument.rb +16 -3
- data/lib/rubocop/cop/style/exponential_notation.rb +3 -3
- data/lib/rubocop/cop/style/fetch_env_var.rb +2 -1
- data/lib/rubocop/cop/style/file_null.rb +89 -0
- data/lib/rubocop/cop/style/file_touch.rb +75 -0
- data/lib/rubocop/cop/style/float_division.rb +8 -4
- data/lib/rubocop/cop/style/for.rb +1 -1
- data/lib/rubocop/cop/style/format_string_token.rb +38 -11
- data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +3 -2
- data/lib/rubocop/cop/style/global_std_stream.rb +3 -0
- data/lib/rubocop/cop/style/global_vars.rb +1 -3
- data/lib/rubocop/cop/style/guard_clause.rb +17 -3
- data/lib/rubocop/cop/style/hash_conversion.rb +1 -2
- data/lib/rubocop/cop/style/hash_each_methods.rb +6 -8
- data/lib/rubocop/cop/style/hash_except.rb +35 -147
- data/lib/rubocop/cop/style/hash_fetch_chain.rb +104 -0
- data/lib/rubocop/cop/style/hash_slice.rb +80 -0
- data/lib/rubocop/cop/style/hash_syntax.rb +9 -3
- data/lib/rubocop/cop/style/hash_transform_keys.rb +2 -2
- data/lib/rubocop/cop/style/hash_transform_values.rb +2 -2
- data/lib/rubocop/cop/style/identical_conditional_branches.rb +25 -6
- data/lib/rubocop/cop/style/if_inside_else.rb +10 -14
- data/lib/rubocop/cop/style/if_unless_modifier.rb +25 -7
- data/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +4 -7
- data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +3 -4
- data/lib/rubocop/cop/style/if_with_semicolon.rb +20 -9
- data/lib/rubocop/cop/style/infinite_loop.rb +1 -1
- data/lib/rubocop/cop/style/inverse_methods.rb +15 -12
- data/lib/rubocop/cop/style/invertible_unless_condition.rb +2 -2
- data/lib/rubocop/cop/style/ip_addresses.rb +2 -2
- data/lib/rubocop/cop/style/it_assignment.rb +36 -0
- data/lib/rubocop/cop/style/it_block_parameter.rb +119 -0
- data/lib/rubocop/cop/style/keyword_arguments_merging.rb +67 -0
- data/lib/rubocop/cop/style/keyword_parameters_order.rb +14 -8
- data/lib/rubocop/cop/style/lambda.rb +1 -0
- data/lib/rubocop/cop/style/lambda_call.rb +10 -4
- data/lib/rubocop/cop/style/line_end_concatenation.rb +10 -4
- data/lib/rubocop/cop/style/map_into_array.rb +11 -3
- data/lib/rubocop/cop/style/map_to_hash.rb +12 -1
- data/lib/rubocop/cop/style/map_to_set.rb +3 -2
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +27 -17
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +2 -0
- data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +8 -11
- data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +3 -4
- data/lib/rubocop/cop/style/method_def_parentheses.rb +1 -1
- data/lib/rubocop/cop/style/missing_else.rb +2 -0
- data/lib/rubocop/cop/style/missing_respond_to_missing.rb +33 -3
- data/lib/rubocop/cop/style/multiline_block_chain.rb +3 -2
- data/lib/rubocop/cop/style/multiline_if_modifier.rb +2 -0
- data/lib/rubocop/cop/style/multiline_memoization.rb +1 -1
- data/lib/rubocop/cop/style/multiline_method_signature.rb +1 -9
- data/lib/rubocop/cop/style/multiple_comparison.rb +52 -51
- data/lib/rubocop/cop/style/mutable_constant.rb +7 -8
- data/lib/rubocop/cop/style/negated_if_else_condition.rb +7 -5
- data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +1 -1
- data/lib/rubocop/cop/style/nested_ternary_operator.rb +5 -4
- data/lib/rubocop/cop/style/next.rb +44 -0
- data/lib/rubocop/cop/style/not.rb +1 -1
- data/lib/rubocop/cop/style/object_then.rb +15 -15
- data/lib/rubocop/cop/style/one_line_conditional.rb +25 -4
- data/lib/rubocop/cop/style/open_struct_use.rb +5 -5
- data/lib/rubocop/cop/style/operator_method_call.rb +5 -6
- data/lib/rubocop/cop/style/or_assignment.rb +3 -6
- data/lib/rubocop/cop/style/parallel_assignment.rb +9 -18
- data/lib/rubocop/cop/style/parentheses_around_condition.rb +2 -2
- data/lib/rubocop/cop/style/percent_literal_delimiters.rb +1 -1
- data/lib/rubocop/cop/style/percent_q_literals.rb +1 -1
- data/lib/rubocop/cop/style/proc.rb +2 -2
- data/lib/rubocop/cop/style/quoted_symbols.rb +1 -1
- data/lib/rubocop/cop/style/raise_args.rb +15 -13
- data/lib/rubocop/cop/style/random_with_offset.rb +3 -3
- data/lib/rubocop/cop/style/redundant_argument.rb +3 -1
- data/lib/rubocop/cop/style/redundant_array_flatten.rb +50 -0
- data/lib/rubocop/cop/style/redundant_assignment.rb +1 -1
- data/lib/rubocop/cop/style/redundant_begin.rb +2 -1
- data/lib/rubocop/cop/style/redundant_condition.rb +95 -23
- data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +16 -5
- data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +6 -10
- data/lib/rubocop/cop/style/redundant_each.rb +1 -1
- data/lib/rubocop/cop/style/redundant_exception.rb +2 -2
- data/lib/rubocop/cop/style/redundant_format.rb +262 -0
- data/lib/rubocop/cop/style/redundant_freeze.rb +3 -3
- data/lib/rubocop/cop/style/redundant_initialize.rb +12 -3
- data/lib/rubocop/cop/style/redundant_line_continuation.rb +54 -18
- data/lib/rubocop/cop/style/redundant_parentheses.rb +68 -26
- data/lib/rubocop/cop/style/redundant_regexp_argument.rb +4 -0
- data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +1 -1
- data/lib/rubocop/cop/style/redundant_regexp_escape.rb +1 -1
- data/lib/rubocop/cop/style/redundant_return.rb +2 -2
- data/lib/rubocop/cop/style/redundant_self.rb +9 -15
- data/lib/rubocop/cop/style/redundant_self_assignment.rb +20 -32
- data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +4 -4
- data/lib/rubocop/cop/style/redundant_sort.rb +3 -3
- data/lib/rubocop/cop/style/redundant_sort_by.rb +17 -1
- data/lib/rubocop/cop/style/redundant_string_escape.rb +2 -2
- data/lib/rubocop/cop/style/regexp_literal.rb +1 -1
- data/lib/rubocop/cop/style/rescue_modifier.rb +5 -3
- data/lib/rubocop/cop/style/return_nil.rb +2 -2
- data/lib/rubocop/cop/style/safe_navigation.rb +56 -16
- data/lib/rubocop/cop/style/safe_navigation_chain_length.rb +52 -0
- data/lib/rubocop/cop/style/select_by_regexp.rb +5 -2
- data/lib/rubocop/cop/style/self_assignment.rb +11 -17
- data/lib/rubocop/cop/style/semicolon.rb +1 -1
- data/lib/rubocop/cop/style/send_with_literal_method_name.rb +2 -1
- data/lib/rubocop/cop/style/signal_exception.rb +2 -3
- data/lib/rubocop/cop/style/single_argument_dig.rb +9 -5
- data/lib/rubocop/cop/style/single_line_block_params.rb +1 -1
- data/lib/rubocop/cop/style/single_line_do_end_block.rb +15 -4
- data/lib/rubocop/cop/style/single_line_methods.rb +6 -7
- data/lib/rubocop/cop/style/slicing_with_range.rb +40 -11
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +42 -106
- data/lib/rubocop/cop/style/special_global_vars.rb +1 -1
- data/lib/rubocop/cop/style/string_concatenation.rb +15 -15
- data/lib/rubocop/cop/style/string_literals.rb +1 -1
- data/lib/rubocop/cop/style/string_methods.rb +1 -1
- data/lib/rubocop/cop/style/struct_inheritance.rb +8 -1
- data/lib/rubocop/cop/style/super_arguments.rb +66 -19
- data/lib/rubocop/cop/style/swap_values.rb +4 -15
- data/lib/rubocop/cop/style/symbol_proc.rb +2 -0
- data/lib/rubocop/cop/style/ternary_parentheses.rb +25 -4
- data/lib/rubocop/cop/style/top_level_method_definition.rb +2 -1
- data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +11 -2
- data/lib/rubocop/cop/style/trailing_comma_in_array_literal.rb +47 -6
- data/lib/rubocop/cop/style/trailing_comma_in_hash_literal.rb +48 -6
- data/lib/rubocop/cop/style/trailing_underscore_variable.rb +4 -4
- data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
- data/lib/rubocop/cop/style/variable_interpolation.rb +1 -2
- data/lib/rubocop/cop/style/while_until_modifier.rb +0 -1
- data/lib/rubocop/cop/style/yoda_condition.rb +8 -4
- data/lib/rubocop/cop/style/yoda_expression.rb +2 -1
- data/lib/rubocop/cop/team.rb +1 -1
- data/lib/rubocop/cop/util.rb +12 -5
- data/lib/rubocop/cop/utils/format_string.rb +10 -5
- data/lib/rubocop/cop/variable_force/assignment.rb +24 -5
- data/lib/rubocop/cop/variable_force/branch.rb +1 -1
- data/lib/rubocop/cop/variable_force/scope.rb +1 -1
- data/lib/rubocop/cop/variable_force/variable.rb +14 -3
- data/lib/rubocop/cop/variable_force/variable_table.rb +5 -5
- data/lib/rubocop/cop/variable_force.rb +5 -11
- data/lib/rubocop/cops_documentation_generator.rb +50 -25
- data/lib/rubocop/directive_comment.rb +45 -11
- data/lib/rubocop/ext/regexp_node.rb +0 -1
- data/lib/rubocop/formatter/disabled_config_formatter.rb +3 -2
- data/lib/rubocop/formatter/formatter_set.rb +1 -1
- data/lib/rubocop/formatter/html_formatter.rb +1 -1
- data/lib/rubocop/formatter/pacman_formatter.rb +1 -1
- data/lib/rubocop/lsp/diagnostic.rb +189 -0
- data/lib/rubocop/lsp/logger.rb +2 -2
- data/lib/rubocop/lsp/routes.rb +7 -23
- data/lib/rubocop/lsp/runtime.rb +18 -50
- data/lib/rubocop/lsp/server.rb +0 -2
- data/lib/rubocop/lsp/stdin_runner.rb +85 -0
- data/lib/rubocop/magic_comment.rb +11 -3
- data/lib/rubocop/options.rb +28 -12
- data/lib/rubocop/path_util.rb +15 -8
- data/lib/rubocop/plugin/configuration_integrator.rb +143 -0
- data/lib/rubocop/plugin/load_error.rb +26 -0
- data/lib/rubocop/plugin/loader.rb +100 -0
- data/lib/rubocop/plugin/not_supported_error.rb +29 -0
- data/lib/rubocop/plugin.rb +46 -0
- data/lib/rubocop/rake_task.rb +4 -1
- data/lib/rubocop/result_cache.rb +13 -13
- data/lib/rubocop/rspec/cop_helper.rb +13 -1
- data/lib/rubocop/rspec/expect_offense.rb +15 -5
- data/lib/rubocop/rspec/shared_contexts.rb +38 -1
- data/lib/rubocop/rspec/support.rb +4 -2
- data/lib/rubocop/runner.rb +26 -15
- data/lib/rubocop/server/cache.rb +47 -11
- data/lib/rubocop/server/cli.rb +2 -2
- data/lib/rubocop/target_finder.rb +7 -2
- data/lib/rubocop/target_ruby.rb +17 -2
- data/lib/rubocop/version.rb +53 -12
- data/lib/rubocop.rb +38 -2
- data/lib/ruby_lsp/rubocop/addon.rb +75 -0
- data/lib/ruby_lsp/rubocop/runtime_adapter.rb +65 -0
- metadata +85 -21
- data/lib/rubocop/cop/utils/regexp_ranges.rb +0 -113
- data/lib/rubocop/rspec/host_environment_simulation_helper.rb +0 -28
@@ -53,6 +53,7 @@ module RuboCop
|
|
53
53
|
# rubocop:enable Metrics/AbcSize
|
54
54
|
|
55
55
|
alias on_numblock on_block
|
56
|
+
alias on_itblock on_block
|
56
57
|
|
57
58
|
private
|
58
59
|
|
@@ -64,6 +65,8 @@ module RuboCop
|
|
64
65
|
(args (arg _)) ...)
|
65
66
|
(numblock
|
66
67
|
$(call _ {:each_with_index :with_index} ...) 1 ...)
|
68
|
+
(itblock
|
69
|
+
$(call _ {:each_with_index :with_index} ...) _ ...)
|
67
70
|
}
|
68
71
|
PATTERN
|
69
72
|
|
@@ -49,6 +49,7 @@ module RuboCop
|
|
49
49
|
end
|
50
50
|
|
51
51
|
alias on_numblock on_block
|
52
|
+
alias on_itblock on_block
|
52
53
|
|
53
54
|
private
|
54
55
|
|
@@ -59,6 +60,8 @@ module RuboCop
|
|
59
60
|
$(call _ {:each_with_object :with_object} _) (args (arg _)) ...)
|
60
61
|
(numblock
|
61
62
|
$(call _ {:each_with_object :with_object} _) 1 ...)
|
63
|
+
(itblock
|
64
|
+
$(call _ {:each_with_object :with_object} _) _ ...)
|
62
65
|
}
|
63
66
|
PATTERN
|
64
67
|
|
@@ -6,7 +6,7 @@ module RuboCop
|
|
6
6
|
# Checks if `include` or `prepend` is called in `refine` block.
|
7
7
|
# These methods are deprecated and should be replaced with `Refinement#import_methods`.
|
8
8
|
#
|
9
|
-
# It emulates deprecation warnings in Ruby 3.1.
|
9
|
+
# It emulates deprecation warnings in Ruby 3.1. Functionality has been removed in Ruby 3.2.
|
10
10
|
#
|
11
11
|
# @safety
|
12
12
|
# This cop's autocorrection is unsafe because `include M` will affect the included class
|
@@ -42,15 +42,11 @@ module RuboCop
|
|
42
42
|
INVALID_TYPES = %i[array dstr float hash nil int str sym].freeze
|
43
43
|
|
44
44
|
def on_resbody(node)
|
45
|
-
|
46
|
-
return if rescued.nil?
|
47
|
-
|
48
|
-
exceptions = *rescued
|
49
|
-
invalid_exceptions = invalid_exceptions(exceptions)
|
45
|
+
invalid_exceptions = invalid_exceptions(node.exceptions)
|
50
46
|
return if invalid_exceptions.empty?
|
51
47
|
|
52
48
|
add_offense(
|
53
|
-
node.loc.keyword.join(
|
49
|
+
node.loc.keyword.join(node.children.first.source_range),
|
54
50
|
message: format(MSG, invalid_exceptions: invalid_exceptions.map(&:source).join(', '))
|
55
51
|
) do |corrector|
|
56
52
|
autocorrect(corrector, node)
|
@@ -58,7 +54,7 @@ module RuboCop
|
|
58
54
|
end
|
59
55
|
|
60
56
|
def autocorrect(corrector, node)
|
61
|
-
rescued
|
57
|
+
rescued = node.children.first
|
62
58
|
range = node.loc.keyword.end.join(rescued.source_range.end)
|
63
59
|
|
64
60
|
corrector.replace(range, correction(*rescued))
|
@@ -32,25 +32,23 @@ module RuboCop
|
|
32
32
|
class ReturnInVoidContext < Base
|
33
33
|
MSG = 'Do not return a value in `%<method>s`.'
|
34
34
|
|
35
|
+
# Returning out of these methods only exits the block itself.
|
36
|
+
SCOPE_CHANGING_METHODS = %i[lambda define_method define_singleton_method].freeze
|
37
|
+
|
35
38
|
def on_return(return_node)
|
36
39
|
return unless return_node.descendants.any?
|
37
40
|
|
38
|
-
|
39
|
-
|
40
|
-
return
|
41
|
-
|
41
|
+
def_node = return_node.each_ancestor(:any_def).first
|
42
|
+
return unless def_node&.void_context?
|
43
|
+
return if return_node.each_ancestor(:any_block).any? do |block_node|
|
44
|
+
SCOPE_CHANGING_METHODS.include?(block_node.method_name)
|
45
|
+
end
|
42
46
|
|
43
47
|
add_offense(
|
44
48
|
return_node.loc.keyword,
|
45
|
-
message: format(message, method:
|
49
|
+
message: format(message, method: def_node.method_name)
|
46
50
|
)
|
47
51
|
end
|
48
|
-
|
49
|
-
private
|
50
|
-
|
51
|
-
def non_void_context(return_node)
|
52
|
-
return_node.each_ancestor(:block, :def, :defs).first
|
53
|
-
end
|
54
52
|
end
|
55
53
|
end
|
56
54
|
end
|
@@ -33,11 +33,13 @@ module RuboCop
|
|
33
33
|
def_node_matcher :bad_method?, <<~PATTERN
|
34
34
|
{
|
35
35
|
(send $(csend ...) $_ ...)
|
36
|
-
(send $(
|
36
|
+
(send $(any_block (csend ...) ...) $_ ...)
|
37
37
|
}
|
38
38
|
PATTERN
|
39
39
|
|
40
40
|
def on_send(node)
|
41
|
+
return unless require_safe_navigation?(node)
|
42
|
+
|
41
43
|
bad_method?(node) do |safe_nav, method|
|
42
44
|
return if nil_methods.include?(method) || PLUS_MINUS_METHODS.include?(node.method_name)
|
43
45
|
|
@@ -52,6 +54,13 @@ module RuboCop
|
|
52
54
|
|
53
55
|
private
|
54
56
|
|
57
|
+
def require_safe_navigation?(node)
|
58
|
+
parent = node.parent
|
59
|
+
return true unless parent&.and_type?
|
60
|
+
|
61
|
+
parent.rhs != node || parent.lhs.receiver != parent.rhs.receiver
|
62
|
+
end
|
63
|
+
|
55
64
|
# @param [Parser::Source::Range] offense_range
|
56
65
|
# @param [RuboCop::AST::SendNode] send_node
|
57
66
|
# @return [String]
|
@@ -88,12 +97,19 @@ module RuboCop
|
|
88
97
|
end
|
89
98
|
|
90
99
|
def require_parentheses?(send_node)
|
100
|
+
return true if operator_inside_hash?(send_node)
|
91
101
|
return false unless send_node.comparison_method?
|
92
102
|
return false unless (node = send_node.parent)
|
93
103
|
|
94
104
|
(node.respond_to?(:logical_operator?) && node.logical_operator?) ||
|
95
105
|
(node.respond_to?(:comparison_method?) && node.comparison_method?)
|
96
106
|
end
|
107
|
+
|
108
|
+
def operator_inside_hash?(send_node)
|
109
|
+
# If an operator call (without a dot) is inside a hash, it needs
|
110
|
+
# to be parenthesized when converted to safe navigation.
|
111
|
+
send_node.parent&.pair_type? && !send_node.loc.dot
|
112
|
+
end
|
97
113
|
end
|
98
114
|
end
|
99
115
|
end
|
@@ -83,6 +83,8 @@ module RuboCop
|
|
83
83
|
def find_consistent_parts(grouped_operands)
|
84
84
|
csend_in_and, csend_in_or, send_in_and, send_in_or = most_left_indices(grouped_operands)
|
85
85
|
|
86
|
+
return if csend_in_and && csend_in_or && csend_in_and < csend_in_or
|
87
|
+
|
86
88
|
if csend_in_and
|
87
89
|
['.', (send_in_and ? [send_in_and, csend_in_and].min : csend_in_and) + 1]
|
88
90
|
elsif send_in_or && csend_in_or
|
@@ -94,7 +96,9 @@ module RuboCop
|
|
94
96
|
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
95
97
|
|
96
98
|
def already_appropriate_call?(operand, dot_op)
|
97
|
-
|
99
|
+
return true if operand.safe_navigation? && dot_op == '&.'
|
100
|
+
|
101
|
+
(operand.dot? || operand.operator_method?) && dot_op == '.'
|
98
102
|
end
|
99
103
|
|
100
104
|
def register_offense(operand, dot_operator)
|
@@ -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|
|
@@ -8,6 +8,11 @@ module RuboCop
|
|
8
8
|
# given by `ruby -cw` prior to Ruby 2.6:
|
9
9
|
# "shadowing outer local variable - foo".
|
10
10
|
#
|
11
|
+
# The cop is now disabled by default to match the upstream Ruby behavior.
|
12
|
+
# It's useful, however, if you'd like to avoid shadowing variables from outer
|
13
|
+
# scopes, which some people consider an anti-pattern that makes it harder
|
14
|
+
# to keep track of what's going on in a program.
|
15
|
+
#
|
11
16
|
# NOTE: Shadowing of variables in block passed to `Ractor.new` is allowed
|
12
17
|
# because `Ractor` should not access outer variables.
|
13
18
|
# eg. following style is encouraged:
|
@@ -56,19 +61,26 @@ module RuboCop
|
|
56
61
|
|
57
62
|
outer_local_variable = variable_table.find_variable(variable.name)
|
58
63
|
return unless outer_local_variable
|
64
|
+
return if variable_used_in_declaration_of_outer?(variable, outer_local_variable)
|
59
65
|
return if same_conditions_node_different_branch?(variable, outer_local_variable)
|
60
66
|
|
61
67
|
message = format(MSG, variable: variable.name)
|
62
68
|
add_offense(variable.declaration_node, message: message)
|
63
69
|
end
|
64
70
|
|
71
|
+
private
|
72
|
+
|
73
|
+
def variable_used_in_declaration_of_outer?(variable, outer_local_variable)
|
74
|
+
variable.scope.node.each_ancestor.any?(outer_local_variable.declaration_node)
|
75
|
+
end
|
76
|
+
|
65
77
|
def same_conditions_node_different_branch?(variable, outer_local_variable)
|
66
78
|
variable_node = variable_node(variable)
|
67
79
|
return false unless node_or_its_ascendant_conditional?(variable_node)
|
68
80
|
|
69
81
|
outer_local_variable_node =
|
70
82
|
find_conditional_node_from_ascendant(outer_local_variable.declaration_node)
|
71
|
-
return
|
83
|
+
return false unless outer_local_variable_node
|
72
84
|
return false unless outer_local_variable_node.conditional?
|
73
85
|
return true if variable_node == outer_local_variable_node
|
74
86
|
|
@@ -0,0 +1,76 @@
|
|
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
|
+
{
|
55
|
+
(send (const {nil? cbase} :Hash) :new [
|
56
|
+
{array hash (send (const {nil? cbase} {:Array :Hash}) :new)}
|
57
|
+
!#capacity_keyword_argument?
|
58
|
+
])
|
59
|
+
(send (const {nil? cbase} :Hash) :new hash #capacity_keyword_argument?)
|
60
|
+
}
|
61
|
+
PATTERN
|
62
|
+
|
63
|
+
# @!method capacity_keyword_argument?(node)
|
64
|
+
def_node_matcher :capacity_keyword_argument?, <<~PATTERN
|
65
|
+
(hash (pair (sym :capacity) _))
|
66
|
+
PATTERN
|
67
|
+
|
68
|
+
def on_send(node)
|
69
|
+
return unless hash_initialized_with_mutable_shared_object?(node)
|
70
|
+
|
71
|
+
add_offense(node)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
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, :
|
119
|
+
ancestor = node.each_ancestor(:kwbegin, :any_def, :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}\"")
|
@@ -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
|
@@ -40,7 +40,7 @@ module RuboCop
|
|
40
40
|
# top-level return node's ancestors should not be of block, def, or
|
41
41
|
# defs type.
|
42
42
|
def top_level_return?(return_node)
|
43
|
-
return_node.each_ancestor(:block, :
|
43
|
+
return_node.each_ancestor(:block, :any_def).none?
|
44
44
|
end
|
45
45
|
end
|
46
46
|
end
|
@@ -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
|
@@ -53,6 +53,7 @@ module RuboCop
|
|
53
53
|
end
|
54
54
|
|
55
55
|
alias on_numblock on_block
|
56
|
+
alias on_itblock on_block
|
56
57
|
|
57
58
|
private
|
58
59
|
|
@@ -74,6 +75,7 @@ module RuboCop
|
|
74
75
|
|
75
76
|
def arg_count(node)
|
76
77
|
return node.children[1] if node.numblock_type? # the maximum numbered param for the block
|
78
|
+
return 1 if node.itblock_type? # `it` block parameter is always one
|
77
79
|
|
78
80
|
# Only `arg`, `optarg` and `mlhs` (destructuring) count as arguments that
|
79
81
|
# can be used. Keyword arguments are not used for these methods so are
|
@@ -81,7 +83,7 @@ module RuboCop
|
|
81
83
|
node.arguments.count do |arg|
|
82
84
|
return Float::INFINITY if arg.restarg_type?
|
83
85
|
|
84
|
-
arg.
|
86
|
+
arg.type?(:arg, :optarg, :mlhs)
|
85
87
|
end
|
86
88
|
end
|
87
89
|
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
|