rubocop 1.81.7 → 1.92.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/LICENSE.txt +1 -1
- data/README.md +2 -2
- data/config/default.yml +626 -111
- data/config/obsoletion.yml +39 -1
- data/exe/rubocop +1 -1
- data/lib/rubocop/cache_config.rb +29 -0
- data/lib/rubocop/cached_data.rb +50 -5
- data/lib/rubocop/changed_files.rb +134 -0
- data/lib/rubocop/cli/command/auto_generate_config.rb +34 -2
- data/lib/rubocop/cli/command/cop_names.rb +57 -0
- data/lib/rubocop/cli/command/execute_runner.rb +54 -3
- data/lib/rubocop/cli/command/explain.rb +34 -0
- 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 +8 -2
- data/lib/rubocop/cli/command/show_docs_url.rb +8 -10
- data/lib/rubocop/cli/command/suggest_extensions.rb +1 -1
- data/lib/rubocop/cli.rb +41 -14
- data/lib/rubocop/comment_config/directive_range.rb +34 -0
- data/lib/rubocop/comment_config/disable_next.rb +143 -0
- data/lib/rubocop/comment_config/push_pop.rb +55 -0
- data/lib/rubocop/comment_config.rb +97 -44
- data/lib/rubocop/config.rb +100 -15
- data/lib/rubocop/config_finder.rb +1 -1
- data/lib/rubocop/config_loader.rb +49 -27
- data/lib/rubocop/config_loader_resolver.rb +95 -20
- data/lib/rubocop/config_obsoletion/cop_rule.rb +2 -1
- data/lib/rubocop/config_obsoletion/extracted_cop.rb +4 -2
- data/lib/rubocop/config_obsoletion/removed_cop.rb +9 -1
- data/lib/rubocop/config_obsoletion.rb +1 -1
- data/lib/rubocop/config_store.rb +2 -2
- data/lib/rubocop/config_validator.rb +69 -7
- data/lib/rubocop/cop/autocorrect_logic.rb +24 -6
- data/lib/rubocop/cop/badge.rb +10 -2
- data/lib/rubocop/cop/base.rb +128 -35
- data/lib/rubocop/cop/bundler/gem_comment.rb +5 -4
- data/lib/rubocop/cop/bundler/gem_version.rb +28 -28
- data/lib/rubocop/cop/bundler/ordered_gems.rb +1 -10
- data/lib/rubocop/cop/bundler.rb +19 -0
- data/lib/rubocop/cop/commissioner.rb +13 -11
- data/lib/rubocop/cop/cop_documentation.rb +81 -0
- data/lib/rubocop/cop/cop_explanation.rb +140 -0
- data/lib/rubocop/cop/corrector.rb +4 -4
- data/lib/rubocop/cop/correctors/alignment_corrector.rb +87 -9
- data/lib/rubocop/cop/correctors/condition_corrector.rb +1 -1
- data/lib/rubocop/cop/correctors/each_to_for_corrector.rb +37 -7
- data/lib/rubocop/cop/correctors/empty_line_corrector.rb +1 -1
- data/lib/rubocop/cop/correctors/lambda_literal_to_method_corrector.rb +31 -4
- data/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +35 -5
- data/lib/rubocop/cop/correctors/ordered_gem_corrector.rb +8 -1
- data/lib/rubocop/cop/correctors/parentheses_corrector.rb +70 -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 +3 -4
- data/lib/rubocop/cop/exclude_limit.rb +31 -5
- data/lib/rubocop/cop/gemspec/dependency_version.rb +0 -6
- data/lib/rubocop/cop/gemspec/development_dependencies.rb +1 -1
- data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +14 -4
- data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +1 -8
- data/lib/rubocop/cop/gemspec/require_mfa.rb +9 -6
- data/lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb +12 -7
- data/lib/rubocop/cop/gemspec.rb +22 -0
- data/lib/rubocop/cop/generator/registration_injector.rb +188 -0
- data/lib/rubocop/cop/generator.rb +5 -1
- 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 +12 -16
- data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_processor.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_walker.rb +1 -2
- data/lib/rubocop/cop/internal_affairs/node_type_group.rb +0 -7
- data/lib/rubocop/cop/internal_affairs/on_send_without_on_csend.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/redundant_context_config_parameter.rb +1 -7
- data/lib/rubocop/cop/internal_affairs/redundant_let_rubocop_config_new.rb +5 -3
- data/lib/rubocop/cop/internal_affairs/style_detected_api_use.rb +1 -7
- 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 +9 -3
- 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/block_alignment.rb +84 -4
- data/lib/rubocop/cop/layout/case_indentation.rb +28 -10
- data/lib/rubocop/cop/layout/class_structure.rb +156 -41
- data/lib/rubocop/cop/layout/comment_indentation.rb +17 -7
- data/lib/rubocop/cop/layout/condition_position.rb +13 -3
- data/lib/rubocop/cop/layout/def_end_alignment.rb +4 -0
- data/lib/rubocop/cop/layout/dot_position.rb +26 -16
- data/lib/rubocop/cop/layout/else_alignment.rb +2 -14
- data/lib/rubocop/cop/layout/empty_comment.rb +8 -10
- data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +25 -7
- data/lib/rubocop/cop/layout/empty_line_after_magic_comment.rb +63 -5
- data/lib/rubocop/cop/layout/empty_line_after_multiline_condition.rb +21 -8
- data/lib/rubocop/cop/layout/empty_line_between_defs.rb +15 -2
- data/lib/rubocop/cop/layout/empty_lines.rb +5 -2
- data/lib/rubocop/cop/layout/empty_lines_after_module_inclusion.rb +2 -2
- data/lib/rubocop/cop/layout/empty_lines_around_attribute_accessor.rb +2 -0
- data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +21 -5
- data/lib/rubocop/cop/layout/empty_lines_around_class_body.rb +16 -2
- data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +23 -1
- data/lib/rubocop/cop/layout/empty_lines_around_module_body.rb +16 -2
- data/lib/rubocop/cop/layout/end_alignment.rb +23 -15
- data/lib/rubocop/cop/layout/extra_spacing.rb +109 -3
- data/lib/rubocop/cop/layout/first_argument_indentation.rb +81 -2
- data/lib/rubocop/cop/layout/first_array_element_indentation.rb +18 -5
- data/lib/rubocop/cop/layout/first_array_element_line_break.rb +41 -0
- data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +36 -23
- data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +25 -25
- data/lib/rubocop/cop/layout/first_method_argument_line_break.rb +6 -0
- data/lib/rubocop/cop/layout/first_method_parameter_line_break.rb +4 -0
- data/lib/rubocop/cop/layout/first_parameter_indentation.rb +11 -0
- data/lib/rubocop/cop/layout/hash_alignment.rb +16 -11
- data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +8 -4
- data/lib/rubocop/cop/layout/heredoc_indentation.rb +48 -3
- data/lib/rubocop/cop/layout/indentation_consistency.rb +22 -5
- data/lib/rubocop/cop/layout/indentation_style.rb +5 -2
- data/lib/rubocop/cop/layout/indentation_width.rb +158 -12
- data/lib/rubocop/cop/layout/leading_comment_space.rb +27 -0
- data/lib/rubocop/cop/layout/line_continuation_spacing.rb +10 -4
- data/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb +25 -9
- data/lib/rubocop/cop/layout/line_length.rb +265 -29
- data/lib/rubocop/cop/layout/multiline_array_brace_layout.rb +69 -57
- data/lib/rubocop/cop/layout/multiline_assignment_layout.rb +8 -2
- data/lib/rubocop/cop/layout/multiline_block_layout.rb +10 -1
- data/lib/rubocop/cop/layout/multiline_hash_brace_layout.rb +65 -56
- data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +7 -1
- data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +268 -38
- data/lib/rubocop/cop/layout/multiline_method_definition_brace_layout.rb +4 -0
- data/lib/rubocop/cop/layout/parameter_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/redundant_line_break.rb +102 -2
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +19 -5
- data/lib/rubocop/cop/layout/single_line_block_chain.rb +10 -2
- data/lib/rubocop/cop/layout/space_after_comma.rb +2 -10
- data/lib/rubocop/cop/layout/space_after_not.rb +5 -0
- data/lib/rubocop/cop/layout/space_after_semicolon.rb +1 -1
- data/lib/rubocop/cop/layout/space_around_block_parameters.rb +10 -4
- data/lib/rubocop/cop/layout/space_around_keyword.rb +14 -2
- data/lib/rubocop/cop/layout/space_around_operators.rb +18 -3
- data/lib/rubocop/cop/layout/space_before_block_braces.rb +4 -1
- 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/space_inside_array_literal_brackets.rb +44 -34
- data/lib/rubocop/cop/layout/space_inside_block_braces.rb +31 -8
- data/lib/rubocop/cop/layout/space_inside_reference_brackets.rb +2 -12
- data/lib/rubocop/cop/layout.rb +114 -0
- data/lib/rubocop/cop/lazy_loader.rb +41 -0
- data/lib/rubocop/cop/lint/ambiguous_assignment.rb +9 -17
- data/lib/rubocop/cop/lint/ambiguous_block_association.rb +72 -1
- data/lib/rubocop/cop/lint/ambiguous_operator.rb +1 -1
- data/lib/rubocop/cop/lint/ambiguous_operator_precedence.rb +3 -11
- data/lib/rubocop/cop/lint/ambiguous_range.rb +1 -2
- data/lib/rubocop/cop/lint/ambiguous_regexp_literal.rb +6 -1
- data/lib/rubocop/cop/lint/argument_mismatch.rb +99 -0
- data/lib/rubocop/cop/lint/assignment_in_condition.rb +15 -1
- data/lib/rubocop/cop/lint/circular_argument_reference.rb +45 -3
- data/lib/rubocop/cop/lint/constant_overwritten_in_rescue.rb +1 -1
- data/lib/rubocop/cop/lint/constant_reassignment.rb +94 -15
- data/lib/rubocop/cop/lint/constant_resolution.rb +31 -6
- data/lib/rubocop/cop/lint/cop_directive_syntax.rb +165 -15
- data/lib/rubocop/cop/lint/data_define_override.rb +63 -0
- data/lib/rubocop/cop/lint/debugger.rb +13 -2
- data/lib/rubocop/cop/lint/deprecated_constants.rb +2 -8
- data/lib/rubocop/cop/lint/deprecated_reference.rb +194 -0
- data/lib/rubocop/cop/lint/duplicate_match_pattern.rb +4 -4
- data/lib/rubocop/cop/lint/duplicate_methods.rb +405 -28
- data/lib/rubocop/cop/lint/else_layout.rb +19 -0
- data/lib/rubocop/cop/lint/empty_block.rb +4 -4
- data/lib/rubocop/cop/lint/empty_conditional_body.rb +9 -2
- data/lib/rubocop/cop/lint/empty_in_pattern.rb +8 -1
- data/lib/rubocop/cop/lint/empty_when.rb +8 -1
- data/lib/rubocop/cop/lint/ensure_return.rb +19 -1
- data/lib/rubocop/cop/lint/erb_new_arguments.rb +4 -2
- data/lib/rubocop/cop/lint/float_comparison.rb +2 -1
- data/lib/rubocop/cop/lint/heredoc_method_call_position.rb +4 -0
- data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +1 -2
- data/lib/rubocop/cop/lint/incompatible_io_select_with_fiber_scheduler.rb +5 -1
- data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +1 -2
- data/lib/rubocop/cop/lint/inherit_exception.rb +53 -7
- data/lib/rubocop/cop/lint/interpolation_check.rb +25 -6
- data/lib/rubocop/cop/lint/lambda_without_literal_block.rb +1 -1
- data/lib/rubocop/cop/lint/literal_as_condition.rb +36 -9
- data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +11 -1
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +75 -37
- data/lib/rubocop/cop/lint/loop.rb +24 -2
- data/lib/rubocop/cop/lint/misplaced_magic_comment.rb +245 -0
- data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +46 -18
- data/lib/rubocop/cop/lint/missing_super.rb +31 -1
- data/lib/rubocop/cop/lint/multiple_comparison.rb +2 -2
- data/lib/rubocop/cop/lint/name_typo.rb +270 -0
- data/lib/rubocop/cop/lint/nested_method_definition.rb +1 -1
- data/lib/rubocop/cop/lint/next_without_accumulator.rb +2 -0
- data/lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +20 -0
- data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +4 -2
- data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +1 -1
- data/lib/rubocop/cop/lint/number_conversion.rb +22 -11
- data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +1 -1
- data/lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +10 -0
- data/lib/rubocop/cop/lint/ordered_magic_comments.rb +7 -7
- data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +15 -4
- data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +20 -14
- data/lib/rubocop/cop/lint/raise_exception.rb +1 -1
- data/lib/rubocop/cop/lint/rand_one.rb +1 -1
- data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +160 -39
- data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +53 -19
- data/lib/rubocop/cop/lint/redundant_dir_glob_sort.rb +28 -6
- data/lib/rubocop/cop/lint/redundant_require_statement.rb +5 -4
- data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +37 -14
- data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +13 -4
- data/lib/rubocop/cop/lint/redundant_type_conversion.rb +11 -5
- data/lib/rubocop/cop/lint/redundant_with_index.rb +2 -3
- data/lib/rubocop/cop/lint/redundant_with_object.rb +5 -0
- data/lib/rubocop/cop/lint/refinement_import_methods.rb +8 -1
- data/lib/rubocop/cop/lint/regexp_as_condition.rb +9 -1
- data/lib/rubocop/cop/lint/require_parentheses.rb +13 -4
- data/lib/rubocop/cop/lint/require_range_parentheses.rb +2 -1
- data/lib/rubocop/cop/lint/require_relative_self_path.rb +7 -5
- data/lib/rubocop/cop/lint/rescue_type.rb +1 -1
- data/lib/rubocop/cop/lint/safe_navigation_chain.rb +24 -0
- data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +56 -6
- data/lib/rubocop/cop/lint/safe_navigation_with_empty.rb +1 -1
- data/lib/rubocop/cop/lint/script_permission.rb +5 -1
- data/lib/rubocop/cop/lint/self_assignment.rb +33 -2
- data/lib/rubocop/cop/lint/send_with_mixin_argument.rb +1 -1
- data/lib/rubocop/cop/lint/shadowed_exception.rb +1 -1
- data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +14 -0
- data/lib/rubocop/cop/lint/shared_mutable_default.rb +3 -1
- data/lib/rubocop/cop/lint/struct_new_override.rb +17 -1
- data/lib/rubocop/cop/lint/super_argument_mismatch.rb +179 -0
- data/lib/rubocop/cop/lint/suppressed_exception_in_number_conversion.rb +13 -2
- data/lib/rubocop/cop/lint/symbol_conversion.rb +22 -4
- data/lib/rubocop/cop/lint/syntax.rb +25 -1
- data/lib/rubocop/cop/lint/to_enum_arguments.rb +72 -4
- data/lib/rubocop/cop/lint/to_json.rb +20 -17
- data/lib/rubocop/cop/lint/top_level_return_with_argument.rb +1 -1
- data/lib/rubocop/cop/lint/trailing_comma_in_attribute_declaration.rb +5 -1
- data/lib/rubocop/cop/lint/unescaped_bracket_in_regexp.rb +54 -11
- data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +1 -0
- data/lib/rubocop/cop/lint/unreachable_code.rb +15 -9
- 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/unused_private_method.rb +234 -0
- data/lib/rubocop/cop/lint/useless_access_modifier.rb +1 -2
- data/lib/rubocop/cop/lint/useless_assignment.rb +61 -27
- data/lib/rubocop/cop/lint/useless_constant_scoping.rb +40 -4
- data/lib/rubocop/cop/lint/useless_default_value_argument.rb +2 -0
- data/lib/rubocop/cop/lint/useless_method_definition.rb +1 -1
- data/lib/rubocop/cop/lint/useless_numeric_operation.rb +10 -10
- data/lib/rubocop/cop/lint/useless_or.rb +15 -2
- data/lib/rubocop/cop/lint/useless_rescue.rb +1 -2
- data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +10 -4
- data/lib/rubocop/cop/lint/useless_setter_call.rb +11 -5
- data/lib/rubocop/cop/lint/useless_times.rb +22 -1
- data/lib/rubocop/cop/lint/utils/nil_receiver_checker.rb +94 -14
- data/lib/rubocop/cop/lint/void.rb +59 -22
- data/lib/rubocop/cop/lint.rb +179 -0
- 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/class_length.rb +4 -2
- data/lib/rubocop/cop/metrics/collection_literal_length.rb +1 -1
- data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +0 -4
- data/lib/rubocop/cop/metrics/method_length.rb +2 -2
- data/lib/rubocop/cop/metrics/module_length.rb +4 -2
- data/lib/rubocop/cop/metrics/perceived_complexity.rb +37 -7
- data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +4 -3
- data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +1 -1
- data/lib/rubocop/cop/metrics/utils/iterating_block.rb +1 -1
- data/lib/rubocop/cop/metrics.rb +31 -0
- data/lib/rubocop/cop/migration/department_name.rb +11 -5
- data/lib/rubocop/cop/migration.rb +13 -0
- data/lib/rubocop/cop/mixin/alignment.rb +5 -1
- data/lib/rubocop/cop/mixin/allowed_methods.rb +5 -5
- data/lib/rubocop/cop/mixin/allowed_pattern.rb +5 -1
- data/lib/rubocop/cop/mixin/annotation_comment.rb +1 -1
- data/lib/rubocop/cop/mixin/check_line_breakable.rb +47 -25
- data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +12 -8
- data/lib/rubocop/cop/mixin/code_length.rb +10 -2
- data/lib/rubocop/cop/mixin/comments_help.rb +1 -2
- data/lib/rubocop/cop/mixin/configurable_enforced_style.rb +1 -2
- data/lib/rubocop/cop/mixin/configurable_max.rb +6 -5
- data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +12 -1
- data/lib/rubocop/cop/mixin/endless_method_body_help.rb +105 -0
- data/lib/rubocop/cop/mixin/endless_method_rewriter.rb +13 -5
- data/lib/rubocop/cop/mixin/forbidden_identifiers.rb +2 -2
- data/lib/rubocop/cop/mixin/forbidden_pattern.rb +5 -1
- data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +58 -12
- data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +37 -10
- data/lib/rubocop/cop/mixin/hash_subset.rb +9 -2
- data/lib/rubocop/cop/mixin/hash_transform_method/autocorrection.rb +63 -0
- data/lib/rubocop/cop/mixin/hash_transform_method.rb +14 -60
- data/lib/rubocop/cop/mixin/indexed_method_arity.rb +94 -0
- data/lib/rubocop/cop/mixin/line_length_help.rb +28 -3
- data/lib/rubocop/cop/mixin/method_complexity.rb +1 -1
- data/lib/rubocop/cop/mixin/min_branches_count.rb +3 -1
- data/lib/rubocop/cop/mixin/multiline_element_line_breaks.rb +11 -1
- data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +1 -1
- data/lib/rubocop/cop/mixin/multiline_literal_brace_layout.rb +10 -1
- data/lib/rubocop/cop/mixin/ordered_gem_node.rb +1 -1
- data/lib/rubocop/cop/mixin/pattern_matching_help.rb +35 -0
- data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +79 -8
- data/lib/rubocop/cop/mixin/project_index_help.rb +203 -0
- data/lib/rubocop/cop/mixin/range_help.rb +1 -2
- data/lib/rubocop/cop/mixin/reparsed_equivalence.rb +181 -0
- data/lib/rubocop/cop/mixin/space_after_punctuation.rb +5 -4
- data/lib/rubocop/cop/mixin/statement_modifier.rb +69 -12
- data/lib/rubocop/cop/mixin/trailing_comma.rb +7 -6
- data/lib/rubocop/cop/mixin/visibility_help.rb +2 -1
- data/lib/rubocop/cop/mixin.rb +93 -0
- data/lib/rubocop/cop/naming/accessor_method_name.rb +8 -0
- data/lib/rubocop/cop/naming/binary_operator_parameter_name.rb +17 -1
- data/lib/rubocop/cop/naming/block_forwarding.rb +4 -1
- data/lib/rubocop/cop/naming/block_parameter_name.rb +1 -1
- data/lib/rubocop/cop/naming/file_name.rb +4 -3
- data/lib/rubocop/cop/naming/heredoc_delimiter_case.rb +9 -2
- data/lib/rubocop/cop/naming/heredoc_delimiter_naming.rb +5 -3
- data/lib/rubocop/cop/naming/inclusive_language.rb +8 -2
- data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +12 -5
- data/lib/rubocop/cop/naming/method_name.rb +6 -3
- data/lib/rubocop/cop/naming/predicate_method.rb +13 -2
- data/lib/rubocop/cop/naming/predicate_prefix.rb +30 -17
- data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +12 -7
- data/lib/rubocop/cop/naming/variable_number.rb +3 -1
- data/lib/rubocop/cop/naming.rb +31 -0
- data/lib/rubocop/cop/offense.rb +108 -9
- data/lib/rubocop/cop/registry.rb +232 -66
- data/lib/rubocop/cop/security/eval.rb +15 -2
- data/lib/rubocop/cop/security/io_methods.rb +2 -2
- data/lib/rubocop/cop/security/json_load.rb +16 -4
- data/lib/rubocop/cop/security/marshal_load.rb +1 -1
- data/lib/rubocop/cop/security.rb +19 -0
- data/lib/rubocop/cop/severity.rb +12 -0
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +55 -8
- data/lib/rubocop/cop/style/accessor_grouping.rb +16 -5
- data/lib/rubocop/cop/style/alias.rb +33 -8
- data/lib/rubocop/cop/style/ambiguous_endless_method_definition.rb +4 -3
- data/lib/rubocop/cop/style/and_or.rb +8 -3
- data/lib/rubocop/cop/style/arguments_forwarding.rb +61 -17
- data/lib/rubocop/cop/style/array_first_last.rb +13 -3
- data/lib/rubocop/cop/style/array_intersect.rb +28 -5
- data/lib/rubocop/cop/style/array_intersect_with_single_element.rb +3 -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 +8 -6
- 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 +7 -6
- data/lib/rubocop/cop/style/block_delimiters.rb +74 -38
- data/lib/rubocop/cop/style/case_equality.rb +29 -15
- data/lib/rubocop/cop/style/case_like_if.rb +11 -10
- data/lib/rubocop/cop/style/character_literal.rb +2 -2
- data/lib/rubocop/cop/style/class_and_module_children.rb +151 -35
- data/lib/rubocop/cop/style/class_equality_comparison.rb +21 -13
- data/lib/rubocop/cop/style/class_methods_definitions.rb +26 -5
- data/lib/rubocop/cop/style/collection_compact.rb +37 -17
- data/lib/rubocop/cop/style/collection_querying.rb +79 -46
- data/lib/rubocop/cop/style/colon_method_call.rb +16 -7
- data/lib/rubocop/cop/style/combinable_loops.rb +91 -9
- data/lib/rubocop/cop/style/comparable_clamp.rb +12 -1
- data/lib/rubocop/cop/style/concat_array_literals.rb +65 -9
- data/lib/rubocop/cop/style/conditional_assignment.rb +34 -18
- data/lib/rubocop/cop/style/constant_visibility.rb +13 -7
- data/lib/rubocop/cop/style/copyright.rb +27 -12
- data/lib/rubocop/cop/style/data_inheritance.rb +18 -0
- data/lib/rubocop/cop/style/date_time.rb +4 -4
- data/lib/rubocop/cop/style/def_with_parentheses.rb +6 -2
- data/lib/rubocop/cop/style/dig_chain.rb +5 -0
- data/lib/rubocop/cop/style/dir_empty.rb +4 -0
- data/lib/rubocop/cop/style/directive_scope.rb +304 -0
- data/lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb +184 -20
- data/lib/rubocop/cop/style/document_dynamic_eval_definition.rb +6 -1
- data/lib/rubocop/cop/style/documentation.rb +53 -6
- data/lib/rubocop/cop/style/documentation_method.rb +8 -12
- data/lib/rubocop/cop/style/double_negation.rb +11 -0
- 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_case_condition.rb +13 -4
- data/lib/rubocop/cop/style/empty_class_definition.rb +126 -0
- data/lib/rubocop/cop/style/empty_heredoc.rb +4 -0
- data/lib/rubocop/cop/style/empty_lambda_parameter.rb +1 -1
- data/lib/rubocop/cop/style/empty_literal.rb +8 -3
- data/lib/rubocop/cop/style/empty_method.rb +15 -9
- data/lib/rubocop/cop/style/empty_string_inside_interpolation.rb +74 -22
- 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 +100 -21
- data/lib/rubocop/cop/style/env_home.rb +4 -0
- data/lib/rubocop/cop/style/even_odd.rb +11 -1
- data/lib/rubocop/cop/style/exact_regexp_match.rb +52 -8
- data/lib/rubocop/cop/style/explicit_block_argument.rb +50 -10
- data/lib/rubocop/cop/style/fetch_env_var.rb +1 -1
- data/lib/rubocop/cop/style/file_null.rb +6 -4
- data/lib/rubocop/cop/style/file_open.rb +84 -0
- data/lib/rubocop/cop/style/file_write.rb +21 -16
- data/lib/rubocop/cop/style/float_division.rb +28 -14
- data/lib/rubocop/cop/style/for.rb +60 -1
- data/lib/rubocop/cop/style/format_string.rb +44 -9
- data/lib/rubocop/cop/style/format_string_token.rb +50 -7
- data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +2 -1
- data/lib/rubocop/cop/style/global_vars.rb +5 -2
- data/lib/rubocop/cop/style/guard_clause.rb +57 -40
- data/lib/rubocop/cop/style/hash_as_last_array_item.rb +31 -9
- data/lib/rubocop/cop/style/hash_conversion.rb +39 -11
- data/lib/rubocop/cop/style/hash_each_methods.rb +1 -2
- data/lib/rubocop/cop/style/hash_lookup_method.rb +128 -0
- data/lib/rubocop/cop/style/hash_slice.rb +16 -0
- data/lib/rubocop/cop/style/hash_syntax.rb +19 -5
- 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/identical_conditional_branches.rb +38 -10
- data/lib/rubocop/cop/style/if_inside_else.rb +36 -8
- data/lib/rubocop/cop/style/if_unless_modifier.rb +80 -76
- data/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +17 -14
- data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +4 -1
- data/lib/rubocop/cop/style/if_with_semicolon.rb +61 -8
- data/lib/rubocop/cop/style/inline_comment.rb +5 -2
- data/lib/rubocop/cop/style/inverse_methods.rb +24 -2
- data/lib/rubocop/cop/style/invertible_unless_condition.rb +25 -5
- data/lib/rubocop/cop/style/ip_addresses.rb +1 -2
- data/lib/rubocop/cop/style/it_block_parameter.rb +94 -4
- data/lib/rubocop/cop/style/keyword_arguments_merging.rb +4 -0
- data/lib/rubocop/cop/style/keyword_parameters_order.rb +10 -4
- data/lib/rubocop/cop/style/lambda.rb +45 -2
- data/lib/rubocop/cop/style/lambda_call.rb +24 -8
- data/lib/rubocop/cop/style/magic_comment_format.rb +4 -4
- data/lib/rubocop/cop/style/map_compact_with_conditional_block.rb +11 -0
- data/lib/rubocop/cop/style/map_into_array.rb +2 -3
- data/lib/rubocop/cop/style/map_join.rb +123 -0
- data/lib/rubocop/cop/style/map_to_hash.rb +1 -2
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +102 -20
- 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 +42 -6
- data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +36 -8
- data/lib/rubocop/cop/style/method_def_parentheses.rb +36 -8
- data/lib/rubocop/cop/style/min_max_comparison.rb +4 -1
- data/lib/rubocop/cop/style/missing_else.rb +7 -1
- data/lib/rubocop/cop/style/missing_respond_to_missing.rb +40 -7
- data/lib/rubocop/cop/style/mixin_grouping.rb +12 -3
- data/lib/rubocop/cop/style/mixin_usage.rb +1 -1
- data/lib/rubocop/cop/style/module_function.rb +4 -2
- data/lib/rubocop/cop/style/module_member_existence_check.rb +110 -0
- data/lib/rubocop/cop/style/multiline_if_modifier.rb +45 -5
- data/lib/rubocop/cop/style/multiline_if_then.rb +10 -4
- data/lib/rubocop/cop/style/multiline_in_pattern_then.rb +7 -0
- data/lib/rubocop/cop/style/multiline_memoization.rb +7 -1
- data/lib/rubocop/cop/style/multiline_method_signature.rb +14 -13
- data/lib/rubocop/cop/style/multiline_ternary_operator.rb +7 -3
- data/lib/rubocop/cop/style/multiline_when_then.rb +7 -0
- data/lib/rubocop/cop/style/multiple_comparison.rb +33 -22
- data/lib/rubocop/cop/style/mutable_constant.rb +158 -14
- data/lib/rubocop/cop/style/negated_if_else_condition.rb +3 -3
- data/lib/rubocop/cop/style/negative_array_index.rb +228 -0
- data/lib/rubocop/cop/style/nested_modifier.rb +36 -12
- data/lib/rubocop/cop/style/nested_ternary_operator.rb +26 -8
- data/lib/rubocop/cop/style/next.rb +24 -10
- data/lib/rubocop/cop/style/nil_comparison.rb +50 -12
- data/lib/rubocop/cop/style/nil_lambda.rb +9 -1
- data/lib/rubocop/cop/style/non_nil_check.rb +21 -11
- data/lib/rubocop/cop/style/not.rb +12 -3
- data/lib/rubocop/cop/style/numeric_literal_prefix.rb +11 -1
- data/lib/rubocop/cop/style/numeric_literals.rb +3 -2
- data/lib/rubocop/cop/style/numeric_predicate.rb +22 -6
- data/lib/rubocop/cop/style/one_class_per_file.rb +115 -0
- data/lib/rubocop/cop/style/one_line_conditional.rb +18 -6
- data/lib/rubocop/cop/style/open_struct_use.rb +1 -1
- data/lib/rubocop/cop/style/operator_method_call.rb +10 -2
- data/lib/rubocop/cop/style/option_hash.rb +1 -1
- data/lib/rubocop/cop/style/optional_arguments.rb +1 -0
- data/lib/rubocop/cop/style/parallel_assignment.rb +26 -7
- data/lib/rubocop/cop/style/parentheses_around_condition.rb +7 -2
- data/lib/rubocop/cop/style/partition_instead_of_double_select.rb +270 -0
- data/lib/rubocop/cop/style/percent_literal_delimiters.rb +18 -3
- data/lib/rubocop/cop/style/perl_backrefs.rb +5 -3
- 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 +20 -10
- data/lib/rubocop/cop/style/reduce_to_hash.rb +216 -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_assignment.rb +12 -2
- data/lib/rubocop/cop/style/redundant_begin.rb +25 -7
- data/lib/rubocop/cop/style/redundant_condition.rb +41 -23
- data/lib/rubocop/cop/style/redundant_constant_base.rb +42 -6
- data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +13 -1
- data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +17 -3
- data/lib/rubocop/cop/style/redundant_each.rb +4 -5
- data/lib/rubocop/cop/style/redundant_exception.rb +21 -3
- data/lib/rubocop/cop/style/redundant_fetch_block.rb +10 -2
- data/lib/rubocop/cop/style/redundant_file_extension_in_require.rb +9 -0
- data/lib/rubocop/cop/style/redundant_filter_chain.rb +1 -1
- data/lib/rubocop/cop/style/redundant_format.rb +43 -7
- data/lib/rubocop/cop/style/redundant_freeze.rb +11 -3
- data/lib/rubocop/cop/style/redundant_heredoc_delimiter_quotes.rb +6 -1
- data/lib/rubocop/cop/style/redundant_interpolation_unfreeze.rb +49 -10
- data/lib/rubocop/cop/style/redundant_line_continuation.rb +82 -115
- data/lib/rubocop/cop/style/redundant_min_max_by.rb +93 -0
- data/lib/rubocop/cop/style/redundant_parentheses.rb +105 -83
- data/lib/rubocop/cop/style/redundant_percent_q.rb +5 -3
- data/lib/rubocop/cop/style/redundant_regexp_argument.rb +13 -2
- data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +6 -5
- data/lib/rubocop/cop/style/redundant_regexp_constructor.rb +27 -7
- data/lib/rubocop/cop/style/redundant_regexp_escape.rb +12 -4
- data/lib/rubocop/cop/style/redundant_return.rb +4 -3
- data/lib/rubocop/cop/style/redundant_self.rb +11 -2
- data/lib/rubocop/cop/style/redundant_self_assignment.rb +1 -2
- data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +27 -4
- data/lib/rubocop/cop/style/redundant_sort.rb +45 -11
- data/lib/rubocop/cop/style/redundant_string_escape.rb +1 -2
- data/lib/rubocop/cop/style/redundant_struct_keyword_init.rb +133 -0
- data/lib/rubocop/cop/style/regexp_literal.rb +106 -28
- data/lib/rubocop/cop/style/require_order.rb +25 -8
- data/lib/rubocop/cop/style/rescue_modifier.rb +15 -14
- data/lib/rubocop/cop/style/return_nil.rb +17 -2
- data/lib/rubocop/cop/style/return_nil_in_predicate_method_definition.rb +11 -1
- data/lib/rubocop/cop/style/reverse_find.rb +51 -0
- data/lib/rubocop/cop/style/safe_navigation.rb +18 -9
- data/lib/rubocop/cop/style/sample.rb +19 -13
- 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 +52 -23
- data/lib/rubocop/cop/style/self_assignment.rb +13 -16
- data/lib/rubocop/cop/style/semicolon.rb +39 -13
- data/lib/rubocop/cop/style/send_with_literal_method_name.rb +4 -0
- data/lib/rubocop/cop/style/single_line_block_params.rb +2 -2
- data/lib/rubocop/cop/style/single_line_do_end_block.rb +19 -7
- data/lib/rubocop/cop/style/single_line_methods.rb +24 -5
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +25 -7
- data/lib/rubocop/cop/style/special_global_vars.rb +7 -2
- data/lib/rubocop/cop/style/stabby_lambda_parentheses.rb +31 -5
- data/lib/rubocop/cop/style/static_class.rb +21 -0
- data/lib/rubocop/cop/style/string_concatenation.rb +25 -6
- data/lib/rubocop/cop/style/string_hash_keys.rb +1 -0
- data/lib/rubocop/cop/style/struct_inheritance.rb +36 -1
- data/lib/rubocop/cop/style/super_arguments.rb +6 -4
- data/lib/rubocop/cop/style/symbol_proc.rb +32 -14
- data/lib/rubocop/cop/style/tally_method.rb +181 -0
- data/lib/rubocop/cop/style/ternary_parentheses.rb +34 -1
- data/lib/rubocop/cop/style/time_now.rb +41 -0
- data/lib/rubocop/cop/style/top_level_method_definition.rb +2 -2
- 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 +35 -32
- data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
- data/lib/rubocop/cop/style/unless_logical_operators.rb +3 -3
- data/lib/rubocop/cop/style/while_until_do.rb +7 -0
- data/lib/rubocop/cop/style/while_until_modifier.rb +16 -0
- data/lib/rubocop/cop/style/word_array.rb +1 -0
- data/lib/rubocop/cop/style/yoda_condition.rb +26 -12
- data/lib/rubocop/cop/style/yoda_expression.rb +11 -2
- data/lib/rubocop/cop/style/zero_length_predicate.rb +6 -3
- data/lib/rubocop/cop/style.rb +311 -0
- data/lib/rubocop/cop/team.rb +171 -48
- data/lib/rubocop/cop/util.rb +5 -8
- data/lib/rubocop/cop/variable_force/assignment.rb +1 -1
- data/lib/rubocop/cop/variable_force/branch.rb +30 -6
- data/lib/rubocop/cop/variable_force/variable.rb +33 -9
- data/lib/rubocop/cops_documentation_generator.rb +27 -9
- data/lib/rubocop/directive_comment.rb +116 -7
- data/lib/rubocop/feature_loader.rb +0 -6
- data/lib/rubocop/file_patterns.rb +9 -1
- data/lib/rubocop/formatter/base_formatter.rb +22 -0
- data/lib/rubocop/formatter/clang_style_formatter.rb +5 -2
- data/lib/rubocop/formatter/disabled_config_formatter.rb +39 -10
- data/lib/rubocop/formatter/emacs_style_formatter.rb +3 -1
- data/lib/rubocop/formatter/formatter_set.rb +7 -2
- data/lib/rubocop/formatter/github_actions_formatter.rb +6 -5
- data/lib/rubocop/formatter/html_formatter.rb +2 -4
- data/lib/rubocop/formatter/json_formatter.rb +82 -7
- data/lib/rubocop/formatter/junit_formatter.rb +27 -10
- data/lib/rubocop/formatter/offense_count_formatter.rb +4 -3
- data/lib/rubocop/formatter/pacman_formatter.rb +3 -1
- data/lib/rubocop/formatter/sarif_formatter.rb +186 -0
- data/lib/rubocop/formatter/simple_text_formatter.rb +4 -5
- data/lib/rubocop/formatter/tap_formatter.rb +8 -3
- data/lib/rubocop/formatter/worst_offenders_formatter.rb +5 -4
- data/lib/rubocop/formatter.rb +23 -21
- data/lib/rubocop/lockfile.rb +18 -0
- data/lib/rubocop/lsp/diagnostic.rb +22 -42
- data/lib/rubocop/lsp/disable_comment_edits.rb +135 -0
- data/lib/rubocop/lsp/routes.rb +130 -83
- data/lib/rubocop/lsp/runtime.rb +64 -15
- data/lib/rubocop/lsp/server.rb +6 -2
- data/lib/rubocop/lsp/stdin_runner.rb +35 -2
- data/lib/rubocop/lsp.rb +5 -2
- data/lib/rubocop/magic_comment.rb +47 -0
- data/lib/rubocop/mcp/autocorrection_request.rb +52 -0
- data/lib/rubocop/mcp/explain_tool.rb +68 -0
- data/lib/rubocop/mcp/scope.rb +65 -0
- data/lib/rubocop/mcp/server.rb +307 -0
- data/lib/rubocop/mcp/source_files.rb +35 -0
- data/lib/rubocop/offense_limit.rb +30 -0
- data/lib/rubocop/options.rb +141 -13
- data/lib/rubocop/path_util.rb +16 -5
- data/lib/rubocop/pending_cops_reporter.rb +1 -6
- data/lib/rubocop/plugin/configuration_integrator.rb +13 -3
- data/lib/rubocop/plugin/loader.rb +2 -2
- data/lib/rubocop/project_index_loader.rb +82 -0
- data/lib/rubocop/rake_task.rb +2 -3
- data/lib/rubocop/remote_config.rb +18 -13
- data/lib/rubocop/result_cache.rb +102 -59
- data/lib/rubocop/rspec/cop_helper.rb +8 -0
- data/lib/rubocop/rspec/expect_offense.rb +2 -4
- data/lib/rubocop/rspec/shared_contexts.rb +53 -5
- data/lib/rubocop/rspec/support.rb +2 -1
- data/lib/rubocop/runner.rb +362 -106
- data/lib/rubocop/server/cache.rb +21 -40
- data/lib/rubocop/server/cli.rb +2 -4
- data/lib/rubocop/server/core.rb +8 -0
- data/lib/rubocop/server.rb +14 -0
- data/lib/rubocop/target_finder.rb +18 -8
- data/lib/rubocop/target_ruby.rb +42 -22
- data/lib/rubocop/todo_audit.rb +111 -0
- data/lib/rubocop/unified_diff.rb +257 -0
- data/lib/rubocop/util.rb +69 -0
- data/lib/rubocop/version.rb +23 -7
- data/lib/rubocop.rb +34 -701
- data/lib/ruby_lsp/rubocop/addon.rb +1 -2
- metadata +80 -14
- data/lib/rubocop/cop/style/double_cop_disable_directive.rb +0 -46
|
@@ -60,11 +60,11 @@ module RuboCop
|
|
|
60
60
|
|
|
61
61
|
private
|
|
62
62
|
|
|
63
|
-
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
63
|
+
# rubocop:disable-next Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
64
64
|
def redundant_each_method(node)
|
|
65
65
|
return if node.last_argument&.block_pass_type?
|
|
66
66
|
|
|
67
|
-
if node.method?(:each) && !node.parent&.
|
|
67
|
+
if node.method?(:each) && !node.parent&.any_block_type?
|
|
68
68
|
ancestor_node = node.each_ancestor(:call).detect do |ancestor|
|
|
69
69
|
ancestor.receiver == node &&
|
|
70
70
|
(RESTRICT_ON_SEND.include?(ancestor.method_name) || ancestor.method?(:reverse_each))
|
|
@@ -74,14 +74,13 @@ module RuboCop
|
|
|
74
74
|
end
|
|
75
75
|
|
|
76
76
|
return unless (prev_method = node.children.first)
|
|
77
|
-
return if !prev_method.
|
|
78
|
-
prev_method.
|
|
77
|
+
return if !prev_method.call_type? || prev_method.parent.any_block_type? ||
|
|
78
|
+
prev_method.last_argument&.block_pass_type?
|
|
79
79
|
|
|
80
80
|
detected = prev_method.method_name.to_s.start_with?('each_') unless node.method?(:each)
|
|
81
81
|
|
|
82
82
|
prev_method if detected || prev_method.method?(:reverse_each)
|
|
83
83
|
end
|
|
84
|
-
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
85
84
|
|
|
86
85
|
def range(node)
|
|
87
86
|
return node.selector unless node.method?(:each)
|
|
@@ -38,6 +38,10 @@ module RuboCop
|
|
|
38
38
|
|
|
39
39
|
def fix_exploded(node)
|
|
40
40
|
exploded?(node) do |command, message|
|
|
41
|
+
# `raise RuntimeError, nil` uses the class name as the message, so
|
|
42
|
+
# rewriting it to `raise nil.to_s` (an empty message) would change it.
|
|
43
|
+
next if message.nil_type?
|
|
44
|
+
|
|
41
45
|
add_offense(node, message: MSG_1) do |corrector|
|
|
42
46
|
corrector.replace(node, replaced_exploded(node, command, message))
|
|
43
47
|
end
|
|
@@ -45,7 +49,7 @@ module RuboCop
|
|
|
45
49
|
end
|
|
46
50
|
|
|
47
51
|
def replaced_exploded(node, command, message)
|
|
48
|
-
arg =
|
|
52
|
+
arg = message_source(message)
|
|
49
53
|
arg = node.parenthesized? ? "(#{arg})" : " #{arg}"
|
|
50
54
|
"#{command}#{arg}"
|
|
51
55
|
end
|
|
@@ -56,20 +60,34 @@ module RuboCop
|
|
|
56
60
|
|
|
57
61
|
def fix_compact(node)
|
|
58
62
|
compact?(node) do |new_call, message|
|
|
63
|
+
next if message.nil_type?
|
|
64
|
+
|
|
59
65
|
add_offense(node, message: MSG_2) do |corrector|
|
|
60
|
-
corrector.replace(new_call,
|
|
66
|
+
corrector.replace(new_call, message_source(message))
|
|
61
67
|
end
|
|
62
68
|
end
|
|
63
69
|
end
|
|
64
70
|
|
|
65
|
-
def
|
|
71
|
+
def message_source(message)
|
|
66
72
|
if string_message?(message)
|
|
67
73
|
message.source
|
|
74
|
+
elsif require_parentheses?(message)
|
|
75
|
+
"(#{message.source}).to_s"
|
|
68
76
|
else
|
|
69
77
|
"#{message.source}.to_s"
|
|
70
78
|
end
|
|
71
79
|
end
|
|
72
80
|
|
|
81
|
+
def require_parentheses?(message)
|
|
82
|
+
if message.call_type?
|
|
83
|
+
!message.method?(:[]) &&
|
|
84
|
+
(message.operator_method? || (message.arguments? && !message.parenthesized?))
|
|
85
|
+
else
|
|
86
|
+
!(message.basic_literal? || message.variable? ||
|
|
87
|
+
message.type?(:const, :self, :begin, :array))
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
73
91
|
# @!method exploded?(node)
|
|
74
92
|
def_node_matcher :exploded?, <<~PATTERN
|
|
75
93
|
(send nil? ${:raise :fail} (const {nil? cbase} :RuntimeError) $_)
|
|
@@ -52,7 +52,7 @@ module RuboCop
|
|
|
52
52
|
${nil? basic_literal? const_type?})
|
|
53
53
|
PATTERN
|
|
54
54
|
|
|
55
|
-
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
|
|
55
|
+
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler, InternalAffairs/ItblockHandler -- the matched body is a literal or a constant
|
|
56
56
|
redundant_fetch_block_candidate?(node) do |send, body|
|
|
57
57
|
return if should_not_check?(send, body)
|
|
58
58
|
|
|
@@ -74,7 +74,8 @@ module RuboCop
|
|
|
74
74
|
def should_not_check?(send, body)
|
|
75
75
|
(body&.const_type? && !check_for_constant?) ||
|
|
76
76
|
(body&.str_type? && !check_for_string?) ||
|
|
77
|
-
rails_cache?(send.receiver)
|
|
77
|
+
rails_cache?(send.receiver) ||
|
|
78
|
+
unappendable_argument?(send)
|
|
78
79
|
end
|
|
79
80
|
|
|
80
81
|
# @!method rails_cache?(node)
|
|
@@ -107,6 +108,13 @@ module RuboCop
|
|
|
107
108
|
def check_for_string?
|
|
108
109
|
frozen_string_literals_enabled?
|
|
109
110
|
end
|
|
111
|
+
|
|
112
|
+
def unappendable_argument?(send)
|
|
113
|
+
argument = send.first_argument
|
|
114
|
+
|
|
115
|
+
argument.type?(:splat, :forwarded_restarg) ||
|
|
116
|
+
(argument.hash_type? && !argument.braces?)
|
|
117
|
+
end
|
|
110
118
|
end
|
|
111
119
|
end
|
|
112
120
|
end
|
|
@@ -41,6 +41,10 @@ module RuboCop
|
|
|
41
41
|
return unless name_node.value.end_with?('.rb')
|
|
42
42
|
|
|
43
43
|
extension_range = extension_range(name_node)
|
|
44
|
+
# A backslash right before the extension means the path is escaped;
|
|
45
|
+
# dropping the extension would either produce invalid Ruby (a trailing
|
|
46
|
+
# backslash escaping the closing quote) or a confusing path, so skip it.
|
|
47
|
+
return if escaped_extension?(name_node, extension_range)
|
|
44
48
|
|
|
45
49
|
add_offense(extension_range) do |corrector|
|
|
46
50
|
corrector.remove(extension_range)
|
|
@@ -55,6 +59,11 @@ module RuboCop
|
|
|
55
59
|
|
|
56
60
|
range_between(end_of_path_string - 4, end_of_path_string - 1)
|
|
57
61
|
end
|
|
62
|
+
|
|
63
|
+
def escaped_extension?(name_node, extension_range)
|
|
64
|
+
offset = extension_range.begin_pos - name_node.source_range.begin_pos
|
|
65
|
+
name_node.source[0...offset].end_with?('\\')
|
|
66
|
+
end
|
|
58
67
|
end
|
|
59
68
|
end
|
|
60
69
|
end
|
|
@@ -62,7 +62,7 @@ module RuboCop
|
|
|
62
62
|
def_node_matcher :select_predicate?, <<~PATTERN
|
|
63
63
|
(call
|
|
64
64
|
{
|
|
65
|
-
(
|
|
65
|
+
(any_block $(call _ {:select :filter :find_all}) ...)
|
|
66
66
|
$(call _ {:select :filter :find_all} block_pass_type?)
|
|
67
67
|
}
|
|
68
68
|
${:#{RESTRICT_ON_SEND.join(' :')}})
|
|
@@ -89,6 +89,8 @@ module RuboCop
|
|
|
89
89
|
|
|
90
90
|
def on_send(node)
|
|
91
91
|
format_without_additional_args?(node) do |value|
|
|
92
|
+
next if string_with_format_sequence?(value)
|
|
93
|
+
|
|
92
94
|
replacement = escape_control_chars(value.source)
|
|
93
95
|
|
|
94
96
|
add_offense(node, message: message(node, replacement)) do |corrector|
|
|
@@ -102,12 +104,31 @@ module RuboCop
|
|
|
102
104
|
|
|
103
105
|
private
|
|
104
106
|
|
|
107
|
+
# A single-argument `format` whose string still contains a format sequence is
|
|
108
|
+
# not redundant: `format('%s')` raises at runtime, and `format('%%')` returns
|
|
109
|
+
# `'%'`, so replacing it with the literal would change behavior.
|
|
110
|
+
def string_with_format_sequence?(node)
|
|
111
|
+
string = static_string_value(node)
|
|
112
|
+
return false unless string
|
|
113
|
+
|
|
114
|
+
RuboCop::Cop::Utils::FormatString.new(string).format_sequences.any?
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def static_string_value(node)
|
|
118
|
+
if node.str_type?
|
|
119
|
+
node.value
|
|
120
|
+
elsif node.dstr_type?
|
|
121
|
+
node.children.select(&:str_type?).map(&:value).join
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
105
125
|
def message(node, prefer)
|
|
106
126
|
format(MSG, prefer: prefer, method_name: node.method_name)
|
|
107
127
|
end
|
|
108
128
|
|
|
109
129
|
def detect_unnecessary_fields(node)
|
|
110
130
|
return unless node.first_argument&.str_type?
|
|
131
|
+
return if node.first_argument.heredoc?
|
|
111
132
|
|
|
112
133
|
string = node.first_argument.value
|
|
113
134
|
arguments = node.arguments[1..]
|
|
@@ -134,7 +155,7 @@ module RuboCop
|
|
|
134
155
|
end
|
|
135
156
|
end
|
|
136
157
|
|
|
137
|
-
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
158
|
+
# rubocop:disable-next Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
138
159
|
def all_fields_literal?(string, arguments)
|
|
139
160
|
count = 0
|
|
140
161
|
sequences = RuboCop::Cop::Utils::FormatString.new(string).format_sequences
|
|
@@ -154,18 +175,17 @@ module RuboCop
|
|
|
154
175
|
|
|
155
176
|
sequences.size == count
|
|
156
177
|
end
|
|
157
|
-
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
158
178
|
|
|
159
179
|
# If the sequence has a variable (`*`) width, it cannot be autocorrected
|
|
160
180
|
# if the width is not given as a numeric literal argument
|
|
161
181
|
def unknown_variable_width?(sequence, arguments)
|
|
162
182
|
return false unless sequence.variable_width?
|
|
163
183
|
|
|
164
|
-
argument = arguments
|
|
165
|
-
!numeric?(argument)
|
|
184
|
+
argument = positional_argument(arguments, sequence.variable_width_argument_number)
|
|
185
|
+
argument.nil? || !numeric?(argument)
|
|
166
186
|
end
|
|
167
187
|
|
|
168
|
-
# rubocop:disable Metrics/AbcSize
|
|
188
|
+
# rubocop:disable-next Metrics/AbcSize
|
|
169
189
|
def find_argument(sequence, arguments, hash)
|
|
170
190
|
if hash && (sequence.annotated? || sequence.template?)
|
|
171
191
|
find_hash_value_node(hash, sequence.name.to_sym).first
|
|
@@ -174,12 +194,11 @@ module RuboCop
|
|
|
174
194
|
arguments.delete_at(sequence.variable_width_argument_number - 1)
|
|
175
195
|
arguments.shift
|
|
176
196
|
elsif sequence.arg_number
|
|
177
|
-
arguments
|
|
197
|
+
positional_argument(arguments, sequence.arg_number.to_i)
|
|
178
198
|
else
|
|
179
199
|
arguments.shift
|
|
180
200
|
end
|
|
181
201
|
end
|
|
182
|
-
# rubocop:enable Metrics/AbcSize
|
|
183
202
|
|
|
184
203
|
def matching_argument?(sequence, argument)
|
|
185
204
|
# Template specifiers don't give a type, any acceptable literal type is ok.
|
|
@@ -199,6 +218,15 @@ module RuboCop
|
|
|
199
218
|
end
|
|
200
219
|
end
|
|
201
220
|
|
|
221
|
+
# `Array#[]` raises `RangeError` for an index beyond the 64-bit range
|
|
222
|
+
# (e.g. `format('%*9999999999999999999999$d', 1)`) instead of returning `nil`,
|
|
223
|
+
# so the index needs to be checked before accessing the array.
|
|
224
|
+
def positional_argument(arguments, number)
|
|
225
|
+
index = number - 1
|
|
226
|
+
|
|
227
|
+
arguments[index] if index < arguments.size
|
|
228
|
+
end
|
|
229
|
+
|
|
202
230
|
def numeric?(argument)
|
|
203
231
|
argument.type?(:numeric, :str) ||
|
|
204
232
|
rational_number?(argument) ||
|
|
@@ -245,6 +273,14 @@ module RuboCop
|
|
|
245
273
|
def argument_value(argument)
|
|
246
274
|
argument = argument.children.first if argument.begin_type?
|
|
247
275
|
|
|
276
|
+
# `nil` formats to an empty string (`format('%s', nil) == ''`), not the
|
|
277
|
+
# literal `'nil'` that `argument.source` would return.
|
|
278
|
+
return if argument.nil_type?
|
|
279
|
+
|
|
280
|
+
typed_argument_value(argument)
|
|
281
|
+
end
|
|
282
|
+
|
|
283
|
+
def typed_argument_value(argument)
|
|
248
284
|
if argument.dsym_type?
|
|
249
285
|
dsym_value(argument)
|
|
250
286
|
elsif argument.hash_type?
|
|
@@ -29,8 +29,7 @@ module RuboCop
|
|
|
29
29
|
operation_produces_immutable_object?(node.receiver))
|
|
30
30
|
|
|
31
31
|
add_offense(node) do |corrector|
|
|
32
|
-
corrector.remove(node.loc.dot)
|
|
33
|
-
corrector.remove(node.loc.selector)
|
|
32
|
+
corrector.remove(node.loc.dot.join(node.loc.selector))
|
|
34
33
|
end
|
|
35
34
|
end
|
|
36
35
|
|
|
@@ -57,12 +56,21 @@ module RuboCop
|
|
|
57
56
|
def_node_matcher :operation_produces_immutable_object?, <<~PATTERN
|
|
58
57
|
{
|
|
59
58
|
(begin (send {float int} {:+ :- :* :** :/ :% :<<} _))
|
|
60
|
-
(begin (send
|
|
59
|
+
(begin (send #numeric_operation? {:+ :- :* :** :/ :%} {float int}))
|
|
61
60
|
(begin (send _ {:== :=== :!= :<= :>= :< :>} _))
|
|
62
61
|
(send _ {:count :length :size} ...)
|
|
63
62
|
(any_block (send _ {:count :length :size} ...) ...)
|
|
64
63
|
}
|
|
65
64
|
PATTERN
|
|
65
|
+
|
|
66
|
+
# @!method numeric_operation?(node)
|
|
67
|
+
def_node_matcher :numeric_operation?, <<~PATTERN
|
|
68
|
+
{
|
|
69
|
+
float int
|
|
70
|
+
(begin #numeric_operation?)
|
|
71
|
+
(send #numeric_operation? {:+ :- :* :** :/ :%} #numeric_operation?)
|
|
72
|
+
}
|
|
73
|
+
PATTERN
|
|
66
74
|
end
|
|
67
75
|
end
|
|
68
76
|
end
|
|
@@ -48,8 +48,13 @@ module RuboCop
|
|
|
48
48
|
def need_heredoc_delimiter_quotes?(node)
|
|
49
49
|
heredoc_delimiter = node.source.delete(heredoc_type(node))
|
|
50
50
|
return true unless heredoc_delimiter.start_with?("'", '"')
|
|
51
|
+
return true if node.loc.heredoc_end.source.strip.match?(/\W/)
|
|
51
52
|
|
|
52
|
-
|
|
53
|
+
# A double-quoted delimiter interpolates exactly like an unquoted one,
|
|
54
|
+
# so its quotes are always redundant. A single-quoted delimiter is
|
|
55
|
+
# required when the body contains interpolation or escapes that would
|
|
56
|
+
# otherwise be evaluated.
|
|
57
|
+
heredoc_delimiter.start_with?("'") &&
|
|
53
58
|
node.loc.heredoc_body.source.match?(STRING_INTERPOLATION_OR_ESCAPED_CHARACTER_PATTERN)
|
|
54
59
|
end
|
|
55
60
|
end
|
|
@@ -15,6 +15,9 @@ module RuboCop
|
|
|
15
15
|
# # bad
|
|
16
16
|
# "#{foo} bar".dup
|
|
17
17
|
#
|
|
18
|
+
# # bad
|
|
19
|
+
# String.new("#{foo} bar")
|
|
20
|
+
#
|
|
18
21
|
# # good
|
|
19
22
|
# "#{foo} bar"
|
|
20
23
|
#
|
|
@@ -25,19 +28,55 @@ module RuboCop
|
|
|
25
28
|
|
|
26
29
|
MSG = "Don't unfreeze interpolated strings as they are already unfrozen."
|
|
27
30
|
|
|
28
|
-
RESTRICT_ON_SEND = %i[+@ dup].freeze
|
|
29
|
-
|
|
30
31
|
minimum_target_ruby_version 3.0
|
|
31
32
|
|
|
32
|
-
def
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
33
|
+
def self.autocorrect_incompatible_with
|
|
34
|
+
[Layout::MultilineMethodCallBraceLayout]
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# @!method redundant_unfreeze?(node)
|
|
38
|
+
def_node_matcher :redundant_unfreeze?, <<~PATTERN
|
|
39
|
+
{
|
|
40
|
+
(send dstr_type? {:+@ :dup})
|
|
41
|
+
(send (const nil? :String) :new dstr_type?)
|
|
42
|
+
}
|
|
43
|
+
PATTERN
|
|
44
|
+
|
|
45
|
+
def on_dstr(node)
|
|
46
|
+
return if uninterpolated_string?(node) || uninterpolated_heredoc?(node)
|
|
47
|
+
return unless redundant_unfreeze?(node.parent)
|
|
48
|
+
return if comment_outside_string?(node)
|
|
49
|
+
|
|
50
|
+
add_offense(offense_range(node.parent)) do |corrector|
|
|
51
|
+
remove_unfreeze(corrector, node.parent, node)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
private
|
|
56
|
+
|
|
57
|
+
def offense_range(node)
|
|
58
|
+
if node.method?(:new)
|
|
59
|
+
node.source_range.begin.join(node.loc.selector)
|
|
60
|
+
else
|
|
61
|
+
node.loc.selector
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Only the parts around the string are removed, so that an unfrozen string
|
|
66
|
+
# interpolated into it can be corrected in the same pass.
|
|
67
|
+
def remove_unfreeze(corrector, node, string)
|
|
68
|
+
corrector.remove(node.source_range.begin.join(string.source_range.begin))
|
|
69
|
+
corrector.remove(string.source_range.end.join(node.source_range.end))
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def comment_outside_string?(node)
|
|
73
|
+
call_range = node.parent.source_range
|
|
74
|
+
string_range = node.source_range
|
|
75
|
+
|
|
76
|
+
processed_source.comments.any? do |comment|
|
|
77
|
+
range = comment.source_range
|
|
37
78
|
|
|
38
|
-
|
|
39
|
-
corrector.remove(node.loc.selector)
|
|
40
|
-
corrector.remove(node.loc.dot) unless node.unary_operation?
|
|
79
|
+
call_range.contains?(range) && !string_range.contains?(range)
|
|
41
80
|
end
|
|
42
81
|
end
|
|
43
82
|
end
|
|
@@ -5,10 +5,13 @@ module RuboCop
|
|
|
5
5
|
module Style
|
|
6
6
|
# Checks for redundant line continuation.
|
|
7
7
|
#
|
|
8
|
-
#
|
|
9
|
-
#
|
|
10
|
-
#
|
|
11
|
-
#
|
|
8
|
+
# A line continuation is redundant when removing the backslash does not
|
|
9
|
+
# change how the program parses: the source is reparsed without the
|
|
10
|
+
# backslash and the resulting AST is compared to the original. Only
|
|
11
|
+
# backslashes that are pure noise are reported; backslashes that are
|
|
12
|
+
# significant — inside strings, for string concatenation, before an
|
|
13
|
+
# operator or argument that would otherwise start a new statement, and
|
|
14
|
+
# so on — are left alone, as are backslashes in comments.
|
|
12
15
|
#
|
|
13
16
|
# @example
|
|
14
17
|
# # bad
|
|
@@ -66,30 +69,23 @@ module RuboCop
|
|
|
66
69
|
#
|
|
67
70
|
class RedundantLineContinuation < Base
|
|
68
71
|
include MatchRange
|
|
72
|
+
include ReparsedEquivalence
|
|
69
73
|
extend AutoCorrector
|
|
70
74
|
|
|
71
75
|
MSG = 'Redundant line continuation.'
|
|
72
76
|
LINE_CONTINUATION = '\\'
|
|
73
77
|
LINE_CONTINUATION_PATTERN = /(\\\n)/.freeze
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
tCVAR tDOT2 tDOT3 tFLOAT tGVAR tIDENTIFIER tINTEGER tIVAR tLAMBDA tLBRACK tLCURLY
|
|
78
|
-
tLPAREN_ARG tPIPE tQSYMBOLS_BEG tQWORDS_BEG tREGEXP_BEG tSTAR tSTRING tSTRING_BEG tSYMBEG
|
|
79
|
-
tSYMBOL tSYMBOLS_BEG tTILDE tUMINUS tUNARY_NUM tUPLUS tWORDS_BEG tXSTRING_BEG
|
|
80
|
-
].freeze
|
|
81
|
-
ARGUMENT_TAKING_FLOW_TOKEN_TYPES = %i[
|
|
82
|
-
tIDENTIFIER kBREAK kNEXT kRETURN kSUPER kYIELD
|
|
83
|
-
].freeze
|
|
84
|
-
ARITHMETIC_OPERATOR_TOKENS = %i[tDIVIDE tDSTAR tMINUS tPERCENT tPLUS tSTAR2].freeze
|
|
78
|
+
STRING_TOKEN_TYPES = %i[tSTRING tSTRING_CONTENT].freeze
|
|
79
|
+
STRING_LITERAL_ENDING_TOKEN_TYPES = %i[tSTRING tSTRING_END].freeze
|
|
80
|
+
STRING_LITERAL_BEGINNING_TOKEN_TYPES = %i[tSTRING tSTRING_BEG].freeze
|
|
85
81
|
|
|
86
82
|
def on_new_investigation
|
|
87
83
|
return unless processed_source.ast
|
|
88
84
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
85
|
+
# A backslash is redundant if the source parses to the same AST
|
|
86
|
+
# without it; verification is the offense logic itself, so oversized
|
|
87
|
+
# scopes are reparsed regardless of size.
|
|
88
|
+
verified_by_reparse(line_continuation_candidates, oversized: :verify).each do |range|
|
|
93
89
|
add_offense(range) do |corrector|
|
|
94
90
|
corrector.remove_leading(range, 1)
|
|
95
91
|
end
|
|
@@ -100,135 +96,106 @@ module RuboCop
|
|
|
100
96
|
|
|
101
97
|
private
|
|
102
98
|
|
|
103
|
-
def
|
|
104
|
-
|
|
105
|
-
string_concatenation?(range.source_line) ||
|
|
106
|
-
start_with_arithmetic_operator?(range) ||
|
|
107
|
-
inside_string_literal_or_method_with_argument?(range) ||
|
|
108
|
-
leading_dot_method_chain_with_blank_line?(range)
|
|
99
|
+
def apply_reparse_correction(corrector, range)
|
|
100
|
+
corrector.remove_leading(range, 1)
|
|
109
101
|
end
|
|
110
102
|
|
|
111
|
-
def
|
|
112
|
-
|
|
113
|
-
# means that it is impossible to have a comment following a continuation.
|
|
114
|
-
# Therefore, if the line contains a comment, it cannot end with a continuation.
|
|
115
|
-
return false if processed_source.line_with_comment?(range.line)
|
|
116
|
-
|
|
117
|
-
range.source_line.end_with?(LINE_CONTINUATION)
|
|
118
|
-
end
|
|
103
|
+
def line_continuation_candidates
|
|
104
|
+
candidates = []
|
|
119
105
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
106
|
+
each_match_range(processed_source.ast.source_range, LINE_CONTINUATION_PATTERN) do |range|
|
|
107
|
+
next if within_comment?(range) || implicit_string_concatenation?(range)
|
|
108
|
+
next if within_string_content?(range)
|
|
109
|
+
next if leading_dot_method_chain_with_blank_line?(range)
|
|
123
110
|
|
|
124
|
-
|
|
125
|
-
|
|
111
|
+
candidates << range
|
|
112
|
+
end
|
|
126
113
|
|
|
127
|
-
|
|
128
|
-
|
|
114
|
+
candidates
|
|
115
|
+
end
|
|
129
116
|
|
|
130
|
-
|
|
131
|
-
|
|
117
|
+
def within_comment?(range)
|
|
118
|
+
processed_source.comments.any? do |comment|
|
|
119
|
+
comment.source_range.overlaps?(range)
|
|
132
120
|
end
|
|
133
121
|
end
|
|
134
122
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
123
|
+
# A backslash directly joining two string literals is never redundant:
|
|
124
|
+
# removing it moves the second literal onto its own logical line,
|
|
125
|
+
# severing the implicit string concatenation. Skipping these up front
|
|
126
|
+
# avoids reparse verification, which is prohibitively slow on generated
|
|
127
|
+
# files gluing thousands of string fragments with line continuations.
|
|
128
|
+
def implicit_string_concatenation?(range)
|
|
129
|
+
tokens = processed_source.sorted_tokens
|
|
140
130
|
|
|
141
|
-
|
|
142
|
-
return
|
|
143
|
-
return false if argument_newline?(node)
|
|
131
|
+
token_before = last_token_before(tokens, range)
|
|
132
|
+
return false unless string_literal_ending_on_line?(token_before, range.line)
|
|
144
133
|
|
|
145
|
-
|
|
146
|
-
source = processed_source.raw_source.dup
|
|
147
|
-
source[range.begin_pos, range.length] = "\n"
|
|
148
|
-
parse(source).valid_syntax?
|
|
134
|
+
string_literal_beginning_on_line?(first_token_after(tokens, range), range.line + 1)
|
|
149
135
|
end
|
|
150
136
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
add_offense(line_continuation_range) do |corrector|
|
|
159
|
-
corrector.remove_trailing(line_continuation_range, 1)
|
|
137
|
+
# A backslash in string content is never a redundant line continuation
|
|
138
|
+
# (removing it changes the string's value, which the reparse check would
|
|
139
|
+
# detect); skipping it up front just avoids a useless reparse.
|
|
140
|
+
def within_string_content?(range)
|
|
141
|
+
@string_content_ranges ||= processed_source.tokens.filter_map do |token|
|
|
142
|
+
token.pos if STRING_TOKEN_TYPES.include?(token.type)
|
|
160
143
|
end
|
|
144
|
+
|
|
145
|
+
@string_content_ranges.any? { |pos| pos.overlaps?(range) }
|
|
161
146
|
end
|
|
162
147
|
|
|
163
|
-
|
|
164
|
-
|
|
148
|
+
# The `parser` gem, unlike Ruby itself, accepts a leading-dot method
|
|
149
|
+
# chain continued across a blank line, so the reparse check alone would
|
|
150
|
+
# deem the backslash redundant even though removing it breaks the code
|
|
151
|
+
# on MRI. Prism matches Ruby here and does not need this guard.
|
|
152
|
+
def leading_dot_method_chain_with_blank_line?(range)
|
|
153
|
+
return false unless range.source_line.strip.start_with?('.', '&.')
|
|
165
154
|
|
|
166
|
-
|
|
155
|
+
processed_source[range.line].strip.empty?
|
|
167
156
|
end
|
|
168
157
|
|
|
169
|
-
def
|
|
170
|
-
|
|
158
|
+
def last_token_before(tokens, range)
|
|
159
|
+
index = tokens.bsearch_index { |token| token.end_pos > range.begin_pos }
|
|
160
|
+
index&.positive? ? tokens[index - 1] : nil
|
|
171
161
|
end
|
|
172
162
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
# do_something \
|
|
176
|
-
# argument
|
|
177
|
-
def method_with_argument?(line_range, current_token, next_token)
|
|
178
|
-
return false unless ARGUMENT_TAKING_FLOW_TOKEN_TYPES.include?(current_token.type)
|
|
179
|
-
return false unless current_token.pos.overlaps?(line_range)
|
|
180
|
-
|
|
181
|
-
ARGUMENT_TYPES.include?(next_token.type)
|
|
163
|
+
def first_token_after(tokens, range)
|
|
164
|
+
tokens.bsearch { |token| token.begin_pos >= range.end_pos }
|
|
182
165
|
end
|
|
183
166
|
|
|
184
|
-
def
|
|
185
|
-
return false
|
|
186
|
-
|
|
187
|
-
node = node.children.first if node.root? && node.begin_type?
|
|
188
|
-
|
|
189
|
-
if argument_is_method?(node)
|
|
190
|
-
argument_newline?(node.first_argument)
|
|
191
|
-
else
|
|
192
|
-
return false unless method_call_with_arguments?(node)
|
|
193
|
-
|
|
194
|
-
node.loc.selector.line != node.first_argument.loc.line
|
|
195
|
-
end
|
|
196
|
-
end
|
|
167
|
+
def string_literal_ending_on_line?(token, line)
|
|
168
|
+
return false unless token
|
|
197
169
|
|
|
198
|
-
|
|
199
|
-
processed_source.ast.each_node do |node|
|
|
200
|
-
return node if same_line?(node, last_line)
|
|
201
|
-
end
|
|
170
|
+
STRING_LITERAL_ENDING_TOKEN_TYPES.include?(token.type) && token.pos.last_line == line
|
|
202
171
|
end
|
|
203
172
|
|
|
204
|
-
def
|
|
205
|
-
return false unless
|
|
173
|
+
def string_literal_beginning_on_line?(token, line)
|
|
174
|
+
return false unless token
|
|
206
175
|
|
|
207
|
-
|
|
208
|
-
if node.heredoc?
|
|
209
|
-
(node.loc.heredoc_body.line..node.loc.heredoc_body.last_line).cover?(line)
|
|
210
|
-
else
|
|
211
|
-
(source_range.line..source_range.last_line).cover?(line)
|
|
212
|
-
end
|
|
213
|
-
else
|
|
214
|
-
source_range.line == line
|
|
215
|
-
end
|
|
176
|
+
STRING_LITERAL_BEGINNING_TOKEN_TYPES.include?(token.type) && token.line == line
|
|
216
177
|
end
|
|
217
178
|
|
|
218
|
-
def
|
|
219
|
-
|
|
220
|
-
|
|
179
|
+
def inspect_end_of_ruby_code_line_continuation
|
|
180
|
+
last_line_number = processed_source.ast.last_line
|
|
181
|
+
last_line = processed_source.lines[last_line_number - 1]
|
|
182
|
+
return unless last_line&.end_with?(LINE_CONTINUATION)
|
|
221
183
|
|
|
222
|
-
|
|
223
|
-
|
|
184
|
+
range = trailing_line_continuation_range(last_line_number)
|
|
185
|
+
return if within_comment?(range)
|
|
186
|
+
return if verified_by_reparse([range], oversized: :verify).empty?
|
|
224
187
|
|
|
225
|
-
|
|
226
|
-
|
|
188
|
+
add_offense(range) do |corrector|
|
|
189
|
+
corrector.remove_trailing(range, 1)
|
|
190
|
+
end
|
|
227
191
|
end
|
|
228
192
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
193
|
+
# The backslash is the last character of the line; locate it by the line's
|
|
194
|
+
# position in the buffer rather than treating the column as an absolute offset
|
|
195
|
+
# (which corrupts an earlier line in multi-line files).
|
|
196
|
+
def trailing_line_continuation_range(line_number)
|
|
197
|
+
line_range = processed_source.buffer.line_range(line_number)
|
|
198
|
+
range_between(line_range.end_pos - 1, line_range.end_pos)
|
|
232
199
|
end
|
|
233
200
|
end
|
|
234
201
|
end
|