rubocop 1.79.2 → 1.88.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/LICENSE.txt +1 -1
- data/README.md +2 -2
- data/config/default.yml +259 -90
- data/config/obsoletion.yml +30 -1
- data/exe/rubocop +1 -8
- data/lib/rubocop/cache_config.rb +29 -0
- data/lib/rubocop/cli/command/auto_generate_config.rb +36 -4
- data/lib/rubocop/cli/command/list_enabled_cops_for.rb +40 -0
- data/lib/rubocop/cli/command/lsp.rb +1 -1
- data/lib/rubocop/cli/command/mcp.rb +19 -0
- data/lib/rubocop/cli/command/show_cops.rb +2 -2
- data/lib/rubocop/cli/command/show_docs_url.rb +4 -8
- data/lib/rubocop/cli/command/suggest_extensions.rb +1 -1
- data/lib/rubocop/cli.rb +35 -9
- data/lib/rubocop/comment_config.rb +59 -17
- data/lib/rubocop/config.rb +14 -10
- data/lib/rubocop/config_finder.rb +1 -1
- data/lib/rubocop/config_loader.rb +37 -23
- data/lib/rubocop/config_loader_resolver.rb +20 -10
- data/lib/rubocop/config_obsoletion/extracted_cop.rb +4 -2
- data/lib/rubocop/config_store.rb +7 -2
- data/lib/rubocop/config_validator.rb +1 -1
- data/lib/rubocop/cop/autocorrect_logic.rb +10 -5
- data/lib/rubocop/cop/base.rb +25 -4
- data/lib/rubocop/cop/bundler/gem_comment.rb +2 -2
- data/lib/rubocop/cop/bundler/gem_version.rb +28 -28
- data/lib/rubocop/cop/bundler/ordered_gems.rb +1 -2
- data/lib/rubocop/cop/correctors/alignment_corrector.rb +26 -7
- data/lib/rubocop/cop/correctors/condition_corrector.rb +1 -1
- data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +7 -2
- data/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +1 -5
- data/lib/rubocop/cop/correctors/parentheses_corrector.rb +33 -2
- data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +2 -2
- data/lib/rubocop/cop/correctors.rb +28 -0
- data/lib/rubocop/cop/documentation.rb +2 -3
- data/lib/rubocop/cop/exclude_limit.rb +31 -5
- data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +2 -2
- data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +1 -2
- data/lib/rubocop/cop/gemspec/require_mfa.rb +5 -5
- data/lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb +12 -7
- data/lib/rubocop/cop/internal_affairs/example_heredoc_delimiter.rb +8 -8
- data/lib/rubocop/cop/internal_affairs/itblock_handler.rb +69 -0
- data/lib/rubocop/cop/internal_affairs/location_exists.rb +28 -2
- data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +1 -0
- data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +9 -9
- data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_processor.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/node_pattern_groups.rb +3 -1
- data/lib/rubocop/cop/internal_affairs/on_send_without_on_csend.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/redundant_let_rubocop_config_new.rb +5 -3
- data/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +4 -4
- data/lib/rubocop/cop/internal_affairs.rb +1 -0
- data/lib/rubocop/cop/layout/argument_alignment.rb +2 -2
- data/lib/rubocop/cop/layout/array_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/begin_end_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/block_alignment.rb +41 -4
- data/lib/rubocop/cop/layout/case_indentation.rb +3 -1
- data/lib/rubocop/cop/layout/class_structure.rb +14 -7
- data/lib/rubocop/cop/layout/dot_position.rb +2 -2
- data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +26 -7
- data/lib/rubocop/cop/layout/empty_line_between_defs.rb +31 -13
- data/lib/rubocop/cop/layout/empty_lines_after_module_inclusion.rb +2 -2
- data/lib/rubocop/cop/layout/empty_lines_around_attribute_accessor.rb +1 -0
- data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +12 -2
- data/lib/rubocop/cop/layout/empty_lines_around_class_body.rb +16 -2
- data/lib/rubocop/cop/layout/empty_lines_around_module_body.rb +16 -2
- data/lib/rubocop/cop/layout/end_alignment.rb +10 -3
- data/lib/rubocop/cop/layout/first_argument_indentation.rb +34 -1
- data/lib/rubocop/cop/layout/first_array_element_line_break.rb +26 -0
- data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +7 -1
- data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +25 -25
- data/lib/rubocop/cop/layout/hash_alignment.rb +3 -6
- data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +2 -2
- data/lib/rubocop/cop/layout/heredoc_indentation.rb +33 -3
- data/lib/rubocop/cop/layout/indentation_style.rb +1 -1
- data/lib/rubocop/cop/layout/indentation_width.rb +123 -7
- data/lib/rubocop/cop/layout/line_continuation_spacing.rb +1 -1
- data/lib/rubocop/cop/layout/line_length.rb +26 -9
- data/lib/rubocop/cop/layout/multiline_array_brace_layout.rb +57 -57
- data/lib/rubocop/cop/layout/multiline_assignment_layout.rb +9 -2
- data/lib/rubocop/cop/layout/multiline_block_layout.rb +2 -0
- data/lib/rubocop/cop/layout/multiline_hash_brace_layout.rb +56 -56
- data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +1 -1
- data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +229 -39
- data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +8 -4
- data/lib/rubocop/cop/layout/parameter_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/redundant_line_break.rb +3 -1
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +13 -3
- data/lib/rubocop/cop/layout/space_after_comma.rb +2 -10
- data/lib/rubocop/cop/layout/space_after_semicolon.rb +1 -1
- data/lib/rubocop/cop/layout/space_around_block_parameters.rb +1 -1
- data/lib/rubocop/cop/layout/space_around_keyword.rb +4 -2
- data/lib/rubocop/cop/layout/space_before_brackets.rb +1 -1
- data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +9 -8
- data/lib/rubocop/cop/layout/trailing_whitespace.rb +1 -1
- data/lib/rubocop/cop/lint/ambiguous_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/circular_argument_reference.rb +45 -3
- data/lib/rubocop/cop/lint/constant_overwritten_in_rescue.rb +4 -3
- data/lib/rubocop/cop/lint/constant_reassignment.rb +93 -11
- data/lib/rubocop/cop/lint/constant_resolution.rb +6 -6
- data/lib/rubocop/cop/lint/cop_directive_syntax.rb +14 -8
- data/lib/rubocop/cop/lint/data_define_override.rb +63 -0
- data/lib/rubocop/cop/lint/debugger.rb +0 -3
- data/lib/rubocop/cop/lint/deprecated_constants.rb +2 -8
- data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +4 -1
- data/lib/rubocop/cop/lint/duplicate_match_pattern.rb +4 -4
- data/lib/rubocop/cop/lint/duplicate_methods.rb +111 -12
- data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +5 -42
- data/lib/rubocop/cop/lint/else_layout.rb +19 -0
- data/lib/rubocop/cop/lint/empty_block.rb +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_interpolation.rb +11 -0
- 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/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_as_condition.rb +5 -1
- data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +11 -1
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +9 -12
- data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +19 -10
- 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 +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 +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 +27 -10
- 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_require_statement.rb +4 -2
- data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +36 -12
- data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +12 -2
- 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_exception.rb +1 -4
- 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 +39 -7
- data/lib/rubocop/cop/lint/send_with_mixin_argument.rb +1 -1
- data/lib/rubocop/cop/lint/shadowed_argument.rb +7 -7
- data/lib/rubocop/cop/lint/shadowed_exception.rb +1 -1
- data/lib/rubocop/cop/lint/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/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 +28 -1
- data/lib/rubocop/cop/lint/to_json.rb +12 -16
- 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 +4 -2
- data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +1 -0
- data/lib/rubocop/cop/lint/unreachable_code.rb +7 -5
- data/lib/rubocop/cop/lint/unreachable_pattern_branch.rb +113 -0
- data/lib/rubocop/cop/lint/unused_method_argument.rb +10 -0
- data/lib/rubocop/cop/lint/uri_escape_unescape.rb +2 -0
- data/lib/rubocop/cop/lint/useless_assignment.rb +53 -25
- data/lib/rubocop/cop/lint/useless_constant_scoping.rb +4 -4
- data/lib/rubocop/cop/lint/useless_default_value_argument.rb +2 -0
- data/lib/rubocop/cop/lint/useless_or.rb +15 -2
- data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +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 +37 -11
- data/lib/rubocop/cop/lint/void.rb +39 -12
- data/lib/rubocop/cop/message_annotator.rb +1 -1
- data/lib/rubocop/cop/metrics/block_length.rb +1 -1
- data/lib/rubocop/cop/metrics/block_nesting.rb +23 -0
- data/lib/rubocop/cop/metrics/collection_literal_length.rb +1 -1
- data/lib/rubocop/cop/metrics/method_length.rb +1 -1
- data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +4 -3
- data/lib/rubocop/cop/metrics/utils/iterating_block.rb +1 -1
- data/lib/rubocop/cop/migration/department_name.rb +12 -1
- data/lib/rubocop/cop/mixin/check_line_breakable.rb +2 -2
- data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +4 -6
- data/lib/rubocop/cop/mixin/code_length.rb +1 -1
- data/lib/rubocop/cop/mixin/configurable_max.rb +6 -5
- data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +1 -7
- data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +5 -5
- data/lib/rubocop/cop/mixin/hash_transform_method/autocorrection.rb +63 -0
- data/lib/rubocop/cop/mixin/hash_transform_method.rb +10 -60
- data/lib/rubocop/cop/mixin/line_length_help.rb +21 -2
- data/lib/rubocop/cop/mixin/method_complexity.rb +1 -1
- data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +1 -1
- data/lib/rubocop/cop/mixin/multiline_literal_brace_layout.rb +1 -1
- data/lib/rubocop/cop/mixin/project_index_help.rb +48 -0
- data/lib/rubocop/cop/mixin/space_after_punctuation.rb +5 -4
- data/lib/rubocop/cop/mixin/statement_modifier.rb +0 -6
- data/lib/rubocop/cop/mixin/trailing_comma.rb +8 -5
- data/lib/rubocop/cop/mixin.rb +86 -0
- data/lib/rubocop/cop/naming/binary_operator_parameter_name.rb +1 -1
- data/lib/rubocop/cop/naming/block_parameter_name.rb +1 -1
- data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +1 -1
- data/lib/rubocop/cop/naming/method_name.rb +5 -3
- data/lib/rubocop/cop/naming/predicate_method.rb +32 -8
- data/lib/rubocop/cop/naming/predicate_prefix.rb +12 -12
- data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +1 -1
- data/lib/rubocop/cop/offense.rb +17 -1
- data/lib/rubocop/cop/registry.rb +62 -38
- data/lib/rubocop/cop/security/eval.rb +15 -2
- data/lib/rubocop/cop/security/io_methods.rb +1 -1
- data/lib/rubocop/cop/security/json_load.rb +33 -11
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +15 -4
- data/lib/rubocop/cop/style/accessor_grouping.rb +4 -2
- data/lib/rubocop/cop/style/alias.rb +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 +50 -12
- data/lib/rubocop/cop/style/array_intersect_with_single_element.rb +50 -0
- data/lib/rubocop/cop/style/array_join.rb +4 -2
- data/lib/rubocop/cop/style/ascii_comments.rb +6 -3
- data/lib/rubocop/cop/style/attr.rb +5 -2
- data/lib/rubocop/cop/style/bare_percent_literals.rb +4 -3
- data/lib/rubocop/cop/style/begin_block.rb +3 -1
- data/lib/rubocop/cop/style/bitwise_predicate.rb +8 -1
- data/lib/rubocop/cop/style/block_delimiters.rb +39 -32
- data/lib/rubocop/cop/style/case_equality.rb +29 -15
- data/lib/rubocop/cop/style/character_literal.rb +2 -2
- data/lib/rubocop/cop/style/class_and_module_children.rb +19 -2
- data/lib/rubocop/cop/style/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 +14 -19
- data/lib/rubocop/cop/style/constant_visibility.rb +20 -12
- data/lib/rubocop/cop/style/copyright.rb +22 -11
- 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/disable_cops_within_source_code_directive.rb +1 -1
- data/lib/rubocop/cop/style/document_dynamic_eval_definition.rb +6 -1
- data/lib/rubocop/cop/style/documentation.rb +6 -6
- data/lib/rubocop/cop/style/documentation_method.rb +8 -8
- data/lib/rubocop/cop/style/double_negation.rb +1 -1
- data/lib/rubocop/cop/style/each_for_simple_loop.rb +1 -1
- data/lib/rubocop/cop/style/each_with_object.rb +2 -0
- data/lib/rubocop/cop/style/empty_block_parameter.rb +1 -1
- data/lib/rubocop/cop/style/empty_class_definition.rb +119 -0
- data/lib/rubocop/cop/style/empty_lambda_parameter.rb +1 -1
- data/lib/rubocop/cop/style/empty_method.rb +0 -6
- data/lib/rubocop/cop/style/encoding.rb +7 -1
- data/lib/rubocop/cop/style/end_block.rb +3 -1
- data/lib/rubocop/cop/style/endless_method.rb +23 -5
- data/lib/rubocop/cop/style/explicit_block_argument.rb +1 -1
- data/lib/rubocop/cop/style/fetch_env_var.rb +1 -1
- 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 +15 -1
- data/lib/rubocop/cop/style/for.rb +3 -0
- data/lib/rubocop/cop/style/format_string.rb +4 -3
- data/lib/rubocop/cop/style/format_string_token.rb +49 -5
- data/lib/rubocop/cop/style/global_vars.rb +5 -2
- data/lib/rubocop/cop/style/guard_clause.rb +27 -22
- data/lib/rubocop/cop/style/hash_as_last_array_item.rb +27 -9
- data/lib/rubocop/cop/style/hash_conversion.rb +1 -1
- data/lib/rubocop/cop/style/hash_lookup_method.rb +106 -0
- data/lib/rubocop/cop/style/hash_slice.rb +16 -0
- data/lib/rubocop/cop/style/hash_syntax.rb +1 -1
- data/lib/rubocop/cop/style/hash_transform_keys.rb +17 -7
- data/lib/rubocop/cop/style/hash_transform_values.rb +17 -7
- data/lib/rubocop/cop/style/if_inside_else.rb +16 -7
- data/lib/rubocop/cop/style/if_unless_modifier.rb +58 -18
- data/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +12 -12
- data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +4 -1
- data/lib/rubocop/cop/style/if_with_semicolon.rb +7 -5
- data/lib/rubocop/cop/style/infinite_loop.rb +1 -1
- data/lib/rubocop/cop/style/inline_comment.rb +4 -1
- data/lib/rubocop/cop/style/ip_addresses.rb +1 -2
- data/lib/rubocop/cop/style/lambda_call.rb +8 -8
- data/lib/rubocop/cop/style/magic_comment_format.rb +3 -3
- data/lib/rubocop/cop/style/map_join.rb +123 -0
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/require_parentheses.rb +15 -2
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +17 -4
- data/lib/rubocop/cop/style/method_def_parentheses.rb +2 -4
- data/lib/rubocop/cop/style/min_max_comparison.rb +1 -1
- data/lib/rubocop/cop/style/module_member_existence_check.rb +110 -0
- data/lib/rubocop/cop/style/multiline_if_then.rb +4 -4
- data/lib/rubocop/cop/style/multiline_method_signature.rb +2 -4
- data/lib/rubocop/cop/style/mutable_constant.rb +106 -12
- data/lib/rubocop/cop/style/negative_array_index.rb +220 -0
- data/lib/rubocop/cop/style/nil_comparison.rb +11 -10
- data/lib/rubocop/cop/style/nil_lambda.rb +1 -1
- data/lib/rubocop/cop/style/non_nil_check.rb +5 -11
- data/lib/rubocop/cop/style/not.rb +2 -0
- data/lib/rubocop/cop/style/numeric_literals.rb +3 -2
- data/lib/rubocop/cop/style/one_class_per_file.rb +115 -0
- data/lib/rubocop/cop/style/one_line_conditional.rb +21 -12
- data/lib/rubocop/cop/style/operator_method_call.rb +11 -2
- data/lib/rubocop/cop/style/parallel_assignment.rb +14 -3
- data/lib/rubocop/cop/style/partition_instead_of_double_select.rb +270 -0
- data/lib/rubocop/cop/style/percent_literal_delimiters.rb +2 -0
- data/lib/rubocop/cop/style/predicate_with_kind.rb +84 -0
- data/lib/rubocop/cop/style/preferred_hash_methods.rb +12 -12
- data/lib/rubocop/cop/style/proc.rb +3 -2
- data/lib/rubocop/cop/style/raise_args.rb +1 -1
- data/lib/rubocop/cop/style/reduce_to_hash.rb +200 -0
- data/lib/rubocop/cop/style/redundant_argument.rb +2 -0
- data/lib/rubocop/cop/style/redundant_array_constructor.rb +2 -2
- data/lib/rubocop/cop/style/redundant_begin.rb +37 -3
- data/lib/rubocop/cop/style/redundant_condition.rb +6 -3
- data/lib/rubocop/cop/style/redundant_constant_base.rb +5 -5
- data/lib/rubocop/cop/style/redundant_each.rb +3 -3
- data/lib/rubocop/cop/style/redundant_exception.rb +1 -1
- data/lib/rubocop/cop/style/redundant_fetch_block.rb +1 -1
- data/lib/rubocop/cop/style/redundant_format.rb +27 -5
- data/lib/rubocop/cop/style/redundant_interpolation.rb +11 -2
- data/lib/rubocop/cop/style/redundant_interpolation_unfreeze.rb +26 -10
- data/lib/rubocop/cop/style/redundant_line_continuation.rb +16 -0
- data/lib/rubocop/cop/style/redundant_min_max_by.rb +93 -0
- data/lib/rubocop/cop/style/redundant_parentheses.rb +36 -30
- data/lib/rubocop/cop/style/redundant_percent_q.rb +5 -3
- data/lib/rubocop/cop/style/redundant_regexp_argument.rb +9 -0
- data/lib/rubocop/cop/style/redundant_regexp_constructor.rb +2 -2
- data/lib/rubocop/cop/style/redundant_regexp_escape.rb +8 -0
- data/lib/rubocop/cop/style/redundant_return.rb +3 -1
- data/lib/rubocop/cop/style/redundant_self.rb +2 -2
- data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +0 -5
- data/lib/rubocop/cop/style/redundant_sort.rb +7 -7
- data/lib/rubocop/cop/style/redundant_struct_keyword_init.rb +114 -0
- data/lib/rubocop/cop/style/regexp_literal.rb +31 -2
- data/lib/rubocop/cop/style/rescue_modifier.rb +3 -3
- data/lib/rubocop/cop/style/reverse_find.rb +51 -0
- data/lib/rubocop/cop/style/safe_navigation.rb +25 -8
- data/lib/rubocop/cop/style/select_by_kind.rb +158 -0
- data/lib/rubocop/cop/style/select_by_range.rb +197 -0
- data/lib/rubocop/cop/style/select_by_regexp.rb +51 -21
- data/lib/rubocop/cop/style/self_assignment.rb +1 -1
- data/lib/rubocop/cop/style/semicolon.rb +41 -8
- data/lib/rubocop/cop/style/single_line_block_params.rb +2 -2
- data/lib/rubocop/cop/style/single_line_do_end_block.rb +1 -1
- data/lib/rubocop/cop/style/single_line_methods.rb +3 -1
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +12 -3
- data/lib/rubocop/cop/style/special_global_vars.rb +6 -1
- data/lib/rubocop/cop/style/string_concatenation.rb +17 -13
- data/lib/rubocop/cop/style/struct_inheritance.rb +13 -0
- data/lib/rubocop/cop/style/super_arguments.rb +2 -2
- data/lib/rubocop/cop/style/symbol_array.rb +1 -1
- data/lib/rubocop/cop/style/symbol_proc.rb +7 -6
- data/lib/rubocop/cop/style/tally_method.rb +181 -0
- data/lib/rubocop/cop/style/top_level_method_definition.rb +2 -2
- data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +45 -0
- data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +1 -1
- data/lib/rubocop/cop/style/trailing_method_end_statement.rb +1 -0
- data/lib/rubocop/cop/style/trailing_underscore_variable.rb +11 -11
- data/lib/rubocop/cop/style/unless_else.rb +10 -9
- data/lib/rubocop/cop/style/unless_logical_operators.rb +3 -3
- data/lib/rubocop/cop/style/while_until_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 +87 -36
- data/lib/rubocop/cop/util.rb +2 -3
- data/lib/rubocop/cop/utils/format_string.rb +10 -0
- data/lib/rubocop/cop/variable_force/branch.rb +30 -6
- data/lib/rubocop/cop/variable_force/variable.rb +1 -1
- data/lib/rubocop/cop/variable_force.rb +9 -7
- data/lib/rubocop/cops_documentation_generator.rb +4 -4
- data/lib/rubocop/directive_comment.rb +48 -4
- data/lib/rubocop/file_patterns.rb +9 -1
- data/lib/rubocop/formatter/clang_style_formatter.rb +5 -2
- data/lib/rubocop/formatter/disabled_config_formatter.rb +38 -14
- data/lib/rubocop/formatter/formatter_set.rb +2 -2
- data/lib/rubocop/formatter/junit_formatter.rb +1 -1
- data/lib/rubocop/formatter/simple_text_formatter.rb +0 -2
- data/lib/rubocop/formatter/tap_formatter.rb +5 -2
- data/lib/rubocop/formatter/worst_offenders_formatter.rb +1 -1
- data/lib/rubocop/formatter.rb +22 -21
- data/lib/rubocop/lsp/diagnostic.rb +18 -33
- data/lib/rubocop/lsp/disable_comment_edits.rb +135 -0
- data/lib/rubocop/lsp/routes.rb +43 -7
- data/lib/rubocop/lsp/runtime.rb +13 -4
- data/lib/rubocop/lsp/stdin_runner.rb +8 -17
- data/lib/rubocop/magic_comment.rb +20 -0
- data/lib/rubocop/mcp/server.rb +200 -0
- data/lib/rubocop/options.rb +35 -4
- data/lib/rubocop/path_util.rb +14 -2
- data/lib/rubocop/plugin/loader.rb +1 -1
- data/lib/rubocop/project_index_loader.rb +66 -0
- data/lib/rubocop/rake_task.rb +1 -1
- data/lib/rubocop/remote_config.rb +10 -8
- data/lib/rubocop/result_cache.rb +61 -38
- data/lib/rubocop/rspec/cop_helper.rb +8 -0
- data/lib/rubocop/rspec/shared_contexts.rb +39 -5
- data/lib/rubocop/rspec/support.rb +2 -1
- data/lib/rubocop/runner.rb +134 -57
- data/lib/rubocop/server/cache.rb +6 -29
- data/lib/rubocop/server/core.rb +8 -0
- data/lib/rubocop/target_finder.rb +17 -10
- data/lib/rubocop/target_ruby.rb +31 -14
- data/lib/rubocop/version.rb +21 -3
- data/lib/rubocop.rb +28 -96
- data/lib/ruby_lsp/rubocop/addon.rb +23 -8
- data/lib/ruby_lsp/rubocop/runtime_adapter.rb +49 -15
- metadata +38 -9
|
@@ -6,22 +6,40 @@ module RuboCop
|
|
|
6
6
|
# Checks for the use of JSON class methods which have potential
|
|
7
7
|
# security issues.
|
|
8
8
|
#
|
|
9
|
+
# `JSON.load` and similar methods allow deserialization of arbitrary ruby objects:
|
|
10
|
+
#
|
|
11
|
+
# [source,ruby]
|
|
12
|
+
# ----
|
|
13
|
+
# require 'json/add/string'
|
|
14
|
+
# result = JSON.load('{ "json_class": "String", "raw": [72, 101, 108, 108, 111] }')
|
|
15
|
+
# pp result # => "Hello"
|
|
16
|
+
# ----
|
|
17
|
+
#
|
|
18
|
+
# Never use `JSON.load` for untrusted user input. Prefer `JSON.parse` unless you have
|
|
19
|
+
# a concrete use-case for `JSON.load`.
|
|
20
|
+
#
|
|
21
|
+
# NOTE: Starting with `json` gem version 2.8.0, triggering this behavior without explicitly
|
|
22
|
+
# passing the `create_additions` keyword argument emits a deprecation warning, with the
|
|
23
|
+
# goal of being secure by default in the next major version 3.0.0.
|
|
24
|
+
#
|
|
9
25
|
# @safety
|
|
10
26
|
# This cop's autocorrection is unsafe because it's potentially dangerous.
|
|
11
|
-
# If using a stream, like `JSON.load(open('file'))`,
|
|
27
|
+
# If using a stream, like `JSON.load(open('file'))`, you will need to call
|
|
12
28
|
# `#read` manually, like `JSON.parse(open('file').read)`.
|
|
13
|
-
# If reading single values (rather than proper JSON objects), like
|
|
14
|
-
# `JSON.load('false')`, it will need to pass the `quirks_mode: true`
|
|
15
|
-
# option, like `JSON.parse('false', quirks_mode: true)`.
|
|
16
29
|
# Other similar issues may apply.
|
|
17
30
|
#
|
|
18
31
|
# @example
|
|
19
32
|
# # bad
|
|
20
|
-
# JSON.load(
|
|
21
|
-
# JSON.restore(
|
|
33
|
+
# JSON.load('{}')
|
|
34
|
+
# JSON.restore('{}')
|
|
22
35
|
#
|
|
23
36
|
# # good
|
|
24
|
-
# JSON.parse(
|
|
37
|
+
# JSON.parse('{}')
|
|
38
|
+
# JSON.unsafe_load('{}')
|
|
39
|
+
#
|
|
40
|
+
# # good - explicit use of `create_additions` option
|
|
41
|
+
# JSON.load('{}', create_additions: true)
|
|
42
|
+
# JSON.load('{}', create_additions: false)
|
|
25
43
|
#
|
|
26
44
|
class JSONLoad < Base
|
|
27
45
|
extend AutoCorrector
|
|
@@ -29,13 +47,17 @@ module RuboCop
|
|
|
29
47
|
MSG = 'Prefer `JSON.parse` over `JSON.%<method>s`.'
|
|
30
48
|
RESTRICT_ON_SEND = %i[load restore].freeze
|
|
31
49
|
|
|
32
|
-
# @!method
|
|
33
|
-
def_node_matcher :
|
|
34
|
-
(
|
|
50
|
+
# @!method insecure_json_load(node)
|
|
51
|
+
def_node_matcher :insecure_json_load, <<~PATTERN
|
|
52
|
+
(
|
|
53
|
+
send (const {nil? cbase} :JSON) ${:load :restore}
|
|
54
|
+
...
|
|
55
|
+
!`(pair (sym :create_additions) _)
|
|
56
|
+
)
|
|
35
57
|
PATTERN
|
|
36
58
|
|
|
37
59
|
def on_send(node)
|
|
38
|
-
|
|
60
|
+
insecure_json_load(node) do |method|
|
|
39
61
|
add_offense(node.loc.selector, message: format(MSG, method: method)) do |corrector|
|
|
40
62
|
corrector.replace(node.loc.selector, 'parse')
|
|
41
63
|
end
|
|
@@ -326,8 +326,7 @@ module RuboCop
|
|
|
326
326
|
argument_less_modifier_node = find_argument_less_modifier_node(node)
|
|
327
327
|
if argument_less_modifier_node
|
|
328
328
|
corrector.insert_after(argument_less_modifier_node, "\n\n#{source}")
|
|
329
|
-
elsif (ancestor = node.each_ancestor(:class, :module).first)
|
|
330
|
-
|
|
329
|
+
elsif (ancestor = node.each_ancestor(:class, :module, :sclass).first)
|
|
331
330
|
corrector.insert_before(ancestor.loc.end, "#{node.method_name}\n\n#{source}\n")
|
|
332
331
|
else
|
|
333
332
|
corrector.replace(node, "#{node.method_name}\n\n#{source}")
|
|
@@ -349,8 +348,20 @@ module RuboCop
|
|
|
349
348
|
|
|
350
349
|
def remove_modifier_node_within_begin(corrector, modifier_node, begin_node)
|
|
351
350
|
def_node = begin_node.children[begin_node.children.index(modifier_node) + 1]
|
|
352
|
-
range
|
|
353
|
-
|
|
351
|
+
# Stop the removal range at the first comment that precedes the def, if
|
|
352
|
+
# any exist. Without this, comments between the modifier and the def are
|
|
353
|
+
# dropped because they fall inside the removed range.
|
|
354
|
+
end_pos = first_comment_or_node_start(def_node)
|
|
355
|
+
corrector.remove(modifier_node.source_range.begin.join(end_pos))
|
|
356
|
+
end
|
|
357
|
+
|
|
358
|
+
def first_comment_or_node_start(node)
|
|
359
|
+
preceding = processed_source.ast_with_comments[node].select do |comment|
|
|
360
|
+
comment.loc.line < node.loc.line
|
|
361
|
+
end
|
|
362
|
+
return node.source_range.begin if preceding.empty?
|
|
363
|
+
|
|
364
|
+
preceding.first.source_range.begin
|
|
354
365
|
end
|
|
355
366
|
|
|
356
367
|
def def_source(node, def_nodes)
|
|
@@ -4,8 +4,10 @@ module RuboCop
|
|
|
4
4
|
module Cop
|
|
5
5
|
module Style
|
|
6
6
|
# Checks for grouping of accessors in `class` and `module` bodies.
|
|
7
|
-
# By default it enforces accessors to be placed in grouped
|
|
8
|
-
#
|
|
7
|
+
# By default it enforces accessors to be placed in grouped
|
|
8
|
+
# declarations, reducing boilerplate. It can also be configured
|
|
9
|
+
# to enforce separating them into individual declarations for
|
|
10
|
+
# easier diffing and per-attribute documentation.
|
|
9
11
|
#
|
|
10
12
|
# NOTE: If there is a method call before the accessor method it is always allowed
|
|
11
13
|
# as it might be intended like Sorbet.
|
|
@@ -4,10 +4,13 @@ module RuboCop
|
|
|
4
4
|
module Cop
|
|
5
5
|
module Style
|
|
6
6
|
# Enforces the use of either `#alias` or `#alias_method`
|
|
7
|
-
# depending on configuration.
|
|
7
|
+
# depending on configuration. Consistent use of one or the
|
|
8
|
+
# other prevents confusion about their different semantics
|
|
9
|
+
# (e.g., `alias` is resolved at parse time, while `alias_method`
|
|
10
|
+
# is resolved at runtime).
|
|
8
11
|
# It also flags uses of `alias :symbol` rather than `alias bareword`.
|
|
9
12
|
#
|
|
10
|
-
# However, it will always enforce `
|
|
13
|
+
# However, it will always enforce `alias_method` when `alias` is used
|
|
11
14
|
# in an instance method definition and in a singleton method definition.
|
|
12
15
|
# If used in a block, always enforce `alias_method`
|
|
13
16
|
# unless it is an `instance_eval` block.
|
|
@@ -42,6 +45,7 @@ module RuboCop
|
|
|
42
45
|
return unless node.command?(:alias_method)
|
|
43
46
|
return unless style == :prefer_alias && alias_keyword_possible?(node)
|
|
44
47
|
return unless node.arguments.count == 2
|
|
48
|
+
return if alias_method_value_used?(node)
|
|
45
49
|
|
|
46
50
|
msg = format(MSG_ALIAS_METHOD, current: lexical_scope_type(node))
|
|
47
51
|
add_offense(node.loc.selector, message: msg) do |corrector|
|
|
@@ -77,6 +81,14 @@ module RuboCop
|
|
|
77
81
|
scope_type(node) != :dynamic && node.arguments.all?(&:sym_type?)
|
|
78
82
|
end
|
|
79
83
|
|
|
84
|
+
# `alias_method` is a method call whose return value can be used
|
|
85
|
+
# (e.g., as an argument to `public`/`module_function`, or as an assignment),
|
|
86
|
+
# but `alias` is a keyword statement that cannot appear in such positions.
|
|
87
|
+
# Detect these positions so the conversion does not produce a syntax error.
|
|
88
|
+
def alias_method_value_used?(node)
|
|
89
|
+
node.argument? || node.parent&.assignment?
|
|
90
|
+
end
|
|
91
|
+
|
|
80
92
|
def alias_method_possible?(node)
|
|
81
93
|
scope_type(node) != :instance_eval &&
|
|
82
94
|
node.children.none?(&:gvar_type?) &&
|
|
@@ -101,7 +113,7 @@ module RuboCop
|
|
|
101
113
|
return :lexical
|
|
102
114
|
when :def, :defs
|
|
103
115
|
return :dynamic
|
|
104
|
-
when :block
|
|
116
|
+
when :block, :numblock, :itblock
|
|
105
117
|
return :instance_eval if parent.method?(:instance_eval)
|
|
106
118
|
|
|
107
119
|
return :dynamic
|
|
@@ -71,7 +71,7 @@ module RuboCop
|
|
|
71
71
|
node.each_child_node do |expr|
|
|
72
72
|
if expr.send_type?
|
|
73
73
|
correct_send(expr, corrector)
|
|
74
|
-
elsif expr.
|
|
74
|
+
elsif expr.type?(:return, :next, :break, :yield) || expr.assignment?
|
|
75
75
|
correct_other(expr, corrector)
|
|
76
76
|
end
|
|
77
77
|
end
|
|
@@ -128,6 +128,7 @@ module RuboCop
|
|
|
128
128
|
|
|
129
129
|
def correct_other(node, corrector)
|
|
130
130
|
return if node.parenthesized_call?
|
|
131
|
+
return if node.children.empty? && node.equal?(node.parent.children.last)
|
|
131
132
|
|
|
132
133
|
corrector.wrap(node, '(', ')')
|
|
133
134
|
end
|
|
@@ -424,21 +424,39 @@ module RuboCop
|
|
|
424
424
|
end
|
|
425
425
|
|
|
426
426
|
def forwarded_rest_arg
|
|
427
|
-
return
|
|
427
|
+
return @forwarded_rest_arg if defined?(@forwarded_rest_arg)
|
|
428
428
|
|
|
429
|
-
|
|
429
|
+
@forwarded_rest_arg = if referenced_rest_arg?
|
|
430
|
+
nil
|
|
431
|
+
else
|
|
432
|
+
arguments.find do |arg|
|
|
433
|
+
forwarded_rest_arg?(arg, @rest_arg_name)
|
|
434
|
+
end
|
|
435
|
+
end
|
|
430
436
|
end
|
|
431
437
|
|
|
432
438
|
def forwarded_kwrest_arg
|
|
433
|
-
return
|
|
439
|
+
return @forwarded_kwrest_arg if defined?(@forwarded_kwrest_arg)
|
|
434
440
|
|
|
435
|
-
|
|
441
|
+
@forwarded_kwrest_arg = if referenced_kwrest_arg?
|
|
442
|
+
nil
|
|
443
|
+
else
|
|
444
|
+
arguments.filter_map do |arg|
|
|
445
|
+
extract_forwarded_kwrest_arg(arg, @kwrest_arg_name)
|
|
446
|
+
end.first
|
|
447
|
+
end
|
|
436
448
|
end
|
|
437
449
|
|
|
438
450
|
def forwarded_block_arg
|
|
439
|
-
return
|
|
440
|
-
|
|
441
|
-
|
|
451
|
+
return @forwarded_block_arg if defined?(@forwarded_block_arg)
|
|
452
|
+
|
|
453
|
+
@forwarded_block_arg = if referenced_block_arg?
|
|
454
|
+
nil
|
|
455
|
+
else
|
|
456
|
+
arguments.find do |arg|
|
|
457
|
+
forwarded_block_arg?(arg, @block_arg_name)
|
|
458
|
+
end
|
|
459
|
+
end
|
|
442
460
|
end
|
|
443
461
|
|
|
444
462
|
def classification
|
|
@@ -40,8 +40,9 @@ module RuboCop
|
|
|
40
40
|
|
|
41
41
|
node = innermost_braces_node(node)
|
|
42
42
|
return if node.parent && brace_method?(node.parent)
|
|
43
|
+
return if compound_assignment_target?(node)
|
|
43
44
|
|
|
44
|
-
preferred = (value
|
|
45
|
+
preferred = preferred_name(value)
|
|
45
46
|
offense_range = find_offense_range(node)
|
|
46
47
|
|
|
47
48
|
add_offense(offense_range, message: format(MSG, preferred: preferred)) do |corrector|
|
|
@@ -53,6 +54,10 @@ module RuboCop
|
|
|
53
54
|
|
|
54
55
|
private
|
|
55
56
|
|
|
57
|
+
def preferred_name(value)
|
|
58
|
+
value.zero? ? 'first' : 'last'
|
|
59
|
+
end
|
|
60
|
+
|
|
56
61
|
def preferred_value(node, value)
|
|
57
62
|
value = ".#{value}" unless node.loc.dot
|
|
58
63
|
value
|
|
@@ -74,6 +79,12 @@ module RuboCop
|
|
|
74
79
|
def brace_method?(node)
|
|
75
80
|
node.send_type? && (node.method?(:[]) || node.method?(:[]=))
|
|
76
81
|
end
|
|
82
|
+
|
|
83
|
+
# `arr[0] += 1` etc. would autocorrect to `arr.first += 1`, which calls the
|
|
84
|
+
# nonexistent `first=`/`last=` setter and raises `NoMethodError`.
|
|
85
|
+
def compound_assignment_target?(node)
|
|
86
|
+
node.parent&.type?(:op_asgn, :or_asgn, :and_asgn) && node.parent.children.first == node
|
|
87
|
+
end
|
|
77
88
|
end
|
|
78
89
|
end
|
|
79
90
|
end
|
|
@@ -10,6 +10,8 @@ module RuboCop
|
|
|
10
10
|
# * `(array1 & array2).any?`
|
|
11
11
|
# * `(array1.intersection(array2)).any?`
|
|
12
12
|
# * `array1.any? { |elem| array2.member?(elem) }`
|
|
13
|
+
# * `(array1 & array2).count > 0`
|
|
14
|
+
# * `(array1 & array2).size > 0`
|
|
13
15
|
#
|
|
14
16
|
# can be replaced with `array1.intersect?(array2)`.
|
|
15
17
|
#
|
|
@@ -51,6 +53,19 @@ module RuboCop
|
|
|
51
53
|
# array1.intersect?(array2)
|
|
52
54
|
# !array1.intersect?(array2)
|
|
53
55
|
#
|
|
56
|
+
# # bad
|
|
57
|
+
# (array1 & array2).count > 0
|
|
58
|
+
# (array1 & array2).count.positive?
|
|
59
|
+
# (array1 & array2).count != 0
|
|
60
|
+
#
|
|
61
|
+
# (array1 & array2).count == 0
|
|
62
|
+
# (array1 & array2).count.zero?
|
|
63
|
+
#
|
|
64
|
+
# # good
|
|
65
|
+
# array1.intersect?(array2)
|
|
66
|
+
#
|
|
67
|
+
# !array1.intersect?(array2)
|
|
68
|
+
#
|
|
54
69
|
# @example AllCops:ActiveSupportExtensionsEnabled: false (default)
|
|
55
70
|
# # good
|
|
56
71
|
# (array1 & array2).present?
|
|
@@ -73,17 +88,33 @@ module RuboCop
|
|
|
73
88
|
PREDICATES = %i[any? empty? none?].to_set.freeze
|
|
74
89
|
ACTIVE_SUPPORT_PREDICATES = (PREDICATES + %i[present? blank?]).freeze
|
|
75
90
|
|
|
91
|
+
ARRAY_SIZE_METHODS = %i[count length size].to_set.freeze
|
|
92
|
+
|
|
76
93
|
# @!method bad_intersection_check?(node, predicates)
|
|
77
94
|
def_node_matcher :bad_intersection_check?, <<~PATTERN
|
|
78
|
-
(call
|
|
95
|
+
$(call
|
|
79
96
|
{
|
|
80
97
|
(begin (send $_ :& $_))
|
|
81
|
-
(call
|
|
98
|
+
(call $!nil? :intersection $_)
|
|
82
99
|
}
|
|
83
100
|
$%1
|
|
84
101
|
)
|
|
85
102
|
PATTERN
|
|
86
103
|
|
|
104
|
+
# @!method intersection_size_check?(node, predicates)
|
|
105
|
+
def_node_matcher :intersection_size_check?, <<~PATTERN
|
|
106
|
+
(call
|
|
107
|
+
$(call
|
|
108
|
+
{
|
|
109
|
+
(begin (send $_ :& $_))
|
|
110
|
+
(call $!nil? :intersection $_)
|
|
111
|
+
}
|
|
112
|
+
%ARRAY_SIZE_METHODS
|
|
113
|
+
)
|
|
114
|
+
{$:> (int 0) | $:positive? | $:!= (int 0) | $:== (int 0) | $:zero?}
|
|
115
|
+
)
|
|
116
|
+
PATTERN
|
|
117
|
+
|
|
87
118
|
# @!method any_none_block_intersection(node)
|
|
88
119
|
def_node_matcher :any_none_block_intersection, <<~PATTERN
|
|
89
120
|
{
|
|
@@ -104,16 +135,20 @@ module RuboCop
|
|
|
104
135
|
PATTERN
|
|
105
136
|
|
|
106
137
|
MSG = 'Use `%<replacement>s` instead of `%<existing>s`.'
|
|
107
|
-
STRAIGHT_METHODS = %i[present? any?].freeze
|
|
108
|
-
NEGATED_METHODS = %i[blank? empty? none?].freeze
|
|
138
|
+
STRAIGHT_METHODS = %i[present? any? > positive? !=].freeze
|
|
139
|
+
NEGATED_METHODS = %i[blank? empty? none? == zero?].freeze
|
|
109
140
|
RESTRICT_ON_SEND = (STRAIGHT_METHODS + NEGATED_METHODS).freeze
|
|
110
141
|
|
|
111
142
|
def on_send(node)
|
|
112
143
|
return if node.block_literal?
|
|
113
|
-
return unless (receiver, argument, method_name = bad_intersection?(node))
|
|
144
|
+
return unless (dot_node, receiver, argument, method_name = bad_intersection?(node))
|
|
114
145
|
|
|
115
|
-
dot =
|
|
146
|
+
dot = dot_node.loc.dot.source
|
|
116
147
|
bang = straight?(method_name) ? '' : '!'
|
|
148
|
+
# `a&.intersection(b)&.none?` returns `nil` when `a` is `nil`, but the negated
|
|
149
|
+
# rewrite `!a&.intersect?(b)` returns `true` there, flipping the result.
|
|
150
|
+
return if bang == '!' && dot == '&.'
|
|
151
|
+
|
|
117
152
|
replacement = "#{bang}#{receiver.source}#{dot}intersect?(#{argument.source})"
|
|
118
153
|
|
|
119
154
|
register_offense(node, replacement)
|
|
@@ -135,13 +170,16 @@ module RuboCop
|
|
|
135
170
|
private
|
|
136
171
|
|
|
137
172
|
def bad_intersection?(node)
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
PREDICATES
|
|
142
|
-
end
|
|
173
|
+
bad_intersection_check?(node, bad_intersection_predicates) ||
|
|
174
|
+
intersection_size_check?(node)
|
|
175
|
+
end
|
|
143
176
|
|
|
144
|
-
|
|
177
|
+
def bad_intersection_predicates
|
|
178
|
+
if active_support_extensions_enabled?
|
|
179
|
+
ACTIVE_SUPPORT_PREDICATES
|
|
180
|
+
else
|
|
181
|
+
PREDICATES
|
|
182
|
+
end
|
|
145
183
|
end
|
|
146
184
|
|
|
147
185
|
def straight?(method_name)
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module Cop
|
|
5
|
+
module Style
|
|
6
|
+
# Use `include?(element)` instead of `intersect?([element])`.
|
|
7
|
+
#
|
|
8
|
+
# @safety
|
|
9
|
+
# The receiver might not be an array.
|
|
10
|
+
#
|
|
11
|
+
# @example
|
|
12
|
+
# # bad
|
|
13
|
+
# array.intersect?([element])
|
|
14
|
+
#
|
|
15
|
+
# # good
|
|
16
|
+
# array.include?(element)
|
|
17
|
+
class ArrayIntersectWithSingleElement < Base
|
|
18
|
+
extend AutoCorrector
|
|
19
|
+
|
|
20
|
+
MSG = 'Use `include?(element)` instead of `intersect?([element])`.'
|
|
21
|
+
|
|
22
|
+
RESTRICT_ON_SEND = %i[intersect?].freeze
|
|
23
|
+
|
|
24
|
+
# @!method single_element(node)
|
|
25
|
+
def_node_matcher :single_element, <<~PATTERN
|
|
26
|
+
(send _ _ $(array $_))
|
|
27
|
+
PATTERN
|
|
28
|
+
|
|
29
|
+
def on_send(node)
|
|
30
|
+
array, element = single_element(node)
|
|
31
|
+
return unless array
|
|
32
|
+
# `[*foo]` is not a single element: the splat can expand to any number of
|
|
33
|
+
# elements, so `intersect?([*foo])` is not equivalent to `include?(*foo)`.
|
|
34
|
+
return if element.splat_type?
|
|
35
|
+
|
|
36
|
+
add_offense(
|
|
37
|
+
node.source_range.with(begin_pos: node.loc.selector.begin_pos)
|
|
38
|
+
) do |corrector|
|
|
39
|
+
corrector.replace(node.loc.selector, 'include?')
|
|
40
|
+
corrector.replace(
|
|
41
|
+
array,
|
|
42
|
+
array.percent_literal? ? element.value.inspect : element.source
|
|
43
|
+
)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
alias on_csend on_send
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -3,9 +3,11 @@
|
|
|
3
3
|
module RuboCop
|
|
4
4
|
module Cop
|
|
5
5
|
module Style
|
|
6
|
-
# Checks for uses of
|
|
6
|
+
# Checks for uses of `*` as a substitute for `Array#join`.
|
|
7
|
+
# Using `join` is clearer about intent and more readable than
|
|
8
|
+
# overloading the `*` operator for string conversion.
|
|
7
9
|
#
|
|
8
|
-
# Not all cases can reliably checked, due to Ruby's dynamic
|
|
10
|
+
# Not all cases can be reliably checked, due to Ruby's dynamic
|
|
9
11
|
# types, so we consider only cases when the first argument is an
|
|
10
12
|
# array literal or the second is a string literal.
|
|
11
13
|
#
|
|
@@ -4,8 +4,11 @@ module RuboCop
|
|
|
4
4
|
module Cop
|
|
5
5
|
module Style
|
|
6
6
|
# Checks for non-ascii (non-English) characters
|
|
7
|
-
# in comments.
|
|
8
|
-
#
|
|
7
|
+
# in comments. Non-ascii characters can cause issues with
|
|
8
|
+
# portability and encoding across different environments
|
|
9
|
+
# and editors. You could set an array of allowed non-ascii
|
|
10
|
+
# chars in `AllowedChars` attribute (copyright notice "©"
|
|
11
|
+
# by default).
|
|
9
12
|
#
|
|
10
13
|
# @example
|
|
11
14
|
# # bad
|
|
@@ -49,7 +52,7 @@ module RuboCop
|
|
|
49
52
|
end
|
|
50
53
|
|
|
51
54
|
def allowed_non_ascii_chars
|
|
52
|
-
cop_config['AllowedChars'] || []
|
|
55
|
+
@allowed_non_ascii_chars ||= (cop_config['AllowedChars'] || []).freeze
|
|
53
56
|
end
|
|
54
57
|
end
|
|
55
58
|
end
|
|
@@ -3,10 +3,13 @@
|
|
|
3
3
|
module RuboCop
|
|
4
4
|
module Cop
|
|
5
5
|
module Style
|
|
6
|
-
# Checks for uses of Module#attr
|
|
6
|
+
# Checks for uses of `Module#attr`. The `attr` method has confusing
|
|
7
|
+
# behavior: with a single argument it creates a reader (like `attr_reader`),
|
|
8
|
+
# but with a second boolean argument it creates an accessor (deprecated in
|
|
9
|
+
# Ruby 1.9). Use `attr_reader` or `attr_accessor` to make intent explicit.
|
|
7
10
|
#
|
|
8
11
|
# @example
|
|
9
|
-
# # bad
|
|
12
|
+
# # bad
|
|
10
13
|
# attr :something, true
|
|
11
14
|
# attr :one, :two, :three # behaves as attr_reader
|
|
12
15
|
#
|
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
module RuboCop
|
|
4
4
|
module Cop
|
|
5
5
|
module Style
|
|
6
|
-
# Checks if usage of
|
|
6
|
+
# Checks if usage of `%()` or `%Q()` matches configuration.
|
|
7
|
+
# Consistent use of one style makes the codebase easier
|
|
8
|
+
# to read.
|
|
7
9
|
#
|
|
8
10
|
# @example EnforcedStyle: bare_percent (default)
|
|
9
11
|
# # bad
|
|
@@ -41,8 +43,7 @@ module RuboCop
|
|
|
41
43
|
|
|
42
44
|
def check(node)
|
|
43
45
|
return if node.heredoc?
|
|
44
|
-
return unless node.loc
|
|
45
|
-
return unless node.loc.begin
|
|
46
|
+
return unless node.loc?(:begin)
|
|
46
47
|
|
|
47
48
|
source = node.loc.begin.source
|
|
48
49
|
if requires_percent_q?(source)
|
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
module RuboCop
|
|
4
4
|
module Cop
|
|
5
5
|
module Style
|
|
6
|
-
# Checks for BEGIN blocks.
|
|
6
|
+
# Checks for `BEGIN` blocks. They are Perl-style constructs that execute
|
|
7
|
+
# code before the rest of the file is parsed, making the control flow
|
|
8
|
+
# harder to follow and reason about.
|
|
7
9
|
#
|
|
8
10
|
# @example
|
|
9
11
|
# # bad
|
|
@@ -70,18 +70,25 @@ module RuboCop
|
|
|
70
70
|
(send _ :& _))
|
|
71
71
|
PATTERN
|
|
72
72
|
|
|
73
|
+
# rubocop:disable Metrics/AbcSize
|
|
73
74
|
def on_send(node)
|
|
74
75
|
return unless node.receiver&.begin_type?
|
|
75
76
|
return unless (preferred_method = preferred_method(node))
|
|
76
77
|
|
|
77
78
|
bit_operation = node.receiver.children.first
|
|
78
79
|
lhs, _operator, rhs = *bit_operation
|
|
79
|
-
|
|
80
|
+
|
|
81
|
+
preferred = if preferred_method == 'allbits?' && lhs.source == node.first_argument.source
|
|
82
|
+
"#{rhs.source}.allbits?(#{lhs.source})"
|
|
83
|
+
else
|
|
84
|
+
"#{lhs.source}.#{preferred_method}(#{rhs.source})"
|
|
85
|
+
end
|
|
80
86
|
|
|
81
87
|
add_offense(node, message: format(MSG, preferred: preferred)) do |corrector|
|
|
82
88
|
corrector.replace(node, preferred)
|
|
83
89
|
end
|
|
84
90
|
end
|
|
91
|
+
# rubocop:enable Metrics/AbcSize
|
|
85
92
|
|
|
86
93
|
private
|
|
87
94
|
|