rubocop 1.79.2 → 1.87.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/LICENSE.txt +1 -1
- data/README.md +2 -2
- data/config/default.yml +185 -20
- data/config/obsoletion.yml +9 -0
- data/exe/rubocop +1 -8
- data/lib/rubocop/cache_config.rb +29 -0
- data/lib/rubocop/cli/command/auto_generate_config.rb +30 -4
- data/lib/rubocop/cli/command/list_enabled_cops_for.rb +40 -0
- data/lib/rubocop/cli/command/lsp.rb +1 -1
- data/lib/rubocop/cli/command/mcp.rb +19 -0
- data/lib/rubocop/cli/command/show_cops.rb +2 -2
- data/lib/rubocop/cli/command/show_docs_url.rb +4 -8
- data/lib/rubocop/cli/command/suggest_extensions.rb +1 -1
- data/lib/rubocop/cli.rb +35 -9
- data/lib/rubocop/comment_config.rb +59 -17
- data/lib/rubocop/config.rb +14 -10
- data/lib/rubocop/config_finder.rb +1 -1
- data/lib/rubocop/config_loader.rb +37 -23
- data/lib/rubocop/config_loader_resolver.rb +20 -10
- data/lib/rubocop/config_obsoletion/extracted_cop.rb +4 -2
- data/lib/rubocop/config_store.rb +7 -2
- data/lib/rubocop/config_validator.rb +1 -1
- data/lib/rubocop/cop/autocorrect_logic.rb +10 -5
- data/lib/rubocop/cop/base.rb +8 -2
- data/lib/rubocop/cop/bundler/gem_version.rb +28 -28
- data/lib/rubocop/cop/bundler/ordered_gems.rb +1 -2
- data/lib/rubocop/cop/correctors/alignment_corrector.rb +26 -7
- data/lib/rubocop/cop/correctors/condition_corrector.rb +1 -1
- data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +7 -2
- data/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +1 -5
- data/lib/rubocop/cop/correctors/parentheses_corrector.rb +33 -2
- data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +2 -2
- data/lib/rubocop/cop/correctors.rb +28 -0
- data/lib/rubocop/cop/documentation.rb +2 -3
- data/lib/rubocop/cop/exclude_limit.rb +31 -5
- data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +2 -2
- data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +1 -2
- data/lib/rubocop/cop/gemspec/require_mfa.rb +5 -5
- data/lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb +12 -7
- data/lib/rubocop/cop/internal_affairs/example_heredoc_delimiter.rb +8 -8
- data/lib/rubocop/cop/internal_affairs/itblock_handler.rb +69 -0
- data/lib/rubocop/cop/internal_affairs/location_exists.rb +28 -2
- data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +1 -0
- data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +9 -9
- data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_processor.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/node_pattern_groups.rb +3 -1
- data/lib/rubocop/cop/internal_affairs/on_send_without_on_csend.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +4 -4
- data/lib/rubocop/cop/internal_affairs.rb +1 -0
- data/lib/rubocop/cop/layout/argument_alignment.rb +2 -2
- data/lib/rubocop/cop/layout/array_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/begin_end_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/case_indentation.rb +3 -1
- data/lib/rubocop/cop/layout/class_structure.rb +14 -7
- data/lib/rubocop/cop/layout/dot_position.rb +2 -2
- data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +26 -7
- data/lib/rubocop/cop/layout/empty_line_between_defs.rb +31 -13
- data/lib/rubocop/cop/layout/empty_lines_after_module_inclusion.rb +2 -2
- data/lib/rubocop/cop/layout/empty_lines_around_attribute_accessor.rb +1 -0
- data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +12 -2
- data/lib/rubocop/cop/layout/empty_lines_around_class_body.rb +16 -2
- data/lib/rubocop/cop/layout/empty_lines_around_module_body.rb +16 -2
- data/lib/rubocop/cop/layout/end_alignment.rb +10 -3
- data/lib/rubocop/cop/layout/first_argument_indentation.rb +34 -1
- data/lib/rubocop/cop/layout/first_array_element_line_break.rb +26 -0
- data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +7 -1
- data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +25 -25
- data/lib/rubocop/cop/layout/hash_alignment.rb +3 -6
- data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +2 -2
- data/lib/rubocop/cop/layout/heredoc_indentation.rb +33 -3
- data/lib/rubocop/cop/layout/indentation_style.rb +1 -1
- data/lib/rubocop/cop/layout/indentation_width.rb +123 -7
- data/lib/rubocop/cop/layout/line_continuation_spacing.rb +1 -1
- data/lib/rubocop/cop/layout/line_length.rb +26 -9
- data/lib/rubocop/cop/layout/multiline_array_brace_layout.rb +57 -57
- data/lib/rubocop/cop/layout/multiline_assignment_layout.rb +9 -2
- data/lib/rubocop/cop/layout/multiline_block_layout.rb +2 -0
- data/lib/rubocop/cop/layout/multiline_hash_brace_layout.rb +56 -56
- data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +1 -1
- data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +229 -39
- data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +8 -4
- data/lib/rubocop/cop/layout/parameter_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/redundant_line_break.rb +3 -1
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +13 -3
- data/lib/rubocop/cop/layout/space_after_comma.rb +2 -10
- data/lib/rubocop/cop/layout/space_after_semicolon.rb +1 -1
- data/lib/rubocop/cop/layout/space_around_block_parameters.rb +1 -1
- data/lib/rubocop/cop/layout/space_around_keyword.rb +4 -2
- data/lib/rubocop/cop/layout/space_before_brackets.rb +1 -1
- data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +9 -8
- data/lib/rubocop/cop/layout/trailing_whitespace.rb +1 -1
- data/lib/rubocop/cop/lint/ambiguous_block_association.rb +1 -1
- data/lib/rubocop/cop/lint/circular_argument_reference.rb +47 -3
- data/lib/rubocop/cop/lint/constant_overwritten_in_rescue.rb +4 -3
- data/lib/rubocop/cop/lint/constant_reassignment.rb +93 -11
- data/lib/rubocop/cop/lint/constant_resolution.rb +6 -6
- data/lib/rubocop/cop/lint/cop_directive_syntax.rb +14 -8
- data/lib/rubocop/cop/lint/data_define_override.rb +63 -0
- data/lib/rubocop/cop/lint/debugger.rb +0 -2
- data/lib/rubocop/cop/lint/deprecated_constants.rb +1 -1
- data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +4 -1
- data/lib/rubocop/cop/lint/duplicate_match_pattern.rb +4 -4
- data/lib/rubocop/cop/lint/duplicate_methods.rb +111 -12
- data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +5 -42
- data/lib/rubocop/cop/lint/else_layout.rb +19 -0
- data/lib/rubocop/cop/lint/empty_block.rb +1 -1
- data/lib/rubocop/cop/lint/empty_conditional_body.rb +6 -1
- data/lib/rubocop/cop/lint/empty_in_pattern.rb +8 -1
- data/lib/rubocop/cop/lint/empty_interpolation.rb +11 -0
- data/lib/rubocop/cop/lint/empty_when.rb +8 -1
- data/lib/rubocop/cop/lint/erb_new_arguments.rb +1 -1
- data/lib/rubocop/cop/lint/float_comparison.rb +1 -1
- data/lib/rubocop/cop/lint/interpolation_check.rb +7 -2
- data/lib/rubocop/cop/lint/literal_as_condition.rb +5 -1
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +1 -1
- data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +18 -9
- data/lib/rubocop/cop/lint/multiple_comparison.rb +2 -2
- data/lib/rubocop/cop/lint/next_without_accumulator.rb +2 -0
- data/lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +4 -0
- data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +4 -2
- data/lib/rubocop/cop/lint/number_conversion.rb +6 -6
- data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +1 -1
- data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +3 -13
- data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +23 -9
- data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +2 -11
- data/lib/rubocop/cop/lint/redundant_require_statement.rb +4 -2
- data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +23 -6
- data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +8 -2
- data/lib/rubocop/cop/lint/redundant_type_conversion.rb +3 -3
- data/lib/rubocop/cop/lint/require_relative_self_path.rb +3 -1
- data/lib/rubocop/cop/lint/rescue_exception.rb +1 -4
- data/lib/rubocop/cop/lint/safe_navigation_chain.rb +17 -0
- data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +7 -1
- data/lib/rubocop/cop/lint/self_assignment.rb +15 -6
- data/lib/rubocop/cop/lint/shadowed_argument.rb +7 -7
- data/lib/rubocop/cop/lint/shadowed_exception.rb +1 -1
- data/lib/rubocop/cop/lint/struct_new_override.rb +17 -1
- data/lib/rubocop/cop/lint/syntax.rb +25 -1
- data/lib/rubocop/cop/lint/to_json.rb +12 -16
- data/lib/rubocop/cop/lint/trailing_comma_in_attribute_declaration.rb +1 -0
- data/lib/rubocop/cop/lint/unescaped_bracket_in_regexp.rb +1 -1
- data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +1 -0
- data/lib/rubocop/cop/lint/unreachable_code.rb +7 -5
- data/lib/rubocop/cop/lint/unreachable_pattern_branch.rb +113 -0
- data/lib/rubocop/cop/lint/unused_method_argument.rb +10 -0
- data/lib/rubocop/cop/lint/uri_escape_unescape.rb +2 -0
- data/lib/rubocop/cop/lint/useless_assignment.rb +48 -25
- data/lib/rubocop/cop/lint/useless_constant_scoping.rb +4 -4
- data/lib/rubocop/cop/lint/useless_default_value_argument.rb +2 -0
- data/lib/rubocop/cop/lint/useless_or.rb +15 -2
- data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +1 -1
- data/lib/rubocop/cop/lint/utils/nil_receiver_checker.rb +37 -11
- data/lib/rubocop/cop/lint/void.rb +39 -12
- data/lib/rubocop/cop/message_annotator.rb +1 -1
- data/lib/rubocop/cop/metrics/block_length.rb +1 -1
- data/lib/rubocop/cop/metrics/block_nesting.rb +23 -0
- data/lib/rubocop/cop/metrics/method_length.rb +1 -1
- data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +4 -3
- data/lib/rubocop/cop/metrics/utils/iterating_block.rb +1 -1
- data/lib/rubocop/cop/migration/department_name.rb +12 -1
- data/lib/rubocop/cop/mixin/check_line_breakable.rb +2 -2
- data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +4 -6
- data/lib/rubocop/cop/mixin/code_length.rb +1 -1
- data/lib/rubocop/cop/mixin/configurable_max.rb +6 -5
- data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +1 -7
- data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +5 -5
- data/lib/rubocop/cop/mixin/hash_transform_method/autocorrection.rb +63 -0
- data/lib/rubocop/cop/mixin/hash_transform_method.rb +10 -60
- data/lib/rubocop/cop/mixin/line_length_help.rb +21 -2
- data/lib/rubocop/cop/mixin/method_complexity.rb +1 -1
- data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +1 -1
- data/lib/rubocop/cop/mixin/multiline_literal_brace_layout.rb +1 -1
- data/lib/rubocop/cop/mixin/project_index_help.rb +48 -0
- data/lib/rubocop/cop/mixin/space_after_punctuation.rb +5 -4
- data/lib/rubocop/cop/mixin/statement_modifier.rb +0 -6
- data/lib/rubocop/cop/mixin/trailing_comma.rb +8 -5
- data/lib/rubocop/cop/mixin.rb +86 -0
- data/lib/rubocop/cop/naming/binary_operator_parameter_name.rb +1 -1
- data/lib/rubocop/cop/naming/block_parameter_name.rb +1 -1
- data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +1 -1
- data/lib/rubocop/cop/naming/method_name.rb +5 -3
- data/lib/rubocop/cop/naming/predicate_method.rb +32 -8
- data/lib/rubocop/cop/naming/predicate_prefix.rb +12 -12
- data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +1 -1
- data/lib/rubocop/cop/offense.rb +17 -1
- data/lib/rubocop/cop/registry.rb +62 -38
- data/lib/rubocop/cop/security/eval.rb +15 -2
- data/lib/rubocop/cop/security/io_methods.rb +1 -1
- data/lib/rubocop/cop/security/json_load.rb +33 -11
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +15 -4
- data/lib/rubocop/cop/style/accessor_grouping.rb +4 -2
- data/lib/rubocop/cop/style/alias.rb +14 -2
- data/lib/rubocop/cop/style/and_or.rb +1 -0
- data/lib/rubocop/cop/style/arguments_forwarding.rb +25 -7
- data/lib/rubocop/cop/style/array_intersect.rb +46 -12
- data/lib/rubocop/cop/style/array_intersect_with_single_element.rb +47 -0
- data/lib/rubocop/cop/style/array_join.rb +4 -2
- data/lib/rubocop/cop/style/ascii_comments.rb +6 -3
- data/lib/rubocop/cop/style/attr.rb +5 -2
- data/lib/rubocop/cop/style/bare_percent_literals.rb +4 -3
- data/lib/rubocop/cop/style/begin_block.rb +3 -1
- data/lib/rubocop/cop/style/bitwise_predicate.rb +8 -1
- data/lib/rubocop/cop/style/block_delimiters.rb +27 -34
- data/lib/rubocop/cop/style/case_equality.rb +15 -13
- data/lib/rubocop/cop/style/character_literal.rb +2 -2
- data/lib/rubocop/cop/style/class_and_module_children.rb +19 -2
- data/lib/rubocop/cop/style/collection_compact.rb +36 -16
- data/lib/rubocop/cop/style/colon_method_call.rb +3 -1
- data/lib/rubocop/cop/style/concat_array_literals.rb +2 -0
- data/lib/rubocop/cop/style/conditional_assignment.rb +8 -18
- data/lib/rubocop/cop/style/constant_visibility.rb +17 -12
- data/lib/rubocop/cop/style/copyright.rb +22 -11
- data/lib/rubocop/cop/style/date_time.rb +2 -2
- data/lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb +1 -1
- data/lib/rubocop/cop/style/document_dynamic_eval_definition.rb +6 -1
- data/lib/rubocop/cop/style/documentation.rb +6 -6
- data/lib/rubocop/cop/style/documentation_method.rb +8 -8
- data/lib/rubocop/cop/style/double_negation.rb +1 -1
- data/lib/rubocop/cop/style/each_for_simple_loop.rb +1 -1
- data/lib/rubocop/cop/style/each_with_object.rb +2 -0
- data/lib/rubocop/cop/style/empty_block_parameter.rb +1 -1
- data/lib/rubocop/cop/style/empty_class_definition.rb +119 -0
- data/lib/rubocop/cop/style/empty_lambda_parameter.rb +1 -1
- data/lib/rubocop/cop/style/empty_method.rb +0 -6
- data/lib/rubocop/cop/style/encoding.rb +7 -1
- data/lib/rubocop/cop/style/end_block.rb +3 -1
- data/lib/rubocop/cop/style/endless_method.rb +23 -5
- data/lib/rubocop/cop/style/explicit_block_argument.rb +1 -1
- data/lib/rubocop/cop/style/file_open.rb +84 -0
- data/lib/rubocop/cop/style/file_write.rb +18 -16
- data/lib/rubocop/cop/style/float_division.rb +15 -1
- data/lib/rubocop/cop/style/for.rb +3 -0
- data/lib/rubocop/cop/style/format_string.rb +4 -3
- data/lib/rubocop/cop/style/format_string_token.rb +49 -5
- data/lib/rubocop/cop/style/global_vars.rb +5 -2
- data/lib/rubocop/cop/style/guard_clause.rb +27 -22
- data/lib/rubocop/cop/style/hash_as_last_array_item.rb +27 -9
- data/lib/rubocop/cop/style/hash_conversion.rb +1 -1
- data/lib/rubocop/cop/style/hash_lookup_method.rb +106 -0
- data/lib/rubocop/cop/style/hash_syntax.rb +1 -1
- data/lib/rubocop/cop/style/hash_transform_keys.rb +17 -7
- data/lib/rubocop/cop/style/hash_transform_values.rb +17 -7
- data/lib/rubocop/cop/style/if_inside_else.rb +16 -7
- data/lib/rubocop/cop/style/if_unless_modifier.rb +57 -17
- data/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +12 -12
- data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +4 -1
- 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/inline_comment.rb +4 -1
- data/lib/rubocop/cop/style/ip_addresses.rb +1 -2
- data/lib/rubocop/cop/style/lambda_call.rb +8 -8
- data/lib/rubocop/cop/style/magic_comment_format.rb +3 -3
- data/lib/rubocop/cop/style/map_join.rb +123 -0
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/require_parentheses.rb +15 -2
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +17 -4
- data/lib/rubocop/cop/style/method_def_parentheses.rb +2 -4
- data/lib/rubocop/cop/style/min_max_comparison.rb +1 -1
- data/lib/rubocop/cop/style/module_member_existence_check.rb +110 -0
- data/lib/rubocop/cop/style/multiline_if_then.rb +4 -4
- data/lib/rubocop/cop/style/multiline_method_signature.rb +2 -4
- data/lib/rubocop/cop/style/mutable_constant.rb +1 -1
- data/lib/rubocop/cop/style/negative_array_index.rb +220 -0
- data/lib/rubocop/cop/style/nil_comparison.rb +11 -10
- data/lib/rubocop/cop/style/nil_lambda.rb +1 -1
- data/lib/rubocop/cop/style/non_nil_check.rb +5 -11
- data/lib/rubocop/cop/style/not.rb +2 -0
- data/lib/rubocop/cop/style/numeric_literals.rb +3 -2
- data/lib/rubocop/cop/style/one_class_per_file.rb +115 -0
- data/lib/rubocop/cop/style/one_line_conditional.rb +21 -12
- data/lib/rubocop/cop/style/operator_method_call.rb +11 -2
- data/lib/rubocop/cop/style/parallel_assignment.rb +6 -2
- data/lib/rubocop/cop/style/partition_instead_of_double_select.rb +270 -0
- data/lib/rubocop/cop/style/percent_literal_delimiters.rb +2 -0
- data/lib/rubocop/cop/style/predicate_with_kind.rb +84 -0
- data/lib/rubocop/cop/style/preferred_hash_methods.rb +12 -12
- data/lib/rubocop/cop/style/proc.rb +3 -2
- data/lib/rubocop/cop/style/raise_args.rb +1 -1
- data/lib/rubocop/cop/style/reduce_to_hash.rb +200 -0
- data/lib/rubocop/cop/style/redundant_argument.rb +2 -0
- data/lib/rubocop/cop/style/redundant_array_constructor.rb +2 -2
- data/lib/rubocop/cop/style/redundant_begin.rb +37 -3
- data/lib/rubocop/cop/style/redundant_condition.rb +6 -3
- data/lib/rubocop/cop/style/redundant_constant_base.rb +5 -5
- data/lib/rubocop/cop/style/redundant_each.rb +3 -3
- data/lib/rubocop/cop/style/redundant_exception.rb +1 -1
- data/lib/rubocop/cop/style/redundant_fetch_block.rb +1 -1
- data/lib/rubocop/cop/style/redundant_format.rb +26 -5
- data/lib/rubocop/cop/style/redundant_interpolation.rb +11 -2
- data/lib/rubocop/cop/style/redundant_interpolation_unfreeze.rb +26 -10
- data/lib/rubocop/cop/style/redundant_line_continuation.rb +16 -0
- data/lib/rubocop/cop/style/redundant_min_max_by.rb +93 -0
- data/lib/rubocop/cop/style/redundant_parentheses.rb +36 -30
- data/lib/rubocop/cop/style/redundant_percent_q.rb +5 -3
- data/lib/rubocop/cop/style/redundant_regexp_argument.rb +9 -0
- data/lib/rubocop/cop/style/redundant_regexp_constructor.rb +2 -2
- data/lib/rubocop/cop/style/redundant_regexp_escape.rb +8 -0
- data/lib/rubocop/cop/style/redundant_return.rb +3 -1
- data/lib/rubocop/cop/style/redundant_self.rb +2 -2
- data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +0 -5
- data/lib/rubocop/cop/style/redundant_sort.rb +7 -7
- data/lib/rubocop/cop/style/redundant_struct_keyword_init.rb +114 -0
- data/lib/rubocop/cop/style/regexp_literal.rb +31 -2
- data/lib/rubocop/cop/style/rescue_modifier.rb +3 -3
- data/lib/rubocop/cop/style/reverse_find.rb +51 -0
- data/lib/rubocop/cop/style/safe_navigation.rb +25 -8
- data/lib/rubocop/cop/style/select_by_kind.rb +158 -0
- data/lib/rubocop/cop/style/select_by_range.rb +197 -0
- data/lib/rubocop/cop/style/select_by_regexp.rb +51 -21
- data/lib/rubocop/cop/style/self_assignment.rb +1 -1
- data/lib/rubocop/cop/style/semicolon.rb +25 -7
- data/lib/rubocop/cop/style/single_line_block_params.rb +2 -2
- data/lib/rubocop/cop/style/single_line_do_end_block.rb +1 -1
- data/lib/rubocop/cop/style/single_line_methods.rb +3 -1
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +12 -3
- data/lib/rubocop/cop/style/special_global_vars.rb +6 -1
- data/lib/rubocop/cop/style/string_concatenation.rb +17 -13
- data/lib/rubocop/cop/style/struct_inheritance.rb +13 -0
- data/lib/rubocop/cop/style/super_arguments.rb +2 -2
- data/lib/rubocop/cop/style/symbol_array.rb +1 -1
- data/lib/rubocop/cop/style/symbol_proc.rb +7 -6
- data/lib/rubocop/cop/style/tally_method.rb +181 -0
- data/lib/rubocop/cop/style/top_level_method_definition.rb +2 -2
- data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +45 -0
- data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +1 -1
- data/lib/rubocop/cop/style/trailing_method_end_statement.rb +1 -0
- data/lib/rubocop/cop/style/trailing_underscore_variable.rb +11 -11
- data/lib/rubocop/cop/style/unless_else.rb +10 -9
- data/lib/rubocop/cop/style/unless_logical_operators.rb +3 -3
- data/lib/rubocop/cop/style/while_until_modifier.rb +16 -0
- data/lib/rubocop/cop/style/yoda_condition.rb +1 -1
- data/lib/rubocop/cop/style/yoda_expression.rb +1 -1
- data/lib/rubocop/cop/team.rb +87 -36
- data/lib/rubocop/cop/util.rb +2 -3
- data/lib/rubocop/cop/utils/format_string.rb +10 -0
- data/lib/rubocop/cop/variable_force/branch.rb +30 -6
- data/lib/rubocop/cop/variable_force/variable.rb +1 -1
- data/lib/rubocop/cop/variable_force.rb +9 -7
- data/lib/rubocop/cops_documentation_generator.rb +4 -4
- data/lib/rubocop/directive_comment.rb +48 -4
- data/lib/rubocop/file_patterns.rb +9 -1
- data/lib/rubocop/formatter/clang_style_formatter.rb +5 -2
- data/lib/rubocop/formatter/disabled_config_formatter.rb +24 -7
- data/lib/rubocop/formatter/formatter_set.rb +2 -2
- data/lib/rubocop/formatter/junit_formatter.rb +1 -1
- data/lib/rubocop/formatter/simple_text_formatter.rb +0 -2
- data/lib/rubocop/formatter/tap_formatter.rb +5 -2
- data/lib/rubocop/formatter/worst_offenders_formatter.rb +1 -1
- data/lib/rubocop/formatter.rb +22 -21
- data/lib/rubocop/lsp/diagnostic.rb +18 -33
- data/lib/rubocop/lsp/disable_comment_edits.rb +135 -0
- data/lib/rubocop/lsp/routes.rb +43 -7
- data/lib/rubocop/lsp/runtime.rb +13 -4
- data/lib/rubocop/lsp/stdin_runner.rb +8 -17
- data/lib/rubocop/magic_comment.rb +20 -0
- data/lib/rubocop/mcp/server.rb +200 -0
- data/lib/rubocop/options.rb +35 -4
- data/lib/rubocop/path_util.rb +14 -2
- data/lib/rubocop/plugin/loader.rb +1 -1
- data/lib/rubocop/project_index_loader.rb +66 -0
- data/lib/rubocop/rake_task.rb +1 -1
- data/lib/rubocop/remote_config.rb +10 -8
- data/lib/rubocop/result_cache.rb +61 -38
- data/lib/rubocop/rspec/cop_helper.rb +8 -0
- data/lib/rubocop/rspec/shared_contexts.rb +39 -5
- data/lib/rubocop/rspec/support.rb +2 -1
- data/lib/rubocop/runner.rb +134 -57
- data/lib/rubocop/server/cache.rb +6 -29
- data/lib/rubocop/server/core.rb +2 -0
- data/lib/rubocop/target_finder.rb +17 -10
- data/lib/rubocop/target_ruby.rb +31 -14
- data/lib/rubocop/version.rb +21 -3
- data/lib/rubocop.rb +28 -96
- data/lib/ruby_lsp/rubocop/addon.rb +23 -8
- data/lib/ruby_lsp/rubocop/runtime_adapter.rb +49 -15
- metadata +38 -9
|
@@ -64,7 +64,7 @@ module RuboCop
|
|
|
64
64
|
|
|
65
65
|
MSG = 'Convert `if` nested inside `else` to `elsif`.'
|
|
66
66
|
|
|
67
|
-
# rubocop:disable Metrics/CyclomaticComplexity
|
|
67
|
+
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
68
68
|
def on_if(node)
|
|
69
69
|
return if node.ternary? || node.unless?
|
|
70
70
|
|
|
@@ -72,6 +72,7 @@ module RuboCop
|
|
|
72
72
|
|
|
73
73
|
return unless else_branch&.if_type? && else_branch.if?
|
|
74
74
|
return if allow_if_modifier_in_else_branch?(else_branch)
|
|
75
|
+
return if comments_between_else_and_if?(node, else_branch)
|
|
75
76
|
|
|
76
77
|
add_offense(else_branch.loc.keyword) do |corrector|
|
|
77
78
|
next if part_of_ignored_node?(node)
|
|
@@ -80,12 +81,12 @@ module RuboCop
|
|
|
80
81
|
ignore_node(node)
|
|
81
82
|
end
|
|
82
83
|
end
|
|
83
|
-
# rubocop:enable Metrics/CyclomaticComplexity
|
|
84
|
+
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
84
85
|
|
|
85
86
|
private
|
|
86
87
|
|
|
87
88
|
def autocorrect(corrector, node)
|
|
88
|
-
if then?
|
|
89
|
+
if node.then?
|
|
89
90
|
# If the nested `if` is a then node, correct it first,
|
|
90
91
|
# then the next pass will use `correct_to_elsif_from_if_inside_else_form`
|
|
91
92
|
IfThenCorrector.new(node, indentation: 0).call(corrector)
|
|
@@ -124,10 +125,6 @@ module RuboCop
|
|
|
124
125
|
corrector.remove(range_by_whole_lines(find_end_range(node), include_final_newline: true))
|
|
125
126
|
end
|
|
126
127
|
|
|
127
|
-
def then?(node)
|
|
128
|
-
node.loc.begin&.source == 'then'
|
|
129
|
-
end
|
|
130
|
-
|
|
131
128
|
def find_end_range(node)
|
|
132
129
|
end_range = node.loc.end
|
|
133
130
|
return end_range if end_range
|
|
@@ -139,6 +136,18 @@ module RuboCop
|
|
|
139
136
|
range_between(node.loc.keyword.begin_pos, condition.source_range.end_pos)
|
|
140
137
|
end
|
|
141
138
|
|
|
139
|
+
def comments_between_else_and_if?(node, else_branch)
|
|
140
|
+
return false if else_branch.modifier_form?
|
|
141
|
+
|
|
142
|
+
else_end = node.loc.else.end_pos
|
|
143
|
+
if_begin = else_branch.loc.keyword.begin_pos
|
|
144
|
+
|
|
145
|
+
processed_source.comments.any? do |comment|
|
|
146
|
+
comment_pos = comment.source_range.begin_pos
|
|
147
|
+
comment_pos > else_end && comment_pos < if_begin
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
|
|
142
151
|
def allow_if_modifier_in_else_branch?(else_branch)
|
|
143
152
|
allow_if_modifier? && else_branch&.modifier_form?
|
|
144
153
|
end
|
|
@@ -71,7 +71,8 @@ module RuboCop
|
|
|
71
71
|
# if short_condition # a long comment that makes it too long if it were just a single line
|
|
72
72
|
# do_something
|
|
73
73
|
# end
|
|
74
|
-
|
|
74
|
+
#
|
|
75
|
+
class IfUnlessModifier < Base # rubocop:disable Metrics/ClassLength
|
|
75
76
|
include StatementModifier
|
|
76
77
|
include LineLengthHelp
|
|
77
78
|
include AllowedPattern
|
|
@@ -88,9 +89,9 @@ module RuboCop
|
|
|
88
89
|
[Style::SoleNestedConditional]
|
|
89
90
|
end
|
|
90
91
|
|
|
91
|
-
# rubocop:disable Metrics/AbcSize
|
|
92
|
+
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
92
93
|
def on_if(node)
|
|
93
|
-
return if endless_method?(node.body)
|
|
94
|
+
return if endless_method?(node.body) || node.ancestors.any?(&:dstr_type?)
|
|
94
95
|
|
|
95
96
|
condition = node.condition
|
|
96
97
|
return if defined_nodes(condition).any? { |n| defined_argument_is_undefined?(node, n) } ||
|
|
@@ -100,12 +101,13 @@ module RuboCop
|
|
|
100
101
|
|
|
101
102
|
add_offense(node.loc.keyword, message: format(msg, keyword: node.keyword)) do |corrector|
|
|
102
103
|
next if part_of_ignored_node?(node)
|
|
104
|
+
next if another_modifier_if_on_same_line?(node)
|
|
103
105
|
|
|
104
106
|
autocorrect(corrector, node)
|
|
105
107
|
ignore_node(node)
|
|
106
108
|
end
|
|
107
109
|
end
|
|
108
|
-
# rubocop:enable Metrics/AbcSize
|
|
110
|
+
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
109
111
|
|
|
110
112
|
private
|
|
111
113
|
|
|
@@ -207,14 +209,14 @@ module RuboCop
|
|
|
207
209
|
def too_long_line_based_on_config?(range, line)
|
|
208
210
|
return false if matches_allowed_pattern?(line)
|
|
209
211
|
|
|
210
|
-
too_long =
|
|
212
|
+
too_long = too_long_line_based_on_allow_cop_directives?(range, line)
|
|
211
213
|
return too_long unless too_long == :undetermined
|
|
212
214
|
|
|
213
215
|
too_long_line_based_on_allow_uri?(line)
|
|
214
216
|
end
|
|
215
217
|
|
|
216
|
-
def
|
|
217
|
-
if
|
|
218
|
+
def too_long_line_based_on_allow_cop_directives?(range, line)
|
|
219
|
+
if allow_cop_directives? && directive_on_source_line?(range.line - 1)
|
|
218
220
|
return line_length_without_directive(line) > max_line_length
|
|
219
221
|
end
|
|
220
222
|
|
|
@@ -230,15 +232,6 @@ module RuboCop
|
|
|
230
232
|
true
|
|
231
233
|
end
|
|
232
234
|
|
|
233
|
-
def too_long_line_based_on_allow_qualified_name?(line)
|
|
234
|
-
if allow_qualified_name?
|
|
235
|
-
namespace_range = find_excessive_range(line, :namespace)
|
|
236
|
-
return false if namespace_range && allowed_position?(line, namespace_range)
|
|
237
|
-
end
|
|
238
|
-
|
|
239
|
-
true
|
|
240
|
-
end
|
|
241
|
-
|
|
242
235
|
def line_length_enabled_at_line?(line)
|
|
243
236
|
processed_source.comment_config.cop_enabled_at_line?('Layout/LineLength', line)
|
|
244
237
|
end
|
|
@@ -248,7 +241,54 @@ module RuboCop
|
|
|
248
241
|
end
|
|
249
242
|
|
|
250
243
|
def non_eligible_node?(node)
|
|
251
|
-
non_simple_if_unless?(node) || node.chained? || node.nested_conditional? ||
|
|
244
|
+
non_simple_if_unless?(node) || node.chained? || node.nested_conditional? ||
|
|
245
|
+
multiline_inside_collection?(node) || super
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
def multiline_inside_collection?(node)
|
|
249
|
+
return false if node.modifier_form?
|
|
250
|
+
return false unless (collection = find_containing_collection(node))
|
|
251
|
+
|
|
252
|
+
collection.children.any? { |child| sibling_if_shares_line?(child, node) }
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
def sibling_if_shares_line?(child, node)
|
|
256
|
+
inner = unwrap_begin(child)
|
|
257
|
+
inner&.if_type? && !inner.ternary? && shares_line_with?(inner, node)
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
def unwrap_begin(node)
|
|
261
|
+
return unless node.is_a?(RuboCop::AST::Node)
|
|
262
|
+
|
|
263
|
+
node = node.value if node.pair_type?
|
|
264
|
+
node.begin_type? ? node.children.first : node
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
def shares_line_with?(inner, node)
|
|
268
|
+
same_line?(inner, node.loc.end) || same_line?(inner.loc.end, node)
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
def find_containing_collection(node)
|
|
272
|
+
parent = node.parent
|
|
273
|
+
return collection_from_ancestor(parent) unless parent&.begin_type?
|
|
274
|
+
|
|
275
|
+
collection_from_ancestor(parent.parent)
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
def collection_from_ancestor(node)
|
|
279
|
+
return node if node&.type?(:array, :call)
|
|
280
|
+
|
|
281
|
+
node.parent if node&.type?(:pair)
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
def another_modifier_if_on_same_line?(node)
|
|
285
|
+
collection = find_containing_collection(node)
|
|
286
|
+
return false unless collection
|
|
287
|
+
|
|
288
|
+
line = node.source_range.line
|
|
289
|
+
collection.each_descendant(:if).any? do |sibling|
|
|
290
|
+
sibling != node && sibling.modifier_form? && sibling.source_range.line == line
|
|
291
|
+
end
|
|
252
292
|
end
|
|
253
293
|
|
|
254
294
|
def non_simple_if_unless?(node)
|
|
@@ -8,20 +8,20 @@ module RuboCop
|
|
|
8
8
|
#
|
|
9
9
|
# @example
|
|
10
10
|
#
|
|
11
|
-
#
|
|
12
|
-
#
|
|
11
|
+
# # bad
|
|
12
|
+
# tired? ? 'stop' : 'go faster' if running?
|
|
13
13
|
#
|
|
14
|
-
#
|
|
15
|
-
#
|
|
16
|
-
#
|
|
17
|
-
#
|
|
18
|
-
#
|
|
19
|
-
#
|
|
14
|
+
# # bad
|
|
15
|
+
# if tired?
|
|
16
|
+
# "please stop"
|
|
17
|
+
# else
|
|
18
|
+
# "keep going"
|
|
19
|
+
# end if running?
|
|
20
20
|
#
|
|
21
|
-
#
|
|
22
|
-
#
|
|
23
|
-
#
|
|
24
|
-
#
|
|
21
|
+
# # good
|
|
22
|
+
# if running?
|
|
23
|
+
# tired? ? 'stop' : 'go faster'
|
|
24
|
+
# end
|
|
25
25
|
class IfUnlessModifierOfIfUnless < Base
|
|
26
26
|
include StatementModifier
|
|
27
27
|
extend AutoCorrector
|
|
@@ -54,7 +54,10 @@ module RuboCop
|
|
|
54
54
|
# # good (but potentially an unsafe correction)
|
|
55
55
|
# foo.do_something?
|
|
56
56
|
#
|
|
57
|
-
# @example AllowedMethods: ['nonzero?'] (default)
|
|
57
|
+
# @example AllowedMethods: ['infinite?', 'nonzero?'] (default)
|
|
58
|
+
# # good
|
|
59
|
+
# num.infinite? ? true : false
|
|
60
|
+
#
|
|
58
61
|
# # good
|
|
59
62
|
# num.nonzero? ? true : false
|
|
60
63
|
#
|
|
@@ -17,9 +17,9 @@ module RuboCop
|
|
|
17
17
|
include OnNormalIfUnless
|
|
18
18
|
extend AutoCorrector
|
|
19
19
|
|
|
20
|
-
MSG_IF_ELSE = 'Do not use
|
|
21
|
-
MSG_NEWLINE = 'Do not use
|
|
22
|
-
MSG_TERNARY = 'Do not use
|
|
20
|
+
MSG_IF_ELSE = 'Do not use `%<keyword>s %<expr>s;` - use `if/else` instead.'
|
|
21
|
+
MSG_NEWLINE = 'Do not use `%<keyword>s %<expr>s;` - use a newline instead.'
|
|
22
|
+
MSG_TERNARY = 'Do not use `%<keyword>s %<expr>s;` - use a ternary operator instead.'
|
|
23
23
|
|
|
24
24
|
def on_normal_if_unless(node)
|
|
25
25
|
return if node.parent&.if_type?
|
|
@@ -49,7 +49,7 @@ module RuboCop
|
|
|
49
49
|
MSG_TERNARY
|
|
50
50
|
end
|
|
51
51
|
|
|
52
|
-
format(template, expr: node.condition.source)
|
|
52
|
+
format(template, keyword: node.keyword, expr: node.condition.source)
|
|
53
53
|
end
|
|
54
54
|
|
|
55
55
|
def autocorrect(corrector, node)
|
|
@@ -71,7 +71,7 @@ module RuboCop
|
|
|
71
71
|
end
|
|
72
72
|
|
|
73
73
|
def use_return_with_argument?(node)
|
|
74
|
-
node.
|
|
74
|
+
node.branches.compact.any? { |branch| branch.return_type? && branch.arguments.any? }
|
|
75
75
|
end
|
|
76
76
|
|
|
77
77
|
def replacement(node)
|
|
@@ -80,6 +80,8 @@ module RuboCop
|
|
|
80
80
|
then_code = node.if_branch ? build_expression(node.if_branch) : 'nil'
|
|
81
81
|
else_code = node.else_branch ? build_expression(node.else_branch) : 'nil'
|
|
82
82
|
|
|
83
|
+
then_code, else_code = else_code, then_code if node.unless?
|
|
84
|
+
|
|
83
85
|
"#{node.condition.source} ? #{then_code} : #{else_code}"
|
|
84
86
|
end
|
|
85
87
|
|
|
@@ -68,7 +68,7 @@ module RuboCop
|
|
|
68
68
|
end
|
|
69
69
|
|
|
70
70
|
def autocorrect(corrector, node)
|
|
71
|
-
if node.
|
|
71
|
+
if node.post_condition_loop?
|
|
72
72
|
replace_begin_end_with_modifier(corrector, node)
|
|
73
73
|
elsif node.modifier_form?
|
|
74
74
|
replace_source(corrector, node.source_range, modifier_replacement(node))
|
|
@@ -3,7 +3,10 @@
|
|
|
3
3
|
module RuboCop
|
|
4
4
|
module Cop
|
|
5
5
|
module Style
|
|
6
|
-
# Checks for trailing inline comments.
|
|
6
|
+
# Checks for trailing inline comments. Inline comments can
|
|
7
|
+
# make lines harder to read, especially when they are long.
|
|
8
|
+
# Placing comments on their own line above the code they
|
|
9
|
+
# describe is often clearer.
|
|
7
10
|
#
|
|
8
11
|
# @example
|
|
9
12
|
#
|
|
@@ -48,8 +48,7 @@ module RuboCop
|
|
|
48
48
|
private
|
|
49
49
|
|
|
50
50
|
def allowed_addresses
|
|
51
|
-
allowed_addresses
|
|
52
|
-
Array(allowed_addresses).map(&:downcase)
|
|
51
|
+
@allowed_addresses ||= Array(cop_config['AllowedAddresses']).map(&:downcase).freeze
|
|
53
52
|
end
|
|
54
53
|
|
|
55
54
|
def potential_ip?(str)
|
|
@@ -6,18 +6,18 @@ module RuboCop
|
|
|
6
6
|
# Checks for use of the lambda.(args) syntax.
|
|
7
7
|
#
|
|
8
8
|
# @example EnforcedStyle: call (default)
|
|
9
|
-
#
|
|
10
|
-
#
|
|
9
|
+
# # bad
|
|
10
|
+
# lambda.(x, y)
|
|
11
11
|
#
|
|
12
|
-
#
|
|
13
|
-
#
|
|
12
|
+
# # good
|
|
13
|
+
# lambda.call(x, y)
|
|
14
14
|
#
|
|
15
15
|
# @example EnforcedStyle: braces
|
|
16
|
-
#
|
|
17
|
-
#
|
|
16
|
+
# # bad
|
|
17
|
+
# lambda.call(x, y)
|
|
18
18
|
#
|
|
19
|
-
#
|
|
20
|
-
#
|
|
19
|
+
# # good
|
|
20
|
+
# lambda.(x, y)
|
|
21
21
|
class LambdaCall < Base
|
|
22
22
|
include ConfigurableEnforcedStyle
|
|
23
23
|
extend AutoCorrector
|
|
@@ -10,7 +10,7 @@ module RuboCop
|
|
|
10
10
|
# Required capitalization can be set with the `DirectiveCapitalization` and
|
|
11
11
|
# `ValueCapitalization` configuration keys.
|
|
12
12
|
#
|
|
13
|
-
# NOTE: If one of these
|
|
13
|
+
# NOTE: If one of these configurations is set to nil, any capitalization is allowed.
|
|
14
14
|
#
|
|
15
15
|
# @example EnforcedStyle: snake_case (default)
|
|
16
16
|
# # The `snake_case` style will enforce that the frozen string literal
|
|
@@ -176,7 +176,7 @@ module RuboCop
|
|
|
176
176
|
if first_non_comment_token
|
|
177
177
|
0...first_non_comment_token.line
|
|
178
178
|
else
|
|
179
|
-
|
|
179
|
+
0..
|
|
180
180
|
end
|
|
181
181
|
end
|
|
182
182
|
|
|
@@ -299,7 +299,7 @@ module RuboCop
|
|
|
299
299
|
end
|
|
300
300
|
|
|
301
301
|
def supported_capitalizations
|
|
302
|
-
cop_config['SupportedCapitalizations'].map(&:to_sym)
|
|
302
|
+
@supported_capitalizations ||= cop_config['SupportedCapitalizations'].map(&:to_sym).freeze
|
|
303
303
|
end
|
|
304
304
|
end
|
|
305
305
|
end
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module Cop
|
|
5
|
+
module Style
|
|
6
|
+
# Checks for `map { |x| x.to_s }.join` and similar calls where the
|
|
7
|
+
# `map` is redundant because `Array#join` implicitly calls `#to_s` on
|
|
8
|
+
# each element.
|
|
9
|
+
#
|
|
10
|
+
# @safety
|
|
11
|
+
# This cop is unsafe because it cannot guarantee that the receiver
|
|
12
|
+
# is an `Array` by static analysis. If the receiver does not have
|
|
13
|
+
# an `Array#join`-compatible implementation (i.e. one that calls
|
|
14
|
+
# `#to_s` on elements), the correction may change behavior.
|
|
15
|
+
#
|
|
16
|
+
# @example
|
|
17
|
+
# # bad
|
|
18
|
+
# array.map(&:to_s).join(', ')
|
|
19
|
+
#
|
|
20
|
+
# # bad
|
|
21
|
+
# array.map { |x| x.to_s }.join(', ')
|
|
22
|
+
#
|
|
23
|
+
# # bad
|
|
24
|
+
# array.collect(&:to_s).join
|
|
25
|
+
#
|
|
26
|
+
# # good
|
|
27
|
+
# array.join(', ')
|
|
28
|
+
#
|
|
29
|
+
# # good
|
|
30
|
+
# array.join
|
|
31
|
+
#
|
|
32
|
+
class MapJoin < Base
|
|
33
|
+
extend AutoCorrector
|
|
34
|
+
include RangeHelp
|
|
35
|
+
|
|
36
|
+
MSG = 'Remove redundant `%<method>s(&:to_s)` before `join`.'
|
|
37
|
+
RESTRICT_ON_SEND = %i[join].freeze
|
|
38
|
+
|
|
39
|
+
# map(&:to_s).join(...)
|
|
40
|
+
# @!method map_to_s_join?(node)
|
|
41
|
+
def_node_matcher :map_to_s_join?, <<~PATTERN
|
|
42
|
+
(call
|
|
43
|
+
$(call _ ${:map :collect} (block_pass (sym :to_s)))
|
|
44
|
+
:join ...)
|
|
45
|
+
PATTERN
|
|
46
|
+
|
|
47
|
+
# map { |x| x.to_s }.join(...)
|
|
48
|
+
# @!method map_to_s_block_join?(node)
|
|
49
|
+
def_node_matcher :map_to_s_block_join?, <<~PATTERN
|
|
50
|
+
(call
|
|
51
|
+
$(block
|
|
52
|
+
(call _ ${:map :collect})
|
|
53
|
+
(args (arg _x))
|
|
54
|
+
(send (lvar _x) :to_s))
|
|
55
|
+
:join ...)
|
|
56
|
+
PATTERN
|
|
57
|
+
|
|
58
|
+
# map { _1.to_s }.join(...)
|
|
59
|
+
# @!method map_to_s_numblock_join?(node)
|
|
60
|
+
def_node_matcher :map_to_s_numblock_join?, <<~PATTERN
|
|
61
|
+
(call
|
|
62
|
+
$(numblock
|
|
63
|
+
(call _ ${:map :collect})
|
|
64
|
+
1
|
|
65
|
+
(send (lvar :_1) :to_s))
|
|
66
|
+
:join ...)
|
|
67
|
+
PATTERN
|
|
68
|
+
|
|
69
|
+
# map { it.to_s }.join(...)
|
|
70
|
+
# @!method map_to_s_itblock_join?(node)
|
|
71
|
+
def_node_matcher :map_to_s_itblock_join?, <<~PATTERN
|
|
72
|
+
(call
|
|
73
|
+
$(itblock
|
|
74
|
+
(call _ ${:map :collect})
|
|
75
|
+
:it
|
|
76
|
+
(send (lvar :it) :to_s))
|
|
77
|
+
:join ...)
|
|
78
|
+
PATTERN
|
|
79
|
+
|
|
80
|
+
def on_send(node)
|
|
81
|
+
map_to_s_join?(node) { |m, n| register_offense(node, m, n) } ||
|
|
82
|
+
map_to_s_block_join?(node) { |m, n| register_offense(node, m, n) } ||
|
|
83
|
+
map_to_s_numblock_join?(node) { |m, n| register_offense(node, m, n) } ||
|
|
84
|
+
map_to_s_itblock_join?(node) { |m, n| register_offense(node, m, n) }
|
|
85
|
+
end
|
|
86
|
+
alias on_csend on_send
|
|
87
|
+
|
|
88
|
+
private
|
|
89
|
+
|
|
90
|
+
def register_offense(join_node, map_node, method_name)
|
|
91
|
+
map_send = map_node.any_block_type? ? map_node.send_node : map_node
|
|
92
|
+
message = format(MSG, method: method_name)
|
|
93
|
+
|
|
94
|
+
add_offense(map_send.loc.selector, message: message) do |corrector|
|
|
95
|
+
remove_map_call(corrector, join_node, map_node, map_send)
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def remove_map_call(corrector, join_node, map_node, map_send)
|
|
100
|
+
receiver = map_send.receiver
|
|
101
|
+
if receiver
|
|
102
|
+
corrector.replace(removal_range(receiver, map_node, map_send), '')
|
|
103
|
+
else
|
|
104
|
+
corrector.replace(no_receiver_range(map_node, join_node), '')
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def removal_range(receiver, map_node, map_send)
|
|
109
|
+
start_pos = if receiver.last_line < map_send.loc.dot.line
|
|
110
|
+
receiver.source_range.end_pos
|
|
111
|
+
else
|
|
112
|
+
map_send.loc.dot.begin_pos
|
|
113
|
+
end
|
|
114
|
+
range_between(start_pos, map_node.source_range.end_pos)
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def no_receiver_range(map_node, join_node)
|
|
118
|
+
range_between(map_node.source_range.begin_pos, join_node.loc.dot.end_pos)
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
end
|
|
@@ -33,13 +33,26 @@ module RuboCop
|
|
|
33
33
|
end
|
|
34
34
|
|
|
35
35
|
def included_macros_list
|
|
36
|
-
cop_config.fetch('IncludedMacros', []).map(&:to_sym)
|
|
36
|
+
@included_macros_list ||= cop_config.fetch('IncludedMacros', []).map(&:to_sym).freeze
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def included_macro_patterns
|
|
40
|
+
@included_macro_patterns ||=
|
|
41
|
+
cop_config.fetch('IncludedMacroPatterns', [])
|
|
42
|
+
.map { |pattern| Regexp.new(pattern) }.freeze
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def matches_included_macro_pattern?(method_name)
|
|
46
|
+
included_macro_patterns.any? do |pattern|
|
|
47
|
+
pattern.match?(method_name.to_s)
|
|
48
|
+
end
|
|
37
49
|
end
|
|
38
50
|
|
|
39
51
|
def ignored_macro?(node)
|
|
40
52
|
cop_config['IgnoreMacros'] &&
|
|
41
53
|
node.macro? &&
|
|
42
|
-
!included_macros_list.include?(node.method_name)
|
|
54
|
+
!included_macros_list.include?(node.method_name) &&
|
|
55
|
+
!matches_included_macro_pattern?(node.method_name)
|
|
43
56
|
end
|
|
44
57
|
end
|
|
45
58
|
end
|
|
@@ -9,17 +9,20 @@ module RuboCop
|
|
|
9
9
|
# In the default style (require_parentheses), macro methods are allowed.
|
|
10
10
|
# Additional methods can be added to the `AllowedMethods` or
|
|
11
11
|
# `AllowedPatterns` list. These options are valid only in the default
|
|
12
|
-
# style. Macros can be included by either setting `IgnoreMacros` to false
|
|
13
|
-
#
|
|
12
|
+
# style. Macros can be included by either setting `IgnoreMacros` to false,
|
|
13
|
+
# adding specific macros to the `IncludedMacros` list, or using
|
|
14
|
+
# `IncludedMacroPatterns` for pattern-based matching.
|
|
14
15
|
#
|
|
15
16
|
# Precedence of options is as follows:
|
|
16
17
|
#
|
|
17
18
|
# 1. `AllowedMethods`
|
|
18
19
|
# 2. `AllowedPatterns`
|
|
19
20
|
# 3. `IncludedMacros`
|
|
21
|
+
# 4. `IncludedMacroPatterns`
|
|
20
22
|
#
|
|
21
|
-
# If a method is listed in both `IncludedMacros`
|
|
22
|
-
# then the latter takes precedence (that is, the
|
|
23
|
+
# If a method is listed in both `IncludedMacros`/`IncludedMacroPatterns`
|
|
24
|
+
# and `AllowedMethods`, then the latter takes precedence (that is, the
|
|
25
|
+
# method is allowed).
|
|
23
26
|
#
|
|
24
27
|
# In the alternative style (omit_parentheses), there are three additional
|
|
25
28
|
# options.
|
|
@@ -148,6 +151,16 @@ module RuboCop
|
|
|
148
151
|
# # still enforces parentheses on other methods
|
|
149
152
|
# array.delete(e)
|
|
150
153
|
#
|
|
154
|
+
# @example IncludedMacroPatterns: ["^assert", "^refute"]
|
|
155
|
+
#
|
|
156
|
+
# # bad
|
|
157
|
+
# assert_equal 'test', x
|
|
158
|
+
# refute_nil value
|
|
159
|
+
#
|
|
160
|
+
# # good
|
|
161
|
+
# assert_equal('test', x)
|
|
162
|
+
# refute_nil(value)
|
|
163
|
+
#
|
|
151
164
|
# @example AllowParenthesesInMultilineCall: false (default)
|
|
152
165
|
#
|
|
153
166
|
# # bad
|
|
@@ -103,8 +103,6 @@ module RuboCop
|
|
|
103
103
|
MSG_MISSING = 'Use def with parentheses when there are parameters.'
|
|
104
104
|
|
|
105
105
|
def on_def(node)
|
|
106
|
-
return if forced_parentheses?(node)
|
|
107
|
-
|
|
108
106
|
args = node.arguments
|
|
109
107
|
|
|
110
108
|
if require_parentheses?(args)
|
|
@@ -113,10 +111,10 @@ module RuboCop
|
|
|
113
111
|
else
|
|
114
112
|
correct_style_detected
|
|
115
113
|
end
|
|
114
|
+
elsif forced_parentheses?(node)
|
|
115
|
+
correct_style_detected
|
|
116
116
|
elsif parentheses?(args)
|
|
117
117
|
unwanted_parentheses(args)
|
|
118
|
-
else
|
|
119
|
-
correct_style_detected
|
|
120
118
|
end
|
|
121
119
|
end
|
|
122
120
|
alias on_defs on_def
|
|
@@ -6,7 +6,7 @@ module RuboCop
|
|
|
6
6
|
# Enforces the use of `max` or `min` instead of comparison for greater or less.
|
|
7
7
|
#
|
|
8
8
|
# NOTE: It can be used if you want to present limit or threshold in Ruby 2.7+.
|
|
9
|
-
#
|
|
9
|
+
# It is slow though. So autocorrection will apply generic `max` or `min`:
|
|
10
10
|
#
|
|
11
11
|
# [source,ruby]
|
|
12
12
|
# ----
|