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
|
@@ -13,8 +13,7 @@ module RuboCop
|
|
|
13
13
|
buffer = node.source_range.source_buffer
|
|
14
14
|
corrector.remove(range_with_surrounding_space(range: node.loc.begin, buffer: buffer,
|
|
15
15
|
side: :right, whitespace: true))
|
|
16
|
-
corrector
|
|
17
|
-
side: :left))
|
|
16
|
+
remove_close_paren(corrector, node, buffer)
|
|
18
17
|
handle_orphaned_comma(corrector, node)
|
|
19
18
|
|
|
20
19
|
return unless ternary_condition?(node) && next_char_is_question_mark?(node)
|
|
@@ -22,8 +21,77 @@ module RuboCop
|
|
|
22
21
|
corrector.insert_after(node.loc.end, ' ')
|
|
23
22
|
end
|
|
24
23
|
|
|
24
|
+
def heredoc_strands_code_after_close_paren?(node)
|
|
25
|
+
return false unless heredoc_body_before_close_paren?(node)
|
|
26
|
+
|
|
27
|
+
after_paren = text_after_close_paren(node)
|
|
28
|
+
|
|
29
|
+
!after_paren.empty? && !after_paren.start_with?('.', '&.', ',')
|
|
30
|
+
end
|
|
31
|
+
|
|
25
32
|
private
|
|
26
33
|
|
|
34
|
+
# When the line above `)` ends with a comment and a chained call follows `)`,
|
|
35
|
+
# crossing the newline would pull the chain into the comment. Preserve the newline.
|
|
36
|
+
# When a heredoc body comes before `)`, a chained call has to start on the line
|
|
37
|
+
# after the terminator instead, since the terminator must stay alone on its line.
|
|
38
|
+
def remove_close_paren(corrector, node, buffer)
|
|
39
|
+
if heredoc_above_close_paren_swallows_chain?(node)
|
|
40
|
+
range = range_with_surrounding_space(range: node.loc.end, buffer: buffer, side: :left)
|
|
41
|
+
|
|
42
|
+
corrector.replace(range, "\n")
|
|
43
|
+
else
|
|
44
|
+
newlines = !comment_above_close_paren_swallows_chain?(node, buffer)
|
|
45
|
+
range = range_with_surrounding_space(
|
|
46
|
+
range: node.loc.end, buffer: buffer, side: :left, newlines: newlines
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
corrector.remove(range)
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def heredoc_above_close_paren_swallows_chain?(node)
|
|
54
|
+
return false unless heredoc_body_before_close_paren?(node)
|
|
55
|
+
|
|
56
|
+
text_after_close_paren(node).start_with?('.', '&.')
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def heredoc_body_before_close_paren?(node)
|
|
60
|
+
return false unless (last_child = node.children.last)
|
|
61
|
+
|
|
62
|
+
close_paren_pos = node.loc.end.begin_pos
|
|
63
|
+
|
|
64
|
+
last_child.each_node(:any_str).any? do |str_node|
|
|
65
|
+
str_node.heredoc? && str_node.loc.heredoc_end.end_pos <= close_paren_pos
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def text_after_close_paren(node)
|
|
70
|
+
close_paren = node.loc.end
|
|
71
|
+
|
|
72
|
+
close_paren.source_line[(close_paren.column + 1)..].to_s.lstrip
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def comment_above_close_paren_swallows_chain?(node, buffer)
|
|
76
|
+
last_child = node.children.last
|
|
77
|
+
return false unless last_child
|
|
78
|
+
|
|
79
|
+
body_end = last_child.source_range.end_pos
|
|
80
|
+
close_paren_begin = node.loc.end.begin_pos
|
|
81
|
+
return false if body_end >= close_paren_begin
|
|
82
|
+
|
|
83
|
+
source_between = buffer.source[body_end...close_paren_begin]
|
|
84
|
+
return false unless source_between.match?(/#[^\n]*\n/)
|
|
85
|
+
|
|
86
|
+
chained_after_close_paren?(node)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def chained_after_close_paren?(node)
|
|
90
|
+
trimmed = text_after_close_paren(node)
|
|
91
|
+
|
|
92
|
+
!trimmed.empty? && !trimmed.start_with?('#')
|
|
93
|
+
end
|
|
94
|
+
|
|
27
95
|
def ternary_condition?(node)
|
|
28
96
|
node.parent&.if_type? && node.parent.ternary?
|
|
29
97
|
end
|
|
@@ -97,8 +97,8 @@ module RuboCop
|
|
|
97
97
|
if delimiters.first != delimiters.last
|
|
98
98
|
# With different delimiters (eg. `[]`, `()`), if there are the same
|
|
99
99
|
# number of each, escaping is not necessary
|
|
100
|
-
delimiter_counts = delimiters.
|
|
101
|
-
|
|
100
|
+
delimiter_counts = delimiters.to_h do |delimiter|
|
|
101
|
+
[delimiter, content.count(delimiter)]
|
|
102
102
|
end
|
|
103
103
|
|
|
104
104
|
return content if delimiter_counts[delimiters.first] == delimiter_counts[delimiters.last]
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module Cop # rubocop:disable Style/Documentation -- a namespace that only autoloads the correctors below
|
|
5
|
+
# Autoloads corrector classes used by cops. Classes are autoloaded to reduce the number of
|
|
6
|
+
# required classes because they're referenced only when autocorrection is performed.
|
|
7
|
+
|
|
8
|
+
# rubocop:disable Layout/LineLength -- the autoload paths do not wrap
|
|
9
|
+
autoload :AlignmentCorrector, 'rubocop/cop/correctors/alignment_corrector'
|
|
10
|
+
autoload :ConditionCorrector, 'rubocop/cop/correctors/condition_corrector'
|
|
11
|
+
autoload :EachToForCorrector, 'rubocop/cop/correctors/each_to_for_corrector'
|
|
12
|
+
autoload :EmptyLineCorrector, 'rubocop/cop/correctors/empty_line_corrector'
|
|
13
|
+
autoload :ForToEachCorrector, 'rubocop/cop/correctors/for_to_each_corrector'
|
|
14
|
+
autoload :IfThenCorrector, 'rubocop/cop/correctors/if_then_corrector'
|
|
15
|
+
autoload :LambdaLiteralToMethodCorrector, 'rubocop/cop/correctors/lambda_literal_to_method_corrector'
|
|
16
|
+
autoload :LineBreakCorrector, 'rubocop/cop/correctors/line_break_corrector'
|
|
17
|
+
autoload :MultilineLiteralBraceCorrector, 'rubocop/cop/correctors/multiline_literal_brace_corrector'
|
|
18
|
+
autoload :OrderedGemCorrector, 'rubocop/cop/correctors/ordered_gem_corrector'
|
|
19
|
+
autoload :ParenthesesCorrector, 'rubocop/cop/correctors/parentheses_corrector'
|
|
20
|
+
autoload :PercentLiteralCorrector, 'rubocop/cop/correctors/percent_literal_corrector'
|
|
21
|
+
autoload :PunctuationCorrector, 'rubocop/cop/correctors/punctuation_corrector'
|
|
22
|
+
autoload :RequireLibraryCorrector, 'rubocop/cop/correctors/require_library_corrector'
|
|
23
|
+
autoload :SpaceCorrector, 'rubocop/cop/correctors/space_corrector'
|
|
24
|
+
autoload :StringLiteralCorrector, 'rubocop/cop/correctors/string_literal_corrector'
|
|
25
|
+
autoload :UnusedArgCorrector, 'rubocop/cop/correctors/unused_arg_corrector'
|
|
26
|
+
# rubocop:enable Layout/LineLength
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -14,7 +14,7 @@ module RuboCop
|
|
|
14
14
|
# @api private
|
|
15
15
|
def url_for(cop_class, config = nil)
|
|
16
16
|
base = department_to_basename(cop_class.department)
|
|
17
|
-
fragment = cop_class.cop_name.downcase.
|
|
17
|
+
fragment = cop_class.cop_name.downcase.delete('/')
|
|
18
18
|
base_url = base_url_for(cop_class, config)
|
|
19
19
|
extension = extension_for(cop_class, config)
|
|
20
20
|
|
|
@@ -55,10 +55,9 @@ module RuboCop
|
|
|
55
55
|
|
|
56
56
|
# @api private
|
|
57
57
|
def builtin?(cop_class)
|
|
58
|
-
|
|
59
|
-
return false unless (m = cop_class.instance_methods(false).first)
|
|
58
|
+
return false unless (name = cop_class.name)
|
|
60
59
|
|
|
61
|
-
path, _line =
|
|
60
|
+
path, _line = Module.const_source_location(name)
|
|
62
61
|
path.start_with?(__dir__)
|
|
63
62
|
end
|
|
64
63
|
end
|
|
@@ -4,16 +4,42 @@ module RuboCop
|
|
|
4
4
|
# Allows specified configuration options to have an exclude limit
|
|
5
5
|
# ie. a maximum value tracked that it can be used by `--auto-gen-config`.
|
|
6
6
|
module ExcludeLimit
|
|
7
|
+
class << self
|
|
8
|
+
attr_accessor :tmp_dir
|
|
9
|
+
|
|
10
|
+
# Reads the aggregated exclude limit values for a cop from tmp files.
|
|
11
|
+
# Returns a hash like { 'Max' => 81 } or an empty hash if no values were written.
|
|
12
|
+
def read_limits(cop_name)
|
|
13
|
+
cop_dir = cop_dir_for(cop_name)
|
|
14
|
+
return {} unless cop_dir&.directory?
|
|
15
|
+
|
|
16
|
+
limits = {}
|
|
17
|
+
cop_dir.children.each do |filepath|
|
|
18
|
+
next unless filepath.file?
|
|
19
|
+
|
|
20
|
+
values = filepath.readlines.map(&:to_i)
|
|
21
|
+
limits[filepath.basename.to_s] = values.max unless values.empty?
|
|
22
|
+
end
|
|
23
|
+
limits
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Returns the tmp directory path for a given cop, or nil if tmp_dir is not set.
|
|
27
|
+
def cop_dir_for(cop_name)
|
|
28
|
+
tmp_dir&.join(cop_name.tr('/', '-'))
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
7
32
|
# Sets up a configuration option to have an exclude limit tracked.
|
|
8
33
|
# The parameter name given is transformed into a method name (eg. `Max`
|
|
9
34
|
# becomes `self.max=` and `MinDigits` becomes `self.min_digits=`).
|
|
10
35
|
def exclude_limit(parameter_name, method_name: transform(parameter_name))
|
|
11
36
|
define_method(:"#{method_name}=") do |value|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
37
|
+
cop_dir = RuboCop::ExcludeLimit.cop_dir_for(self.class.badge.to_s)
|
|
38
|
+
return unless cop_dir
|
|
39
|
+
|
|
40
|
+
cop_dir.mkpath
|
|
41
|
+
filepath = cop_dir.join(parameter_name)
|
|
42
|
+
filepath.write("#{value}\n", mode: 'a')
|
|
17
43
|
end
|
|
18
44
|
end
|
|
19
45
|
|
|
@@ -109,12 +109,6 @@ module RuboCop
|
|
|
109
109
|
end
|
|
110
110
|
end
|
|
111
111
|
|
|
112
|
-
def match_block_variable_name?(receiver_name)
|
|
113
|
-
gem_specification(processed_source.ast) do |block_variable_name|
|
|
114
|
-
return block_variable_name == receiver_name
|
|
115
|
-
end
|
|
116
|
-
end
|
|
117
|
-
|
|
118
112
|
def add_dependency_method?(method_name)
|
|
119
113
|
ADD_DEPENDENCY_METHODS.include?(method_name)
|
|
120
114
|
end
|
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
module RuboCop
|
|
4
4
|
module Cop
|
|
5
5
|
module Gemspec
|
|
6
|
-
# An attribute assignment method
|
|
6
|
+
# An attribute assignment method call should be listed only once
|
|
7
7
|
# in a gemspec.
|
|
8
8
|
#
|
|
9
9
|
# Assigning to an attribute with the same name using `spec.foo =` or
|
|
10
10
|
# `spec.attribute#[]=` will be an unintended usage. On the other hand,
|
|
11
|
-
# duplication of methods such
|
|
11
|
+
# duplication of methods such as `spec.requirements`,
|
|
12
12
|
# `spec.add_runtime_dependency`, and others are permitted because it is
|
|
13
13
|
# the intended use of appending values.
|
|
14
14
|
#
|
|
@@ -83,18 +83,28 @@ module RuboCop
|
|
|
83
83
|
def duplicated_assignment_method_nodes
|
|
84
84
|
assignment_method_declarations(processed_source.ast)
|
|
85
85
|
.select(&:assignment_method?)
|
|
86
|
-
.group_by(
|
|
86
|
+
.group_by { |node| [enclosing_specification(node), node.method_name] }
|
|
87
87
|
.values
|
|
88
88
|
.select { |nodes| nodes.size > 1 }
|
|
89
89
|
end
|
|
90
90
|
|
|
91
91
|
def duplicated_indexed_assignment_method_nodes
|
|
92
92
|
indexed_assignment_method_declarations(processed_source.ast)
|
|
93
|
-
.group_by { |node|
|
|
93
|
+
.group_by { |node| indexed_assignment_key(node) }
|
|
94
94
|
.values
|
|
95
95
|
.select { |nodes| nodes.size > 1 }
|
|
96
96
|
end
|
|
97
97
|
|
|
98
|
+
def indexed_assignment_key(node)
|
|
99
|
+
[enclosing_specification(node), node.children.first.method_name, node.first_argument]
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# Assignments in separate `Gem::Specification.new` blocks are not duplicates of
|
|
103
|
+
# one another, so the enclosing specification is part of the grouping key.
|
|
104
|
+
def enclosing_specification(node)
|
|
105
|
+
node.each_ancestor(:block).find { |block| gem_specification?(block) }
|
|
106
|
+
end
|
|
107
|
+
|
|
98
108
|
def register_offense(node, assignment, line_of_first_occurrence)
|
|
99
109
|
line_range = node.loc.column...node.loc.last_column
|
|
100
110
|
offense_location = source_range(processed_source.buffer, node.first_line, line_range)
|
|
@@ -69,8 +69,7 @@ module RuboCop
|
|
|
69
69
|
def on_new_investigation
|
|
70
70
|
return if processed_source.blank?
|
|
71
71
|
|
|
72
|
-
dependency_declarations(processed_source.ast)
|
|
73
|
-
.each_cons(2) do |previous, current|
|
|
72
|
+
dependency_declarations(processed_source.ast).each_cons(2) do |previous, current|
|
|
74
73
|
next unless consecutive_lines?(previous, current)
|
|
75
74
|
next unless case_insensitive_out_of_order?(gem_name(current), gem_name(previous))
|
|
76
75
|
next unless get_dependency_name(previous) == get_dependency_name(current)
|
|
@@ -81,12 +80,6 @@ module RuboCop
|
|
|
81
80
|
|
|
82
81
|
private
|
|
83
82
|
|
|
84
|
-
def previous_declaration(node)
|
|
85
|
-
declarations = dependency_declarations(processed_source.ast)
|
|
86
|
-
node_index = declarations.find_index(node)
|
|
87
|
-
declarations.to_a[node_index - 1]
|
|
88
|
-
end
|
|
89
|
-
|
|
90
83
|
def get_dependency_name(node)
|
|
91
84
|
node.method_name
|
|
92
85
|
end
|
|
@@ -6,7 +6,7 @@ module RuboCop
|
|
|
6
6
|
# Requires a gemspec to have `rubygems_mfa_required` metadata set.
|
|
7
7
|
#
|
|
8
8
|
# This setting tells RubyGems that MFA (Multi-Factor Authentication) is
|
|
9
|
-
# required for accounts to be able perform privileged operations, such as
|
|
9
|
+
# required for accounts to be able to perform privileged operations, such as
|
|
10
10
|
# (see RubyGems' documentation for the full list of privileged
|
|
11
11
|
# operations):
|
|
12
12
|
#
|
|
@@ -70,7 +70,7 @@ module RuboCop
|
|
|
70
70
|
def_node_matcher :metadata, <<~PATTERN
|
|
71
71
|
`{
|
|
72
72
|
(send _ :metadata= $_)
|
|
73
|
-
(send (send _ :metadata) :[]= (str "rubygems_mfa_required") $_)
|
|
73
|
+
(send (send _ :metadata) :[]= {(str "rubygems_mfa_required") (sym :rubygems_mfa_required)} $_)
|
|
74
74
|
}
|
|
75
75
|
PATTERN
|
|
76
76
|
|
|
@@ -78,13 +78,13 @@ module RuboCop
|
|
|
78
78
|
def_node_search :metadata_assignment, <<~PATTERN
|
|
79
79
|
`{
|
|
80
80
|
(send _ :metadata= _)
|
|
81
|
-
(send (send _ :metadata) :[]=
|
|
81
|
+
(send (send _ :metadata) :[]= {str sym} _)
|
|
82
82
|
}
|
|
83
83
|
PATTERN
|
|
84
84
|
|
|
85
85
|
# @!method rubygems_mfa_required(node)
|
|
86
86
|
def_node_search :rubygems_mfa_required, <<~PATTERN
|
|
87
|
-
(pair (str "rubygems_mfa_required") $_)
|
|
87
|
+
(pair {(str "rubygems_mfa_required") (sym :rubygems_mfa_required)} $_)
|
|
88
88
|
PATTERN
|
|
89
89
|
|
|
90
90
|
# @!method true_string?(node)
|
|
@@ -92,7 +92,7 @@ module RuboCop
|
|
|
92
92
|
(str "true")
|
|
93
93
|
PATTERN
|
|
94
94
|
|
|
95
|
-
def on_block(node) # rubocop:disable Metrics/MethodLength, InternalAffairs/NumblockHandler
|
|
95
|
+
def on_block(node) # rubocop:disable Metrics/MethodLength, InternalAffairs/NumblockHandler, InternalAffairs/ItblockHandler -- the gemspec block is matched by its named block variable
|
|
96
96
|
gem_specification(node) do |block_var|
|
|
97
97
|
metadata_value = metadata(node)
|
|
98
98
|
mfa_value = mfa_value(metadata_value)
|
|
@@ -143,7 +143,10 @@ module RuboCop
|
|
|
143
143
|
#{block_var}.metadata['rubygems_mfa_required'] = 'true'
|
|
144
144
|
RUBY
|
|
145
145
|
|
|
146
|
-
|
|
146
|
+
# Scope the search to the current spec block. Searching the whole file
|
|
147
|
+
# would, for a second `Gem::Specification.new` block, insert the directive
|
|
148
|
+
# into the first block, leaving this block uncorrected and looping forever.
|
|
149
|
+
if (last_assignment = metadata_assignment(node).to_a.last)
|
|
147
150
|
corrector.insert_after(last_assignment, "\n#{require_mfa_directive}")
|
|
148
151
|
else
|
|
149
152
|
corrector.insert_before(node.loc.end, "#{require_mfa_directive}\n")
|
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
module RuboCop
|
|
4
4
|
module Cop
|
|
5
5
|
module Gemspec
|
|
6
|
-
# Checks that `RUBY_VERSION`
|
|
7
|
-
# Using `RUBY_VERSION` is dangerous because value of the
|
|
6
|
+
# Checks that `RUBY_VERSION` and `Ruby::VERSION` constants are not used in gemspec.
|
|
7
|
+
# Using `RUBY_VERSION` and `Ruby::VERSION` is dangerous because the value of the
|
|
8
8
|
# constant is determined by `rake release`.
|
|
9
|
-
# It's possible to have dependency based on
|
|
10
|
-
# to execute `rake release` and not user's
|
|
9
|
+
# It's possible to have a dependency based on the Ruby version used
|
|
10
|
+
# to execute `rake release` and not the user's Ruby version.
|
|
11
11
|
#
|
|
12
12
|
# @example
|
|
13
13
|
#
|
|
@@ -28,15 +28,20 @@ module RuboCop
|
|
|
28
28
|
class RubyVersionGlobalsUsage < Base
|
|
29
29
|
include GemspecHelp
|
|
30
30
|
|
|
31
|
-
MSG = 'Do not use `
|
|
31
|
+
MSG = 'Do not use `%<ruby_version>s` in gemspec file.'
|
|
32
32
|
|
|
33
33
|
# @!method ruby_version?(node)
|
|
34
|
-
def_node_matcher :ruby_version?,
|
|
34
|
+
def_node_matcher :ruby_version?, <<~PATTERN
|
|
35
|
+
{
|
|
36
|
+
(const {cbase nil?} :RUBY_VERSION)
|
|
37
|
+
(const (const {cbase nil?} :Ruby) :VERSION)
|
|
38
|
+
}
|
|
39
|
+
PATTERN
|
|
35
40
|
|
|
36
41
|
def on_const(node)
|
|
37
42
|
return unless gem_spec_with_ruby_version?(node)
|
|
38
43
|
|
|
39
|
-
add_offense(node)
|
|
44
|
+
add_offense(node, message: format(MSG, ruby_version: node.source))
|
|
40
45
|
end
|
|
41
46
|
|
|
42
47
|
private
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module Cop
|
|
5
|
+
# Cops for the `Gemspec` department. The department's cops are registered for lazy loading
|
|
6
|
+
# and their files are loaded on demand.
|
|
7
|
+
module Gemspec
|
|
8
|
+
extend LazyLoader
|
|
9
|
+
|
|
10
|
+
register_cop :AddRuntimeDependency, "#{__dir__}/gemspec/add_runtime_dependency"
|
|
11
|
+
register_cop :AttributeAssignment, "#{__dir__}/gemspec/attribute_assignment"
|
|
12
|
+
register_cop :DependencyVersion, "#{__dir__}/gemspec/dependency_version"
|
|
13
|
+
register_cop :DeprecatedAttributeAssignment, "#{__dir__}/gemspec/deprecated_attribute_assignment"
|
|
14
|
+
register_cop :DevelopmentDependencies, "#{__dir__}/gemspec/development_dependencies"
|
|
15
|
+
register_cop :DuplicatedAssignment, "#{__dir__}/gemspec/duplicated_assignment"
|
|
16
|
+
register_cop :OrderedDependencies, "#{__dir__}/gemspec/ordered_dependencies"
|
|
17
|
+
register_cop :RequireMFA, "#{__dir__}/gemspec/require_mfa"
|
|
18
|
+
register_cop :RequiredRubyVersion, "#{__dir__}/gemspec/required_ruby_version"
|
|
19
|
+
register_cop :RubyVersionGlobalsUsage, "#{__dir__}/gemspec/ruby_version_globals_usage"
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module Cop
|
|
5
|
+
class Generator
|
|
6
|
+
# A class that injects a `register_cop` directive into the cop's department module
|
|
7
|
+
# so that the new cop is registered for lazy loading.
|
|
8
|
+
# The directive is injected in alphabetical order among the existing directives without
|
|
9
|
+
# reordering them, since the registration order defines the cop execution order.
|
|
10
|
+
# When the department module file does not exist yet, it is created, and a require for
|
|
11
|
+
# it is injected into the root RuboCop file.
|
|
12
|
+
#
|
|
13
|
+
# Anything unexpected in the department module, such as a commented-out or otherwise
|
|
14
|
+
# unparsable `register_cop` line, raises an error instead of silently producing
|
|
15
|
+
# a broken registration.
|
|
16
|
+
class RegistrationInjector
|
|
17
|
+
EXTEND_PATTERN = /\A(?<indent>\s*)extend LazyLoader\n\z/.freeze
|
|
18
|
+
ENTRY_PATTERN = %r{
|
|
19
|
+
\A(?<indent>\s*)register_cop\s
|
|
20
|
+
:(?<constant>[A-Za-z0-9]+),\s
|
|
21
|
+
"\#\{__dir__\}/(?<path>[a-z0-9_/]+)"\n\z
|
|
22
|
+
}x.freeze
|
|
23
|
+
DEPARTMENT_REQUIRE_PATTERN = %r{\Arequire_relative 'rubocop/cop/[a-z0-9_/]+'\n\z}.freeze
|
|
24
|
+
|
|
25
|
+
def initialize(source_path:, badge:, root_file_path: 'lib/rubocop.rb', output: $stdout)
|
|
26
|
+
@source_path = Pathname(source_path)
|
|
27
|
+
@badge = badge
|
|
28
|
+
@root_file_path = root_file_path
|
|
29
|
+
@department_file_path = Pathname("#{@source_path.dirname}.rb")
|
|
30
|
+
@output = output
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def inject
|
|
34
|
+
if File.exist?(department_file_path)
|
|
35
|
+
inject_directive
|
|
36
|
+
else
|
|
37
|
+
create_department_file
|
|
38
|
+
inject_department_require
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
private
|
|
43
|
+
|
|
44
|
+
attr_reader :source_path, :badge, :root_file_path, :department_file_path, :output
|
|
45
|
+
|
|
46
|
+
def inject_directive
|
|
47
|
+
lines = File.readlines(department_file_path)
|
|
48
|
+
entries = parse_entries(lines)
|
|
49
|
+
return if entries.any? { |entry| entry[:path] == cop_path }
|
|
50
|
+
|
|
51
|
+
line, indent = insertion_point(lines, entries)
|
|
52
|
+
lines.insert(line, "#{indent}#{directive}\n")
|
|
53
|
+
|
|
54
|
+
write_department_file(lines)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def create_department_file
|
|
58
|
+
File.write(department_file_path, department_module_source)
|
|
59
|
+
|
|
60
|
+
output.puts "[create] #{department_file_path}"
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def inject_department_require
|
|
64
|
+
require_path = department_file_path.sub_ext('').to_s.delete_prefix('lib/')
|
|
65
|
+
require_directive = "require_relative '#{require_path}'\n"
|
|
66
|
+
|
|
67
|
+
lines = File.readlines(root_file_path)
|
|
68
|
+
return if lines.include?(require_directive)
|
|
69
|
+
|
|
70
|
+
lines.insert(department_require_index(lines, require_directive), require_directive)
|
|
71
|
+
File.write(root_file_path, lines.join)
|
|
72
|
+
|
|
73
|
+
output.puts "[modify] #{root_file_path} - `#{require_directive.strip}` was injected."
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def write_department_file(lines)
|
|
77
|
+
File.write(department_file_path, lines.join)
|
|
78
|
+
|
|
79
|
+
output.puts "[modify] #{department_file_path} - `#{directive}` was injected."
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# @return [Array<Hash>] the `register_cop` entries with their line numbers
|
|
83
|
+
def parse_entries(lines)
|
|
84
|
+
lines.filter_map.with_index do |line, index|
|
|
85
|
+
match = ENTRY_PATTERN.match(line)
|
|
86
|
+
|
|
87
|
+
if match
|
|
88
|
+
{ line: index, indent: match[:indent], constant: match[:constant],
|
|
89
|
+
path: match[:path] }
|
|
90
|
+
elsif line.include?('register_cop')
|
|
91
|
+
raise Error, "unexpected `register_cop` line in #{department_file_path}:" \
|
|
92
|
+
"#{index + 1}; fix it or register the cop manually: #{line}"
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# The directive path is relative to the department module file's directory,
|
|
98
|
+
# which `__dir__` resolves to at load time.
|
|
99
|
+
def cop_path
|
|
100
|
+
source_path.relative_path_from(department_file_path.dirname).to_s.delete_suffix('.rb')
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def insertion_point(lines, entries)
|
|
104
|
+
if entries.empty?
|
|
105
|
+
first_directive_position(lines)
|
|
106
|
+
else
|
|
107
|
+
successor = entries.find { |entry| entry[:path] > cop_path }
|
|
108
|
+
entry = successor || entries.last
|
|
109
|
+
|
|
110
|
+
[entry[:line] + (successor ? 0 : 1), entry[:indent]]
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def directive
|
|
115
|
+
"register_cop :#{badge.cop_name}, \"\#{__dir__}/#{cop_path}\""
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
# The department requires form the contiguous block right before
|
|
119
|
+
# the `rubocop/cop/team` require in the root RuboCop file.
|
|
120
|
+
def department_require_index(lines, require_directive)
|
|
121
|
+
anchor = lines.index("require_relative 'rubocop/cop/team'\n")
|
|
122
|
+
unless anchor
|
|
123
|
+
raise Error, "could not find the department require block in #{root_file_path}"
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
block_end = anchor - 1
|
|
127
|
+
block_end -= 1 while lines[block_end] == "\n"
|
|
128
|
+
block_start = block_end
|
|
129
|
+
block_start -= 1 while lines[block_start - 1]&.match?(DEPARTMENT_REQUIRE_PATTERN)
|
|
130
|
+
|
|
131
|
+
(block_start..block_end).find do |index|
|
|
132
|
+
lines[index] > require_directive
|
|
133
|
+
end || (block_end + 1)
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def first_directive_position(lines)
|
|
137
|
+
extend_lines = lines.filter_map.with_index do |line, index|
|
|
138
|
+
[index, EXTEND_PATTERN.match(line)[:indent]] if EXTEND_PATTERN.match?(line)
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
unless extend_lines.size == 1
|
|
142
|
+
raise Error, "expected `extend LazyLoader` in #{department_file_path}; " \
|
|
143
|
+
'add it or register the cop manually'
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
index, indent = extend_lines.first
|
|
147
|
+
blank_after_extend = lines[index + 1] == "\n"
|
|
148
|
+
|
|
149
|
+
[index + (blank_after_extend ? 2 : 1), indent]
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
def department_module_source
|
|
153
|
+
modules = %w[RuboCop Cop] + badge.department.to_s.split('/')
|
|
154
|
+
body_indent = ' ' * modules.size
|
|
155
|
+
|
|
156
|
+
lines = ['# frozen_string_literal: true', '']
|
|
157
|
+
lines.concat(module_opening_lines(modules))
|
|
158
|
+
lines << "#{body_indent}extend LazyLoader"
|
|
159
|
+
lines << ''
|
|
160
|
+
lines << "#{body_indent}#{directive}"
|
|
161
|
+
lines.concat(module_closing_lines(modules))
|
|
162
|
+
|
|
163
|
+
"#{lines.join("\n")}\n"
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
def module_opening_lines(modules)
|
|
167
|
+
modules.flat_map.with_index do |mod, nesting|
|
|
168
|
+
indent = ' ' * nesting
|
|
169
|
+
lines = []
|
|
170
|
+
|
|
171
|
+
if mod == modules.last
|
|
172
|
+
lines << "#{indent}# Cops for the `#{badge.department}` department. " \
|
|
173
|
+
"The department's cops are"
|
|
174
|
+
lines << "#{indent}# registered for lazy loading and their files are " \
|
|
175
|
+
'loaded on demand.'
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
lines << "#{indent}module #{mod}"
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
def module_closing_lines(modules)
|
|
183
|
+
(modules.size - 1).downto(0).map { |nesting| "#{' ' * nesting}end" }
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
end
|
|
188
|
+
end
|
|
@@ -136,6 +136,10 @@ module RuboCop
|
|
|
136
136
|
RequireFileInjector.new(source_path: source_path, root_file_path: root_file_path).inject
|
|
137
137
|
end
|
|
138
138
|
|
|
139
|
+
def inject_registration
|
|
140
|
+
RegistrationInjector.new(source_path: source_path, badge: badge).inject
|
|
141
|
+
end
|
|
142
|
+
|
|
139
143
|
def inject_config(config_file_path: 'config/default.yml',
|
|
140
144
|
version_added: '<<next>>')
|
|
141
145
|
injector =
|
|
@@ -143,7 +147,7 @@ module RuboCop
|
|
|
143
147
|
badge: badge,
|
|
144
148
|
version_added: version_added)
|
|
145
149
|
|
|
146
|
-
injector.inject do # rubocop:disable Lint/UnexpectedBlockArity
|
|
150
|
+
injector.inject do # rubocop:disable Lint/UnexpectedBlockArity -- this `inject` is the injector API, not `Enumerable#inject`
|
|
147
151
|
output.puts(format(CONFIGURATION_ADDED_MESSAGE,
|
|
148
152
|
configuration_file_path: config_file_path))
|
|
149
153
|
end
|
|
@@ -9,15 +9,15 @@ module RuboCop
|
|
|
9
9
|
# the delimiter.
|
|
10
10
|
#
|
|
11
11
|
# @example
|
|
12
|
-
#
|
|
13
|
-
#
|
|
14
|
-
#
|
|
15
|
-
#
|
|
12
|
+
# # bad
|
|
13
|
+
# expect_offense(<<~CODE)
|
|
14
|
+
# example_ruby_code
|
|
15
|
+
# CODE
|
|
16
16
|
#
|
|
17
|
-
#
|
|
18
|
-
#
|
|
19
|
-
#
|
|
20
|
-
#
|
|
17
|
+
# # good
|
|
18
|
+
# expect_offense(<<~RUBY)
|
|
19
|
+
# example_ruby_code
|
|
20
|
+
# RUBY
|
|
21
21
|
class ExampleHeredocDelimiter < Base
|
|
22
22
|
extend AutoCorrector
|
|
23
23
|
|