rubocop 1.84.2 → 1.88.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/config/default.yml +183 -87
- data/config/obsoletion.yml +26 -1
- data/lib/rubocop/cache_config.rb +1 -1
- data/lib/rubocop/cli/command/auto_generate_config.rb +34 -2
- data/lib/rubocop/cli/command/list_enabled_cops_for.rb +40 -0
- data/lib/rubocop/cli/command/mcp.rb +19 -0
- data/lib/rubocop/cli/command/show_cops.rb +2 -2
- data/lib/rubocop/cli/command/show_docs_url.rb +4 -8
- data/lib/rubocop/cli/command/suggest_extensions.rb +1 -1
- data/lib/rubocop/cli.rb +9 -7
- data/lib/rubocop/comment_config.rb +12 -15
- data/lib/rubocop/config.rb +14 -10
- data/lib/rubocop/config_finder.rb +1 -1
- data/lib/rubocop/config_loader.rb +17 -2
- data/lib/rubocop/config_loader_resolver.rb +13 -4
- data/lib/rubocop/config_obsoletion/extracted_cop.rb +4 -2
- data/lib/rubocop/config_store.rb +2 -2
- data/lib/rubocop/config_validator.rb +1 -1
- data/lib/rubocop/cop/autocorrect_logic.rb +2 -1
- data/lib/rubocop/cop/base.rb +25 -4
- data/lib/rubocop/cop/bundler/gem_comment.rb +5 -3
- data/lib/rubocop/cop/correctors/condition_corrector.rb +1 -1
- data/lib/rubocop/cop/correctors/each_to_for_corrector.rb +1 -1
- data/lib/rubocop/cop/correctors/lambda_literal_to_method_corrector.rb +7 -1
- data/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +1 -5
- data/lib/rubocop/cop/correctors/ordered_gem_corrector.rb +8 -1
- data/lib/rubocop/cop/correctors/parentheses_corrector.rb +33 -2
- data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +2 -2
- data/lib/rubocop/cop/correctors.rb +28 -0
- data/lib/rubocop/cop/documentation.rb +2 -3
- data/lib/rubocop/cop/exclude_limit.rb +31 -5
- data/lib/rubocop/cop/gemspec/development_dependencies.rb +1 -1
- data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +2 -2
- data/lib/rubocop/cop/gemspec/require_mfa.rb +9 -6
- data/lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb +3 -3
- data/lib/rubocop/cop/internal_affairs/itblock_handler.rb +69 -0
- data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +1 -0
- data/lib/rubocop/cop/internal_affairs/redundant_let_rubocop_config_new.rb +5 -3
- data/lib/rubocop/cop/internal_affairs.rb +1 -0
- data/lib/rubocop/cop/layout/argument_alignment.rb +2 -2
- data/lib/rubocop/cop/layout/array_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/begin_end_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/block_alignment.rb +58 -4
- data/lib/rubocop/cop/layout/class_structure.rb +8 -4
- data/lib/rubocop/cop/layout/condition_position.rb +13 -3
- data/lib/rubocop/cop/layout/dot_position.rb +1 -1
- data/lib/rubocop/cop/layout/empty_comment.rb +8 -10
- data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +23 -7
- data/lib/rubocop/cop/layout/empty_line_between_defs.rb +15 -2
- data/lib/rubocop/cop/layout/empty_lines_around_attribute_accessor.rb +1 -0
- data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +12 -2
- data/lib/rubocop/cop/layout/empty_lines_around_class_body.rb +16 -2
- data/lib/rubocop/cop/layout/empty_lines_around_module_body.rb +16 -2
- data/lib/rubocop/cop/layout/end_alignment.rb +8 -5
- data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +20 -15
- data/lib/rubocop/cop/layout/hash_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/indentation_width.rb +40 -0
- data/lib/rubocop/cop/layout/line_length.rb +5 -3
- data/lib/rubocop/cop/layout/multiline_assignment_layout.rb +9 -2
- data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +1 -1
- data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +53 -3
- data/lib/rubocop/cop/layout/parameter_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/redundant_line_break.rb +3 -1
- data/lib/rubocop/cop/layout/space_around_block_parameters.rb +1 -1
- data/lib/rubocop/cop/layout/space_around_keyword.rb +3 -1
- data/lib/rubocop/cop/layout/space_around_operators.rb +6 -2
- data/lib/rubocop/cop/layout/space_before_brackets.rb +1 -1
- data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +1 -0
- data/lib/rubocop/cop/lint/ambiguous_assignment.rb +1 -11
- data/lib/rubocop/cop/lint/ambiguous_block_association.rb +1 -1
- data/lib/rubocop/cop/lint/ambiguous_operator_precedence.rb +1 -10
- data/lib/rubocop/cop/lint/assignment_in_condition.rb +13 -1
- data/lib/rubocop/cop/lint/circular_argument_reference.rb +1 -3
- data/lib/rubocop/cop/lint/constant_overwritten_in_rescue.rb +1 -1
- data/lib/rubocop/cop/lint/constant_reassignment.rb +93 -11
- data/lib/rubocop/cop/lint/constant_resolution.rb +6 -6
- data/lib/rubocop/cop/lint/data_define_override.rb +63 -0
- data/lib/rubocop/cop/lint/debugger.rb +0 -1
- data/lib/rubocop/cop/lint/deprecated_constants.rb +2 -8
- data/lib/rubocop/cop/lint/duplicate_methods.rb +55 -8
- data/lib/rubocop/cop/lint/empty_block.rb +4 -4
- data/lib/rubocop/cop/lint/empty_conditional_body.rb +6 -1
- data/lib/rubocop/cop/lint/empty_in_pattern.rb +8 -1
- data/lib/rubocop/cop/lint/empty_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 +1 -0
- data/lib/rubocop/cop/lint/incompatible_io_select_with_fiber_scheduler.rb +5 -1
- data/lib/rubocop/cop/lint/interpolation_check.rb +25 -5
- data/lib/rubocop/cop/lint/lambda_without_literal_block.rb +1 -1
- data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +11 -1
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +8 -11
- data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +5 -5
- data/lib/rubocop/cop/lint/multiple_comparison.rb +2 -2
- data/lib/rubocop/cop/lint/next_without_accumulator.rb +2 -0
- data/lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +16 -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 +19 -10
- data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +1 -1
- data/lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +3 -0
- data/lib/rubocop/cop/lint/ordered_magic_comments.rb +7 -7
- data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +3 -13
- 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 +4 -1
- data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +6 -12
- data/lib/rubocop/cop/lint/redundant_dir_glob_sort.rb +15 -4
- data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +36 -12
- data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +4 -0
- data/lib/rubocop/cop/lint/redundant_type_conversion.rb +10 -3
- data/lib/rubocop/cop/lint/redundant_with_index.rb +1 -1
- 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 +18 -0
- data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +7 -1
- 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 +24 -1
- 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/suppressed_exception_in_number_conversion.rb +12 -0
- data/lib/rubocop/cop/lint/symbol_conversion.rb +21 -4
- data/lib/rubocop/cop/lint/syntax.rb +25 -1
- data/lib/rubocop/cop/lint/to_enum_arguments.rb +35 -2
- 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 +36 -10
- data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +1 -0
- data/lib/rubocop/cop/lint/unreachable_code.rb +2 -2
- 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/useless_assignment.rb +14 -14
- data/lib/rubocop/cop/lint/useless_constant_scoping.rb +4 -4
- data/lib/rubocop/cop/lint/useless_default_value_argument.rb +2 -0
- data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +8 -4
- data/lib/rubocop/cop/lint/useless_setter_call.rb +4 -1
- data/lib/rubocop/cop/lint/useless_times.rb +22 -1
- data/lib/rubocop/cop/lint/utils/nil_receiver_checker.rb +35 -9
- data/lib/rubocop/cop/lint/void.rb +32 -12
- 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/collection_literal_length.rb +1 -1
- data/lib/rubocop/cop/metrics/method_length.rb +2 -2
- data/lib/rubocop/cop/metrics/perceived_complexity.rb +38 -7
- data/lib/rubocop/cop/metrics/utils/iterating_block.rb +1 -1
- data/lib/rubocop/cop/migration/department_name.rb +12 -1
- data/lib/rubocop/cop/mixin/check_line_breakable.rb +1 -1
- data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +2 -2
- data/lib/rubocop/cop/mixin/configurable_max.rb +6 -5
- data/lib/rubocop/cop/mixin/hash_subset.rb +8 -0
- 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/project_index_help.rb +48 -0
- data/lib/rubocop/cop/mixin.rb +86 -0
- data/lib/rubocop/cop/naming/binary_operator_parameter_name.rb +1 -1
- data/lib/rubocop/cop/naming/block_parameter_name.rb +1 -1
- data/lib/rubocop/cop/naming/file_name.rb +4 -3
- data/lib/rubocop/cop/naming/inclusive_language.rb +8 -2
- data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +10 -1
- data/lib/rubocop/cop/naming/predicate_method.rb +2 -2
- data/lib/rubocop/cop/naming/predicate_prefix.rb +1 -1
- data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +10 -4
- data/lib/rubocop/cop/offense.rb +8 -0
- data/lib/rubocop/cop/registry.rb +62 -38
- data/lib/rubocop/cop/security/eval.rb +15 -2
- data/lib/rubocop/cop/security/io_methods.rb +2 -2
- data/lib/rubocop/cop/security/marshal_load.rb +1 -1
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +14 -2
- data/lib/rubocop/cop/style/accessor_grouping.rb +15 -3
- data/lib/rubocop/cop/style/alias.rb +15 -3
- data/lib/rubocop/cop/style/and_or.rb +2 -1
- data/lib/rubocop/cop/style/arguments_forwarding.rb +25 -7
- data/lib/rubocop/cop/style/array_first_last.rb +12 -1
- data/lib/rubocop/cop/style/array_intersect.rb +4 -0
- 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 +5 -2
- data/lib/rubocop/cop/style/bare_percent_literals.rb +3 -1
- data/lib/rubocop/cop/style/begin_block.rb +3 -1
- data/lib/rubocop/cop/style/block_delimiters.rb +37 -31
- data/lib/rubocop/cop/style/case_equality.rb +18 -2
- data/lib/rubocop/cop/style/character_literal.rb +2 -2
- data/lib/rubocop/cop/style/class_and_module_children.rb +18 -2
- data/lib/rubocop/cop/style/class_equality_comparison.rb +21 -13
- data/lib/rubocop/cop/style/class_methods_definitions.rb +11 -5
- data/lib/rubocop/cop/style/collection_compact.rb +36 -16
- data/lib/rubocop/cop/style/colon_method_call.rb +16 -7
- data/lib/rubocop/cop/style/combinable_loops.rb +5 -0
- data/lib/rubocop/cop/style/comparable_clamp.rb +12 -1
- data/lib/rubocop/cop/style/concat_array_literals.rb +7 -1
- data/lib/rubocop/cop/style/conditional_assignment.rb +6 -5
- data/lib/rubocop/cop/style/constant_visibility.rb +4 -1
- data/lib/rubocop/cop/style/copyright.rb +22 -11
- data/lib/rubocop/cop/style/data_inheritance.rb +4 -0
- data/lib/rubocop/cop/style/date_time.rb +4 -4
- 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/disable_cops_within_source_code_directive.rb +1 -1
- data/lib/rubocop/cop/style/document_dynamic_eval_definition.rb +6 -1
- data/lib/rubocop/cop/style/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 +12 -2
- data/lib/rubocop/cop/style/empty_class_definition.rb +51 -21
- 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 +7 -2
- data/lib/rubocop/cop/style/empty_string_inside_interpolation.rb +30 -20
- 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 +8 -3
- 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 +8 -1
- data/lib/rubocop/cop/style/fetch_env_var.rb +1 -1
- data/lib/rubocop/cop/style/file_null.rb +4 -2
- 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/for.rb +3 -0
- data/lib/rubocop/cop/style/format_string.rb +17 -4
- data/lib/rubocop/cop/style/format_string_token.rb +29 -2
- data/lib/rubocop/cop/style/global_vars.rb +5 -2
- data/lib/rubocop/cop/style/guard_clause.rb +9 -6
- data/lib/rubocop/cop/style/hash_as_last_array_item.rb +21 -5
- data/lib/rubocop/cop/style/hash_conversion.rb +1 -1
- data/lib/rubocop/cop/style/hash_lookup_method.rb +19 -7
- data/lib/rubocop/cop/style/hash_slice.rb +16 -0
- data/lib/rubocop/cop/style/hash_syntax.rb +2 -0
- data/lib/rubocop/cop/style/hash_transform_keys.rb +17 -7
- data/lib/rubocop/cop/style/hash_transform_values.rb +17 -7
- data/lib/rubocop/cop/style/if_inside_else.rb +16 -7
- data/lib/rubocop/cop/style/if_unless_modifier.rb +15 -4
- data/lib/rubocop/cop/style/if_with_semicolon.rb +16 -6
- data/lib/rubocop/cop/style/inline_comment.rb +5 -2
- data/lib/rubocop/cop/style/ip_addresses.rb +1 -2
- data/lib/rubocop/cop/style/keyword_arguments_merging.rb +4 -0
- data/lib/rubocop/cop/style/keyword_parameters_order.rb +7 -3
- data/lib/rubocop/cop/style/lambda.rb +7 -1
- data/lib/rubocop/cop/style/magic_comment_format.rb +3 -3
- data/lib/rubocop/cop/style/map_compact_with_conditional_block.rb +11 -0
- data/lib/rubocop/cop/style/map_into_array.rb +1 -1
- data/lib/rubocop/cop/style/map_join.rb +123 -0
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/require_parentheses.rb +5 -3
- data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +6 -2
- data/lib/rubocop/cop/style/method_def_parentheses.rb +1 -1
- data/lib/rubocop/cop/style/min_max_comparison.rb +4 -1
- data/lib/rubocop/cop/style/module_member_existence_check.rb +7 -14
- data/lib/rubocop/cop/style/multiline_if_then.rb +4 -2
- data/lib/rubocop/cop/style/multiline_memoization.rb +7 -1
- data/lib/rubocop/cop/style/multiline_method_signature.rb +11 -4
- data/lib/rubocop/cop/style/mutable_constant.rb +106 -12
- data/lib/rubocop/cop/style/nil_comparison.rb +2 -3
- data/lib/rubocop/cop/style/nil_lambda.rb +9 -1
- data/lib/rubocop/cop/style/non_nil_check.rb +5 -11
- data/lib/rubocop/cop/style/not.rb +2 -0
- data/lib/rubocop/cop/style/numeric_literals.rb +3 -2
- data/lib/rubocop/cop/style/numeric_predicate.rb +1 -1
- data/lib/rubocop/cop/style/one_class_per_file.rb +115 -0
- data/lib/rubocop/cop/style/one_line_conditional.rb +4 -3
- data/lib/rubocop/cop/style/open_struct_use.rb +1 -1
- 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 +23 -3
- data/lib/rubocop/cop/style/partition_instead_of_double_select.rb +270 -0
- data/lib/rubocop/cop/style/percent_literal_delimiters.rb +4 -0
- 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/proc.rb +3 -2
- data/lib/rubocop/cop/style/raise_args.rb +1 -1
- data/lib/rubocop/cop/style/reduce_to_hash.rb +200 -0
- data/lib/rubocop/cop/style/redundant_array_constructor.rb +2 -2
- data/lib/rubocop/cop/style/redundant_begin.rb +3 -3
- data/lib/rubocop/cop/style/redundant_constant_base.rb +5 -5
- data/lib/rubocop/cop/style/redundant_each.rb +3 -3
- data/lib/rubocop/cop/style/redundant_exception.rb +6 -0
- data/lib/rubocop/cop/style/redundant_fetch_block.rb +1 -1
- data/lib/rubocop/cop/style/redundant_filter_chain.rb +1 -1
- data/lib/rubocop/cop/style/redundant_format.rb +29 -0
- data/lib/rubocop/cop/style/redundant_interpolation_unfreeze.rb +26 -10
- data/lib/rubocop/cop/style/redundant_line_continuation.rb +27 -3
- data/lib/rubocop/cop/style/redundant_min_max_by.rb +93 -0
- data/lib/rubocop/cop/style/redundant_parentheses.rb +25 -22
- data/lib/rubocop/cop/style/redundant_percent_q.rb +4 -1
- data/lib/rubocop/cop/style/redundant_regexp_constructor.rb +2 -2
- data/lib/rubocop/cop/style/redundant_regexp_escape.rb +8 -4
- data/lib/rubocop/cop/style/redundant_return.rb +3 -1
- data/lib/rubocop/cop/style/redundant_self.rb +11 -2
- data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +0 -5
- data/lib/rubocop/cop/style/redundant_struct_keyword_init.rb +133 -0
- data/lib/rubocop/cop/style/regexp_literal.rb +31 -2
- data/lib/rubocop/cop/style/rescue_modifier.rb +3 -3
- data/lib/rubocop/cop/style/safe_navigation.rb +7 -7
- data/lib/rubocop/cop/style/select_by_kind.rb +158 -0
- data/lib/rubocop/cop/style/select_by_range.rb +197 -0
- data/lib/rubocop/cop/style/select_by_regexp.rb +51 -21
- data/lib/rubocop/cop/style/self_assignment.rb +1 -1
- data/lib/rubocop/cop/style/semicolon.rb +22 -5
- data/lib/rubocop/cop/style/single_line_block_params.rb +2 -2
- data/lib/rubocop/cop/style/single_line_do_end_block.rb +18 -5
- data/lib/rubocop/cop/style/single_line_methods.rb +3 -1
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +4 -2
- data/lib/rubocop/cop/style/special_global_vars.rb +6 -1
- data/lib/rubocop/cop/style/string_hash_keys.rb +1 -0
- data/lib/rubocop/cop/style/struct_inheritance.rb +13 -0
- data/lib/rubocop/cop/style/symbol_proc.rb +7 -6
- data/lib/rubocop/cop/style/tally_method.rb +181 -0
- data/lib/rubocop/cop/style/ternary_parentheses.rb +11 -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 +7 -8
- 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 +1 -1
- data/lib/rubocop/cop/style/yoda_expression.rb +1 -1
- data/lib/rubocop/cop/style/zero_length_predicate.rb +6 -3
- data/lib/rubocop/cop/team.rb +86 -35
- data/lib/rubocop/cop/variable_force/branch.rb +2 -2
- data/lib/rubocop/directive_comment.rb +2 -1
- data/lib/rubocop/file_patterns.rb +9 -1
- data/lib/rubocop/formatter/disabled_config_formatter.rb +19 -9
- data/lib/rubocop/formatter/formatter_set.rb +1 -1
- data/lib/rubocop/formatter/junit_formatter.rb +1 -1
- data/lib/rubocop/formatter/simple_text_formatter.rb +0 -2
- data/lib/rubocop/formatter/worst_offenders_formatter.rb +1 -1
- data/lib/rubocop/formatter.rb +22 -21
- data/lib/rubocop/lsp/diagnostic.rb +1 -0
- data/lib/rubocop/lsp/routes.rb +10 -3
- data/lib/rubocop/lsp/runtime.rb +1 -2
- data/lib/rubocop/mcp/server.rb +200 -0
- data/lib/rubocop/options.rb +35 -4
- data/lib/rubocop/path_util.rb +14 -2
- data/lib/rubocop/plugin/loader.rb +1 -1
- data/lib/rubocop/project_index_loader.rb +66 -0
- data/lib/rubocop/result_cache.rb +22 -10
- data/lib/rubocop/rspec/cop_helper.rb +8 -0
- data/lib/rubocop/rspec/shared_contexts.rb +32 -2
- data/lib/rubocop/runner.rb +126 -53
- data/lib/rubocop/server/cache.rb +5 -7
- data/lib/rubocop/server/core.rb +8 -0
- data/lib/rubocop/target_finder.rb +14 -7
- data/lib/rubocop/target_ruby.rb +18 -12
- data/lib/rubocop/version.rb +21 -3
- data/lib/rubocop.rb +22 -96
- metadata +27 -5
|
@@ -44,13 +44,6 @@ module RuboCop
|
|
|
44
44
|
RESTRICT_ON_SEND = PRECEDENCE.flatten.freeze
|
|
45
45
|
MSG = 'Wrap expressions with varying precedence with parentheses to avoid ambiguity.'
|
|
46
46
|
|
|
47
|
-
def on_new_investigation
|
|
48
|
-
# Cache the precedence of each node being investigated
|
|
49
|
-
# so that we only need to calculate it once
|
|
50
|
-
@node_precedences = {}
|
|
51
|
-
super
|
|
52
|
-
end
|
|
53
|
-
|
|
54
47
|
def on_and(node)
|
|
55
48
|
return unless (parent = node.parent)
|
|
56
49
|
|
|
@@ -77,9 +70,7 @@ module RuboCop
|
|
|
77
70
|
private
|
|
78
71
|
|
|
79
72
|
def precedence(node)
|
|
80
|
-
|
|
81
|
-
PRECEDENCE.index { |operators| operators.include?(operator_name(node)) }
|
|
82
|
-
end
|
|
73
|
+
PRECEDENCE.index { |operators| operators.include?(operator_name(node)) }
|
|
83
74
|
end
|
|
84
75
|
|
|
85
76
|
def operator?(node)
|
|
@@ -78,13 +78,25 @@ module RuboCop
|
|
|
78
78
|
end
|
|
79
79
|
|
|
80
80
|
def allowed_construct?(asgn_node)
|
|
81
|
-
asgn_node.begin_type?
|
|
81
|
+
return true if asgn_node.begin_type?
|
|
82
|
+
|
|
83
|
+
conditional_assignment?(asgn_node) || discarded_assignment?(asgn_node)
|
|
82
84
|
end
|
|
83
85
|
|
|
84
86
|
def conditional_assignment?(asgn_node)
|
|
85
87
|
!asgn_node.loc.operator
|
|
86
88
|
end
|
|
87
89
|
|
|
90
|
+
# An assignment that is a statement of a multi-statement `begin`
|
|
91
|
+
# (e.g. `(foo = bar; baz)`) has its value discarded, so it is not used
|
|
92
|
+
# as the condition. Wrapping it in parentheses would only conflict with
|
|
93
|
+
# `Style/RedundantParentheses`, so it is left alone.
|
|
94
|
+
def discarded_assignment?(asgn_node)
|
|
95
|
+
parent = asgn_node.parent
|
|
96
|
+
|
|
97
|
+
parent&.begin_type? && parent.children.size > 1
|
|
98
|
+
end
|
|
99
|
+
|
|
88
100
|
def skip_children?(asgn_node)
|
|
89
101
|
(asgn_node.call_type? && !asgn_node.assignment_method?) ||
|
|
90
102
|
empty_condition?(asgn_node) ||
|
|
@@ -80,7 +80,6 @@ module RuboCop
|
|
|
80
80
|
check_assignment_chain(arg_name, arg_value)
|
|
81
81
|
end
|
|
82
82
|
|
|
83
|
-
# rubocop:disable Metrics/AbcSize
|
|
84
83
|
def check_assignment_chain(arg_name, node)
|
|
85
84
|
return unless node.lvasgn_type?
|
|
86
85
|
|
|
@@ -88,7 +87,7 @@ module RuboCop
|
|
|
88
87
|
current_node = node
|
|
89
88
|
|
|
90
89
|
while current_node.lvasgn_type?
|
|
91
|
-
seen_variables << current_node.children.first
|
|
90
|
+
seen_variables << current_node.children.first
|
|
92
91
|
current_node = current_node.children.last
|
|
93
92
|
end
|
|
94
93
|
|
|
@@ -99,7 +98,6 @@ module RuboCop
|
|
|
99
98
|
|
|
100
99
|
add_offense(current_node, message: format(MSG, arg_name: arg_name))
|
|
101
100
|
end
|
|
102
|
-
# rubocop:enable Metrics/AbcSize
|
|
103
101
|
end
|
|
104
102
|
end
|
|
105
103
|
end
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
module RuboCop
|
|
4
4
|
module Cop
|
|
5
5
|
module Lint
|
|
6
|
-
# Checks for overwriting an exception with an exception result by
|
|
6
|
+
# Checks for overwriting an exception with an exception result by using ``rescue =>``.
|
|
7
7
|
#
|
|
8
8
|
# You intended to write as `rescue StandardError`.
|
|
9
9
|
# However, you have written `rescue => StandardError`.
|
|
@@ -6,11 +6,19 @@ module RuboCop
|
|
|
6
6
|
# Checks for constant reassignments.
|
|
7
7
|
#
|
|
8
8
|
# Emulates Ruby's runtime warning "already initialized constant X"
|
|
9
|
-
# when a constant is reassigned in the same file and namespace
|
|
10
|
-
# `NAME = value` syntax.
|
|
9
|
+
# when a constant is reassigned in the same file and namespace.
|
|
11
10
|
#
|
|
12
|
-
# The cop
|
|
13
|
-
#
|
|
11
|
+
# The cop tracks constants defined via `NAME = value` syntax as well as
|
|
12
|
+
# class/module keyword definitions. It detects reassignment when a constant
|
|
13
|
+
# is first defined one way and then redefined using the `NAME = value` syntax.
|
|
14
|
+
#
|
|
15
|
+
# The cop cannot catch all offenses, like, for example, when using metaprogramming
|
|
16
|
+
# (`Module#const_set`).
|
|
17
|
+
#
|
|
18
|
+
# By default the cop also cannot detect reassignment across files.
|
|
19
|
+
# When `AllCops/UseProjectIndex` is enabled and the `rubydex` gem is installed,
|
|
20
|
+
# the cop additionally consults the project-wide index and reports reassignments
|
|
21
|
+
# whose previous definition lives in another file.
|
|
14
22
|
#
|
|
15
23
|
# The cop only takes into account constants assigned in a "simple" way: directly
|
|
16
24
|
# inside class/module definition, or within another constant. Other type of assignments
|
|
@@ -36,6 +44,14 @@ module RuboCop
|
|
|
36
44
|
# X = :bar
|
|
37
45
|
# end
|
|
38
46
|
#
|
|
47
|
+
# # bad
|
|
48
|
+
# class FooError < StandardError; end
|
|
49
|
+
# FooError = Class.new(RuntimeError)
|
|
50
|
+
#
|
|
51
|
+
# # bad
|
|
52
|
+
# module M; end
|
|
53
|
+
# M = 1
|
|
54
|
+
#
|
|
39
55
|
# # good - keep only one assignment
|
|
40
56
|
# X = :bar
|
|
41
57
|
#
|
|
@@ -63,22 +79,44 @@ module RuboCop
|
|
|
63
79
|
# end
|
|
64
80
|
#
|
|
65
81
|
class ConstantReassignment < Base
|
|
82
|
+
include ProjectIndexHelp
|
|
83
|
+
|
|
66
84
|
MSG = 'Constant `%<constant>s` is already assigned in this namespace.'
|
|
85
|
+
CROSS_FILE_MSG = 'Constant `%<constant>s` is already assigned in `%<path>s`.'
|
|
67
86
|
|
|
68
87
|
RESTRICT_ON_SEND = %i[remove_const].freeze
|
|
69
88
|
|
|
70
89
|
# @!method remove_constant(node)
|
|
71
90
|
def_node_matcher :remove_constant, <<~PATTERN
|
|
72
|
-
(send
|
|
91
|
+
(send {nil? self} :remove_const
|
|
73
92
|
({sym str} $_))
|
|
74
93
|
PATTERN
|
|
75
94
|
|
|
95
|
+
def on_class(node)
|
|
96
|
+
return unless unconditional_definition?(node)
|
|
97
|
+
|
|
98
|
+
constant_definitions[definition_name(node)] ||= :class
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def on_module(node)
|
|
102
|
+
return unless unconditional_definition?(node)
|
|
103
|
+
|
|
104
|
+
constant_definitions[definition_name(node)] ||= :module
|
|
105
|
+
end
|
|
106
|
+
|
|
76
107
|
def on_casgn(node)
|
|
77
108
|
return unless fixed_constant_path?(node)
|
|
78
109
|
return unless simple_assignment?(node)
|
|
79
|
-
return if constant_names.add?(fully_qualified_constant_name(node))
|
|
80
110
|
|
|
81
|
-
|
|
111
|
+
name = fully_qualified_constant_name(node)
|
|
112
|
+
|
|
113
|
+
if constant_definitions.key?(name)
|
|
114
|
+
add_offense(node, message: format(MSG, constant: constant_display_name(node)))
|
|
115
|
+
return
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
constant_definitions[name] = :casgn
|
|
119
|
+
report_cross_file_collision(node, name, constant_display_name(node))
|
|
82
120
|
end
|
|
83
121
|
|
|
84
122
|
def on_send(node)
|
|
@@ -90,7 +128,7 @@ module RuboCop
|
|
|
90
128
|
|
|
91
129
|
return if namespaces.none?
|
|
92
130
|
|
|
93
|
-
|
|
131
|
+
constant_definitions.delete(fully_qualified_name_for(namespaces, constant))
|
|
94
132
|
end
|
|
95
133
|
|
|
96
134
|
private
|
|
@@ -104,7 +142,7 @@ module RuboCop
|
|
|
104
142
|
return true if ancestor.type?(:module, :class)
|
|
105
143
|
|
|
106
144
|
ancestor.begin_type? || ancestor.literal? || ancestor.casgn_type? ||
|
|
107
|
-
freeze_method?(ancestor)
|
|
145
|
+
ancestor.type?(:masgn, :mlhs) || freeze_method?(ancestor)
|
|
108
146
|
end
|
|
109
147
|
end
|
|
110
148
|
|
|
@@ -128,6 +166,10 @@ module RuboCop
|
|
|
128
166
|
['', *namespaces, constant].join('::')
|
|
129
167
|
end
|
|
130
168
|
|
|
169
|
+
def constant_display_name(node)
|
|
170
|
+
[*constant_namespaces(node), node.name].join('::')
|
|
171
|
+
end
|
|
172
|
+
|
|
131
173
|
def constant_namespaces(node)
|
|
132
174
|
node.each_path.select(&:const_type?).map(&:short_name)
|
|
133
175
|
end
|
|
@@ -139,8 +181,48 @@ module RuboCop
|
|
|
139
181
|
.reverse
|
|
140
182
|
end
|
|
141
183
|
|
|
142
|
-
def
|
|
143
|
-
|
|
184
|
+
def unconditional_definition?(node)
|
|
185
|
+
node.each_ancestor.all? do |ancestor|
|
|
186
|
+
ancestor.type?(:begin, :module, :class)
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
def definition_name(node)
|
|
191
|
+
identifier = node.identifier
|
|
192
|
+
|
|
193
|
+
if identifier.namespace&.cbase_type?
|
|
194
|
+
fully_qualified_name_for([], identifier.short_name)
|
|
195
|
+
else
|
|
196
|
+
namespaces = ancestor_namespaces(node) + identifier_namespaces(identifier)
|
|
197
|
+
fully_qualified_name_for(namespaces, identifier.short_name)
|
|
198
|
+
end
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
def identifier_namespaces(identifier)
|
|
202
|
+
identifier.each_path.select(&:const_type?).map(&:short_name)
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
def constant_definitions
|
|
206
|
+
@constant_definitions ||= {}
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
def report_cross_file_collision(node, fully_qualified_name, display_name)
|
|
210
|
+
return unless project_index
|
|
211
|
+
return unless (declaration = project_index[fully_qualified_name.delete_prefix('::')])
|
|
212
|
+
return unless (prior = prior_definition_in_other_file(declaration))
|
|
213
|
+
|
|
214
|
+
msg = format(CROSS_FILE_MSG, constant: display_name, path: prior.location.to_file_path)
|
|
215
|
+
|
|
216
|
+
add_offense(node, message: msg)
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
def prior_definition_in_other_file(declaration)
|
|
220
|
+
current = processed_source.file_path
|
|
221
|
+
|
|
222
|
+
declaration.definitions.find do |definition|
|
|
223
|
+
other = definition.location.to_file_path
|
|
224
|
+
!File.identical?(other, current)
|
|
225
|
+
end
|
|
144
226
|
end
|
|
145
227
|
end
|
|
146
228
|
end
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
module RuboCop
|
|
4
4
|
module Cop
|
|
5
5
|
module Lint
|
|
6
|
-
#
|
|
6
|
+
# Checks that certain constants are fully qualified.
|
|
7
7
|
#
|
|
8
8
|
# This is not enabled by default because it would mark a lot of offenses
|
|
9
9
|
# unnecessarily.
|
|
@@ -13,12 +13,12 @@ module RuboCop
|
|
|
13
13
|
#
|
|
14
14
|
# Large projects will over time end up with one or two constant names that
|
|
15
15
|
# are problematic because of a conflict with a library or just internally
|
|
16
|
-
# using the same name a namespace and a class. To avoid too many unnecessary
|
|
17
|
-
# offenses,
|
|
16
|
+
# using the same name for a namespace and a class. To avoid too many unnecessary
|
|
17
|
+
# offenses, enable this cop with `Only: [The, Constant, Names, Causing, Issues]`
|
|
18
18
|
#
|
|
19
|
-
# NOTE: `Style/RedundantConstantBase` cop is disabled if this cop is enabled
|
|
20
|
-
# conflicting rules.
|
|
21
|
-
# this cop which is disabled by default.
|
|
19
|
+
# NOTE: `Style/RedundantConstantBase` cop is disabled if this cop is enabled,
|
|
20
|
+
# to prevent conflicting rules. This is because it respects user configurations
|
|
21
|
+
# that want to enable this cop which is disabled by default.
|
|
22
22
|
#
|
|
23
23
|
# @example
|
|
24
24
|
# # By default checks every constant
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module Cop
|
|
5
|
+
module Lint
|
|
6
|
+
# Checks unexpected overrides of the `Data` built-in methods
|
|
7
|
+
# via `Data.define`.
|
|
8
|
+
#
|
|
9
|
+
# @example
|
|
10
|
+
# # bad
|
|
11
|
+
# Bad = Data.define(:members, :clone, :to_s)
|
|
12
|
+
# b = Bad.new(members: [], clone: true, to_s: 'bad')
|
|
13
|
+
# b.members #=> [] (overriding `Data#members`)
|
|
14
|
+
# b.clone #=> true (overriding `Object#clone`)
|
|
15
|
+
# b.to_s #=> "bad" (overriding `Data#to_s`)
|
|
16
|
+
#
|
|
17
|
+
# # good
|
|
18
|
+
# Good = Data.define(:id, :name)
|
|
19
|
+
# g = Good.new(id: 1, name: "foo")
|
|
20
|
+
# g.members #=> [:id, :name]
|
|
21
|
+
# g.clone #=> #<data Good id=1, name="foo">
|
|
22
|
+
#
|
|
23
|
+
class DataDefineOverride < Base
|
|
24
|
+
MSG = '`%<member_name>s` member overrides `Data#%<method_name>s` and it may be unexpected.'
|
|
25
|
+
RESTRICT_ON_SEND = %i[define].freeze
|
|
26
|
+
|
|
27
|
+
# This is based on `Data.define.instance_methods.sort` in Ruby 4.0.0.
|
|
28
|
+
DATA_METHOD_NAMES = %i[
|
|
29
|
+
! != !~ <=> == === __id__ __send__ class clone deconstruct deconstruct_keys
|
|
30
|
+
define_singleton_method display dup enum_for eql? equal? extend freeze frozen? hash
|
|
31
|
+
inspect instance_eval instance_exec instance_of? instance_variable_defined?
|
|
32
|
+
instance_variable_get instance_variable_set instance_variables is_a? itself kind_of?
|
|
33
|
+
members method methods nil? object_id private_methods protected_methods
|
|
34
|
+
public_method public_methods public_send remove_instance_variable respond_to? send
|
|
35
|
+
singleton_class singleton_method singleton_methods tap then to_enum to_h to_s with
|
|
36
|
+
yield_self
|
|
37
|
+
].freeze
|
|
38
|
+
MEMBER_NAME_TYPES = %i[sym str].freeze
|
|
39
|
+
|
|
40
|
+
# @!method data_define(node)
|
|
41
|
+
def_node_matcher :data_define, <<~PATTERN
|
|
42
|
+
(send
|
|
43
|
+
(const {nil? cbase} :Data) :define ...)
|
|
44
|
+
PATTERN
|
|
45
|
+
|
|
46
|
+
def on_send(node)
|
|
47
|
+
return unless data_define(node)
|
|
48
|
+
|
|
49
|
+
node.arguments.each do |arg|
|
|
50
|
+
next unless MEMBER_NAME_TYPES.include?(arg.type)
|
|
51
|
+
|
|
52
|
+
member_name = arg.value
|
|
53
|
+
|
|
54
|
+
next unless DATA_METHOD_NAMES.include?(member_name.to_sym)
|
|
55
|
+
|
|
56
|
+
message = format(MSG, member_name: member_name.inspect, method_name: member_name.to_s)
|
|
57
|
+
add_offense(arg, message: message)
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
@@ -14,7 +14,7 @@ module RuboCop
|
|
|
14
14
|
# Alternative: 'alternative_value'
|
|
15
15
|
# DeprecatedVersion: 'deprecated_version'
|
|
16
16
|
#
|
|
17
|
-
# By default, `NIL`, `TRUE`, `FALSE`, `Net::HTTPServerException
|
|
17
|
+
# By default, `NIL`, `TRUE`, `FALSE`, `Net::HTTPServerException`, `Random::DEFAULT`,
|
|
18
18
|
# `Struct::Group`, and `Struct::Passwd` are configured.
|
|
19
19
|
#
|
|
20
20
|
# @example
|
|
@@ -49,7 +49,7 @@ module RuboCop
|
|
|
49
49
|
# Maybe further investigation of RuboCop AST will lead to an essential solution.
|
|
50
50
|
return unless node.loc
|
|
51
51
|
|
|
52
|
-
constant = node.
|
|
52
|
+
constant = node.source.delete_prefix('::')
|
|
53
53
|
return unless (deprecated_constant = deprecated_constants[constant])
|
|
54
54
|
|
|
55
55
|
alternative = deprecated_constant['Alternative']
|
|
@@ -63,12 +63,6 @@ module RuboCop
|
|
|
63
63
|
|
|
64
64
|
private
|
|
65
65
|
|
|
66
|
-
def constant_name(node, nested_constant_name)
|
|
67
|
-
return nested_constant_name.to_s unless node.namespace.const_type?
|
|
68
|
-
|
|
69
|
-
constant_name(node.namespace, "#{node.namespace.short_name}::#{nested_constant_name}")
|
|
70
|
-
end
|
|
71
|
-
|
|
72
66
|
def message(good, bad, deprecated_version)
|
|
73
67
|
deprecated_message = ", deprecated since Ruby #{deprecated_version}" if deprecated_version
|
|
74
68
|
|
|
@@ -197,6 +197,13 @@ module RuboCop
|
|
|
197
197
|
# @!method sym_name(node)
|
|
198
198
|
def_node_matcher :sym_name, '(sym $_name)'
|
|
199
199
|
|
|
200
|
+
# @!method class_or_module_new_block?(node)
|
|
201
|
+
def_node_matcher :class_or_module_new_block?, <<~PATTERN
|
|
202
|
+
(block
|
|
203
|
+
(send (const _ {:Class :Module}) :new ...)
|
|
204
|
+
...)
|
|
205
|
+
PATTERN
|
|
206
|
+
|
|
200
207
|
def on_send(node) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
|
201
208
|
name, original_name = alias_method?(node)
|
|
202
209
|
|
|
@@ -233,9 +240,12 @@ module RuboCop
|
|
|
233
240
|
|
|
234
241
|
def check_self_receiver(node, name)
|
|
235
242
|
enclosing = node.parent_module_name
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
243
|
+
if enclosing
|
|
244
|
+
found_method(node, "#{enclosing}.#{name}")
|
|
245
|
+
elsif (anon_block = anonymous_class_block(node))
|
|
246
|
+
scope = qualified_name(anon_block.parent_module_name, nil, 'Object')
|
|
247
|
+
found_method(node, "#{scope}.#{name}", scope_id: anon_block_scope_id(anon_block))
|
|
248
|
+
end
|
|
239
249
|
end
|
|
240
250
|
|
|
241
251
|
def inside_condition?(node)
|
|
@@ -274,16 +284,50 @@ module RuboCop
|
|
|
274
284
|
end
|
|
275
285
|
|
|
276
286
|
def found_instance_method(node, name)
|
|
277
|
-
|
|
287
|
+
if (scope = node.parent_module_name)
|
|
288
|
+
found_method(node, "#{humanize_scope(scope)}#{name}")
|
|
289
|
+
elsif (anon_block = anonymous_class_block(node))
|
|
290
|
+
base = qualified_name(anon_block.parent_module_name, nil, 'Object')
|
|
291
|
+
scope = node.each_ancestor(:sclass).any? ? "#<Class:#{base}>" : base
|
|
292
|
+
found_method(
|
|
293
|
+
node, "#{humanize_scope(scope)}#{name}", scope_id: anon_block_scope_id(anon_block)
|
|
294
|
+
)
|
|
295
|
+
else
|
|
296
|
+
found_sclass_method(node, name)
|
|
297
|
+
end
|
|
298
|
+
end
|
|
278
299
|
|
|
279
|
-
|
|
300
|
+
def humanize_scope(scope)
|
|
280
301
|
scope = scope.sub(
|
|
281
302
|
/(?:(?<name>.*)::)#<Class:\k<name>>|#<Class:(?<name>.*)>(?:::)?/,
|
|
282
303
|
'\k<name>.'
|
|
283
304
|
)
|
|
284
|
-
scope
|
|
305
|
+
scope.end_with?('.') ? scope : "#{scope}#"
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
def anonymous_class_block(node)
|
|
309
|
+
first_block = node.each_ancestor(:block).first
|
|
310
|
+
return unless class_or_module_new_block?(first_block)
|
|
311
|
+
return if first_block.parent&.type?(:lvasgn)
|
|
312
|
+
return if node.each_ancestor(:sclass).any? { |s| !s.children.first.self_type? }
|
|
313
|
+
|
|
314
|
+
first_block
|
|
315
|
+
end
|
|
316
|
+
|
|
317
|
+
def anon_block_scope_id(anon_block)
|
|
318
|
+
parent = anon_block.parent
|
|
319
|
+
return unless parent&.type?(:any_block, :begin, :call, :casgn, :any_def)
|
|
320
|
+
|
|
321
|
+
if (receiver = named_receiver(parent))
|
|
322
|
+
"#{receiver.source}.#{parent.method_name}"
|
|
323
|
+
elsif !parent.begin_type? || parent.parent&.any_block_type?
|
|
324
|
+
source_location(anon_block)
|
|
325
|
+
end
|
|
326
|
+
end
|
|
285
327
|
|
|
286
|
-
|
|
328
|
+
def named_receiver(node)
|
|
329
|
+
receiver = node.receiver
|
|
330
|
+
receiver unless class_or_module_new_block?(receiver)
|
|
287
331
|
end
|
|
288
332
|
|
|
289
333
|
def found_sclass_method(node, name)
|
|
@@ -296,8 +340,10 @@ module RuboCop
|
|
|
296
340
|
found_method(node, "#{singleton_receiver_node.method_name}.#{name}")
|
|
297
341
|
end
|
|
298
342
|
|
|
299
|
-
|
|
343
|
+
# rubocop:disable Metrics/AbcSize
|
|
344
|
+
def found_method(node, method_name, scope_id: nil)
|
|
300
345
|
key = method_key(node, method_name)
|
|
346
|
+
key = "#{key}@#{scope_id}" if scope_id
|
|
301
347
|
scope = node.each_ancestor(:rescue, :ensure).first&.type
|
|
302
348
|
|
|
303
349
|
if @definitions.key?(key)
|
|
@@ -314,6 +360,7 @@ module RuboCop
|
|
|
314
360
|
@definitions[key] = node
|
|
315
361
|
end
|
|
316
362
|
end
|
|
363
|
+
# rubocop:enable Metrics/AbcSize
|
|
317
364
|
|
|
318
365
|
def method_key(node, method_name)
|
|
319
366
|
if (ancestor_def = node.each_ancestor(:any_def).first)
|
|
@@ -63,7 +63,7 @@ module RuboCop
|
|
|
63
63
|
class EmptyBlock < Base
|
|
64
64
|
MSG = 'Empty block detected.'
|
|
65
65
|
|
|
66
|
-
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
|
|
66
|
+
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler, InternalAffairs/ItblockHandler
|
|
67
67
|
return if node.body
|
|
68
68
|
return if allow_empty_lambdas? && node.lambda_or_proc?
|
|
69
69
|
return if cop_config['AllowComments'] && allow_comment?(node)
|
|
@@ -77,7 +77,7 @@ module RuboCop
|
|
|
77
77
|
return false unless processed_source.contains_comment?(node.source_range)
|
|
78
78
|
|
|
79
79
|
line_comment = processed_source.comment_at_line(node.source_range.line)
|
|
80
|
-
!line_comment || !comment_disables_cop?(line_comment
|
|
80
|
+
!line_comment || !comment_disables_cop?(line_comment)
|
|
81
81
|
end
|
|
82
82
|
|
|
83
83
|
def allow_empty_lambdas?
|
|
@@ -85,8 +85,8 @@ module RuboCop
|
|
|
85
85
|
end
|
|
86
86
|
|
|
87
87
|
def comment_disables_cop?(comment)
|
|
88
|
-
|
|
89
|
-
|
|
88
|
+
directive = DirectiveComment.new(comment)
|
|
89
|
+
directive.disabled? && directive.cop_names.include?(cop_name)
|
|
90
90
|
end
|
|
91
91
|
end
|
|
92
92
|
end
|
|
@@ -70,7 +70,7 @@ module RuboCop
|
|
|
70
70
|
|
|
71
71
|
def on_if(node)
|
|
72
72
|
return if node.body || same_line?(node.loc.begin, node.loc.end)
|
|
73
|
-
return if
|
|
73
|
+
return if allow_comments?(node)
|
|
74
74
|
|
|
75
75
|
range = offense_range(node)
|
|
76
76
|
|
|
@@ -83,6 +83,11 @@ module RuboCop
|
|
|
83
83
|
|
|
84
84
|
private
|
|
85
85
|
|
|
86
|
+
def allow_comments?(node)
|
|
87
|
+
cop_config['AllowComments'] && contains_comments?(node) &&
|
|
88
|
+
!comments_contain_disables?(node, name)
|
|
89
|
+
end
|
|
90
|
+
|
|
86
91
|
def offense_range(node)
|
|
87
92
|
if node.loc.else
|
|
88
93
|
node.source_range.begin.join(node.loc.else.begin)
|
|
@@ -53,11 +53,18 @@ module RuboCop
|
|
|
53
53
|
def on_case_match(node)
|
|
54
54
|
node.in_pattern_branches.each do |branch|
|
|
55
55
|
next if branch.body
|
|
56
|
-
next if
|
|
56
|
+
next if allow_comments?(branch)
|
|
57
57
|
|
|
58
58
|
add_offense(branch)
|
|
59
59
|
end
|
|
60
60
|
end
|
|
61
|
+
|
|
62
|
+
private
|
|
63
|
+
|
|
64
|
+
def allow_comments?(node)
|
|
65
|
+
cop_config['AllowComments'] && contains_comments?(node) &&
|
|
66
|
+
!comments_contain_disables?(node, name)
|
|
67
|
+
end
|
|
61
68
|
end
|
|
62
69
|
end
|
|
63
70
|
end
|
|
@@ -50,11 +50,18 @@ module RuboCop
|
|
|
50
50
|
def on_case(node)
|
|
51
51
|
node.when_branches.each do |when_node|
|
|
52
52
|
next if when_node.body
|
|
53
|
-
next if
|
|
53
|
+
next if allow_comments?(when_node)
|
|
54
54
|
|
|
55
55
|
add_offense(when_node)
|
|
56
56
|
end
|
|
57
57
|
end
|
|
58
|
+
|
|
59
|
+
private
|
|
60
|
+
|
|
61
|
+
def allow_comments?(node)
|
|
62
|
+
cop_config['AllowComments'] && contains_comments?(node) &&
|
|
63
|
+
!comments_contain_disables?(node, name)
|
|
64
|
+
end
|
|
58
65
|
end
|
|
59
66
|
end
|
|
60
67
|
end
|
|
@@ -43,7 +43,25 @@ module RuboCop
|
|
|
43
43
|
MSG = 'Do not return from an `ensure` block.'
|
|
44
44
|
|
|
45
45
|
def on_ensure(node)
|
|
46
|
-
node.branch&.each_node(:return)
|
|
46
|
+
node.branch&.each_node(:return) do |return_node|
|
|
47
|
+
next if return_from_inner_scope?(return_node, node)
|
|
48
|
+
|
|
49
|
+
add_offense(return_node)
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
private
|
|
54
|
+
|
|
55
|
+
# A `return` inside a nested method definition or lambda within the
|
|
56
|
+
# `ensure` returns from that inner scope, not from the method whose
|
|
57
|
+
# `ensure` this is, so it is not an offense. A `return` inside a plain
|
|
58
|
+
# block (or `proc`) does propagate out, so it remains an offense.
|
|
59
|
+
def return_from_inner_scope?(return_node, ensure_node)
|
|
60
|
+
return_node.each_ancestor do |ancestor|
|
|
61
|
+
break if ancestor == ensure_node
|
|
62
|
+
return true if ancestor.any_def_type? || (ancestor.any_block_type? && ancestor.lambda?)
|
|
63
|
+
end
|
|
64
|
+
false
|
|
47
65
|
end
|
|
48
66
|
end
|
|
49
67
|
end
|
|
@@ -23,7 +23,7 @@ module RuboCop
|
|
|
23
23
|
# `ERB.new` with non-keyword arguments is deprecated since ERB 2.2.0.
|
|
24
24
|
# Use `:trim_mode` and `:eoutvar` keyword arguments to `ERB.new`.
|
|
25
25
|
# This cop identifies places where `ERB.new(str, trim_mode, eoutvar)` can
|
|
26
|
-
# be replaced by `ERB.new(str,
|
|
26
|
+
# be replaced by `ERB.new(str, trim_mode: trim_mode, eoutvar: eoutvar)`.
|
|
27
27
|
#
|
|
28
28
|
# @example
|
|
29
29
|
# # Target codes supports Ruby 2.6 and higher only
|
|
@@ -148,7 +148,9 @@ module RuboCop
|
|
|
148
148
|
arguments = node.arguments
|
|
149
149
|
overridden_kwargs = kwargs.dup
|
|
150
150
|
|
|
151
|
-
|
|
151
|
+
if arguments[2] && !arguments[2].hash_type?
|
|
152
|
+
overridden_kwargs[0] = "trim_mode: #{arguments[2].source}"
|
|
153
|
+
end
|
|
152
154
|
|
|
153
155
|
if arguments[3] && !arguments[3].hash_type?
|
|
154
156
|
overridden_kwargs[1] = "eoutvar: #{arguments[3].source}"
|
|
@@ -61,11 +61,15 @@ module RuboCop
|
|
|
61
61
|
private
|
|
62
62
|
|
|
63
63
|
def scheduler_compatible?(io1, io2)
|
|
64
|
-
return false unless
|
|
64
|
+
return false unless single_io_array?(io1)
|
|
65
65
|
|
|
66
66
|
io2&.array_type? ? io2.values.empty? : (io2.nil? || io2.nil_type?)
|
|
67
67
|
end
|
|
68
68
|
|
|
69
|
+
def single_io_array?(node)
|
|
70
|
+
node&.array_type? && node.values.size == 1 && !node.values.first.splat_type?
|
|
71
|
+
end
|
|
72
|
+
|
|
69
73
|
def preferred_method(read, write, timeout)
|
|
70
74
|
timeout_argument = timeout.nil? ? '' : "(#{timeout.source})"
|
|
71
75
|
|