rubocop 1.59.0 → 1.68.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/LICENSE.txt +1 -1
- data/README.md +69 -70
- data/assets/output.css.erb +159 -0
- data/assets/output.html.erb +1 -160
- data/config/default.yml +165 -24
- data/config/internal_affairs.yml +11 -0
- data/exe/rubocop +4 -3
- data/lib/rubocop/cached_data.rb +21 -5
- data/lib/rubocop/cli/command/auto_generate_config.rb +18 -10
- data/lib/rubocop/cli/command/execute_runner.rb +1 -1
- data/lib/rubocop/cli/command/lsp.rb +4 -4
- data/lib/rubocop/cli/command/show_docs_url.rb +2 -2
- data/lib/rubocop/cli/command/version.rb +2 -2
- data/lib/rubocop/cli.rb +10 -1
- data/lib/rubocop/comment_config.rb +1 -1
- data/lib/rubocop/config.rb +41 -13
- data/lib/rubocop/config_finder.rb +12 -2
- data/lib/rubocop/config_loader.rb +15 -10
- data/lib/rubocop/config_loader_resolver.rb +13 -8
- data/lib/rubocop/config_obsoletion.rb +1 -1
- data/lib/rubocop/config_validator.rb +17 -9
- data/lib/rubocop/cop/autocorrect_logic.rb +28 -3
- data/lib/rubocop/cop/base.rb +73 -18
- data/lib/rubocop/cop/bundler/gem_version.rb +4 -5
- data/lib/rubocop/cop/cop.rb +30 -4
- data/lib/rubocop/cop/correctors/alignment_corrector.rb +1 -12
- data/lib/rubocop/cop/correctors/each_to_for_corrector.rb +4 -8
- data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +5 -13
- data/lib/rubocop/cop/correctors/line_break_corrector.rb +2 -0
- data/lib/rubocop/cop/correctors/parentheses_corrector.rb +1 -1
- data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +10 -0
- data/lib/rubocop/cop/documentation.rb +32 -5
- data/lib/rubocop/cop/exclude_limit.rb +1 -1
- data/lib/rubocop/cop/force.rb +12 -0
- data/lib/rubocop/cop/gemspec/add_runtime_dependency.rb +38 -0
- data/lib/rubocop/cop/gemspec/dependency_version.rb +3 -5
- data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +2 -2
- data/lib/rubocop/cop/gemspec/required_ruby_version.rb +5 -1
- data/lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb +3 -3
- data/lib/rubocop/cop/internal_affairs/cop_description.rb +0 -4
- data/lib/rubocop/cop/internal_affairs/empty_line_between_expect_offense_and_correction.rb +2 -1
- data/lib/rubocop/cop/internal_affairs/example_description.rb +6 -5
- data/lib/rubocop/cop/internal_affairs/method_name_end_with.rb +8 -6
- data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +123 -29
- data/lib/rubocop/cop/internal_affairs/redundant_expect_offense_arguments.rb +34 -0
- data/lib/rubocop/cop/internal_affairs/redundant_message_argument.rb +6 -21
- data/lib/rubocop/cop/internal_affairs/redundant_source_range.rb +8 -1
- data/lib/rubocop/cop/internal_affairs/undefined_config.rb +11 -1
- data/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +0 -5
- data/lib/rubocop/cop/internal_affairs.rb +17 -0
- data/lib/rubocop/cop/layout/access_modifier_indentation.rb +5 -1
- data/lib/rubocop/cop/layout/assignment_indentation.rb +3 -2
- data/lib/rubocop/cop/layout/block_alignment.rb +30 -12
- data/lib/rubocop/cop/layout/case_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/comment_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/condition_position.rb +0 -4
- data/lib/rubocop/cop/layout/def_end_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/empty_comment.rb +3 -1
- data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +1 -1
- data/lib/rubocop/cop/layout/empty_line_after_magic_comment.rb +14 -7
- data/lib/rubocop/cop/layout/empty_line_after_multiline_condition.rb +1 -1
- data/lib/rubocop/cop/layout/empty_line_between_defs.rb +2 -1
- data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +8 -3
- data/lib/rubocop/cop/layout/end_alignment.rb +8 -2
- data/lib/rubocop/cop/layout/first_argument_indentation.rb +2 -2
- data/lib/rubocop/cop/layout/first_array_element_indentation.rb +18 -4
- data/lib/rubocop/cop/layout/first_method_argument_line_break.rb +8 -0
- data/lib/rubocop/cop/layout/heredoc_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/indentation_width.rb +5 -6
- data/lib/rubocop/cop/layout/leading_comment_space.rb +56 -1
- data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +1 -1
- data/lib/rubocop/cop/layout/line_length.rb +20 -20
- data/lib/rubocop/cop/layout/redundant_line_break.rb +14 -2
- data/lib/rubocop/cop/layout/space_around_operators.rb +3 -0
- data/lib/rubocop/cop/layout/space_before_block_braces.rb +19 -10
- data/lib/rubocop/cop/layout/space_before_brackets.rb +5 -5
- data/lib/rubocop/cop/layout/space_inside_block_braces.rb +4 -0
- data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +1 -1
- data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +3 -4
- data/lib/rubocop/cop/legacy/corrector.rb +12 -2
- data/lib/rubocop/cop/lint/ambiguous_block_association.rb +0 -2
- data/lib/rubocop/cop/lint/ambiguous_operator.rb +0 -2
- data/lib/rubocop/cop/lint/ambiguous_range.rb +4 -1
- data/lib/rubocop/cop/lint/ambiguous_regexp_literal.rb +0 -2
- data/lib/rubocop/cop/lint/assignment_in_condition.rb +2 -2
- data/lib/rubocop/cop/lint/big_decimal_new.rb +4 -7
- data/lib/rubocop/cop/lint/boolean_symbol.rb +1 -3
- data/lib/rubocop/cop/lint/circular_argument_reference.rb +0 -13
- data/lib/rubocop/cop/lint/debugger.rb +27 -6
- data/lib/rubocop/cop/lint/deprecated_class_methods.rb +1 -1
- data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +0 -10
- data/lib/rubocop/cop/lint/duplicate_branch.rb +39 -4
- data/lib/rubocop/cop/lint/duplicate_case_condition.rb +1 -5
- data/lib/rubocop/cop/lint/duplicate_hash_key.rb +0 -4
- data/lib/rubocop/cop/lint/duplicate_methods.rb +0 -10
- data/lib/rubocop/cop/lint/duplicate_set_element.rb +74 -0
- data/lib/rubocop/cop/lint/each_with_object_argument.rb +0 -4
- data/lib/rubocop/cop/lint/else_layout.rb +0 -2
- data/lib/rubocop/cop/lint/empty_conditional_body.rb +29 -8
- data/lib/rubocop/cop/lint/empty_ensure.rb +1 -11
- data/lib/rubocop/cop/lint/empty_interpolation.rb +0 -4
- data/lib/rubocop/cop/lint/empty_when.rb +1 -3
- data/lib/rubocop/cop/lint/ensure_return.rb +1 -9
- data/lib/rubocop/cop/lint/erb_new_arguments.rb +21 -14
- data/lib/rubocop/cop/lint/float_comparison.rb +1 -1
- data/lib/rubocop/cop/lint/float_out_of_range.rb +0 -4
- data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +0 -10
- data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +23 -12
- data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +0 -7
- data/lib/rubocop/cop/lint/interpolation_check.rb +0 -4
- data/lib/rubocop/cop/lint/it_without_arguments_in_block.rb +5 -14
- data/lib/rubocop/cop/lint/literal_as_condition.rb +1 -1
- data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +13 -6
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +25 -6
- data/lib/rubocop/cop/lint/loop.rb +6 -12
- data/lib/rubocop/cop/lint/mixed_case_range.rb +9 -4
- data/lib/rubocop/cop/lint/nested_method_definition.rb +1 -7
- data/lib/rubocop/cop/lint/next_without_accumulator.rb +0 -4
- data/lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +0 -5
- data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +7 -0
- data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +1 -1
- data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +5 -6
- data/lib/rubocop/cop/lint/percent_string_array.rb +0 -4
- data/lib/rubocop/cop/lint/percent_symbol_array.rb +0 -4
- data/lib/rubocop/cop/lint/rand_one.rb +0 -4
- data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +3 -1
- data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +14 -9
- data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +1 -1
- data/lib/rubocop/cop/lint/redundant_string_coercion.rb +0 -4
- data/lib/rubocop/cop/lint/redundant_with_index.rb +4 -0
- data/lib/rubocop/cop/lint/require_parentheses.rb +0 -4
- data/lib/rubocop/cop/lint/rescue_exception.rb +0 -4
- data/lib/rubocop/cop/lint/rescue_type.rb +1 -3
- data/lib/rubocop/cop/lint/return_in_void_context.rb +0 -2
- data/lib/rubocop/cop/lint/safe_navigation_chain.rb +9 -4
- data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +107 -41
- data/lib/rubocop/cop/lint/script_permission.rb +3 -3
- data/lib/rubocop/cop/lint/shadowed_argument.rb +1 -0
- data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +6 -10
- data/lib/rubocop/cop/lint/symbol_conversion.rb +1 -1
- data/lib/rubocop/cop/lint/syntax.rb +6 -3
- data/lib/rubocop/cop/lint/to_enum_arguments.rb +1 -3
- data/lib/rubocop/cop/lint/unescaped_bracket_in_regexp.rb +88 -0
- data/lib/rubocop/cop/lint/unified_integer.rb +0 -4
- data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +1 -0
- data/lib/rubocop/cop/lint/unreachable_code.rb +4 -7
- data/lib/rubocop/cop/lint/unreachable_loop.rb +8 -2
- data/lib/rubocop/cop/lint/uri_regexp.rb +25 -7
- data/lib/rubocop/cop/lint/useless_assignment.rb +19 -16
- data/lib/rubocop/cop/lint/useless_else_without_rescue.rb +0 -4
- data/lib/rubocop/cop/lint/useless_numeric_operation.rb +77 -0
- data/lib/rubocop/cop/lint/useless_setter_call.rb +0 -4
- data/lib/rubocop/cop/lint/useless_times.rb +1 -1
- data/lib/rubocop/cop/lint/void.rb +41 -9
- data/lib/rubocop/cop/metrics/block_length.rb +6 -5
- data/lib/rubocop/cop/metrics/block_nesting.rb +19 -7
- data/lib/rubocop/cop/metrics/class_length.rb +6 -5
- data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +4 -1
- data/lib/rubocop/cop/metrics/method_length.rb +6 -5
- data/lib/rubocop/cop/metrics/module_length.rb +6 -5
- data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +5 -5
- data/lib/rubocop/cop/mixin/alignment.rb +5 -1
- data/lib/rubocop/cop/mixin/allowed_methods.rb +7 -1
- data/lib/rubocop/cop/mixin/allowed_pattern.rb +15 -3
- data/lib/rubocop/cop/mixin/annotation_comment.rb +0 -2
- data/lib/rubocop/cop/mixin/check_line_breakable.rb +10 -0
- data/lib/rubocop/cop/mixin/code_length.rb +12 -1
- data/lib/rubocop/cop/mixin/configurable_formatting.rb +1 -0
- data/lib/rubocop/cop/mixin/configurable_max.rb +5 -1
- data/lib/rubocop/cop/mixin/endless_method_rewriter.rb +24 -0
- data/lib/rubocop/cop/mixin/frozen_string_literal.rb +22 -10
- data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +9 -2
- data/lib/rubocop/cop/mixin/line_length_help.rb +7 -2
- data/lib/rubocop/cop/mixin/method_complexity.rb +15 -6
- data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +1 -1
- data/lib/rubocop/cop/mixin/percent_array.rb +1 -1
- data/lib/rubocop/cop/mixin/rescue_node.rb +4 -0
- data/lib/rubocop/cop/mixin/safe_assignment.rb +1 -1
- data/lib/rubocop/cop/mixin/statement_modifier.rb +3 -2
- data/lib/rubocop/cop/mixin/string_literals_help.rb +12 -0
- data/lib/rubocop/cop/naming/accessor_method_name.rb +5 -0
- data/lib/rubocop/cop/naming/block_forwarding.rb +33 -6
- data/lib/rubocop/cop/naming/file_name.rb +2 -2
- data/lib/rubocop/cop/naming/inclusive_language.rb +13 -5
- data/lib/rubocop/cop/naming/predicate_name.rb +55 -29
- data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +10 -1
- data/lib/rubocop/cop/offense.rb +4 -5
- data/lib/rubocop/cop/registry.rb +1 -1
- data/lib/rubocop/cop/security/compound_hash.rb +2 -2
- data/lib/rubocop/cop/security/open.rb +2 -2
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +62 -2
- data/lib/rubocop/cop/style/accessor_grouping.rb +10 -2
- data/lib/rubocop/cop/style/alias.rb +2 -1
- data/lib/rubocop/cop/style/ambiguous_endless_method_definition.rb +79 -0
- data/lib/rubocop/cop/style/arguments_forwarding.rb +141 -24
- data/lib/rubocop/cop/style/bitwise_predicate.rb +100 -0
- data/lib/rubocop/cop/style/block_delimiters.rb +31 -3
- data/lib/rubocop/cop/style/case_like_if.rb +1 -1
- data/lib/rubocop/cop/style/class_vars.rb +3 -3
- data/lib/rubocop/cop/style/collection_compact.rb +19 -10
- data/lib/rubocop/cop/style/combinable_defined.rb +115 -0
- data/lib/rubocop/cop/style/combinable_loops.rb +7 -0
- data/lib/rubocop/cop/style/commented_keyword.rb +12 -3
- data/lib/rubocop/cop/style/conditional_assignment.rb +7 -8
- data/lib/rubocop/cop/style/copyright.rb +31 -21
- data/lib/rubocop/cop/style/data_inheritance.rb +1 -1
- data/lib/rubocop/cop/style/def_with_parentheses.rb +0 -2
- data/lib/rubocop/cop/style/documentation.rb +24 -24
- data/lib/rubocop/cop/style/documentation_method.rb +20 -0
- data/lib/rubocop/cop/style/each_for_simple_loop.rb +7 -8
- data/lib/rubocop/cop/style/empty_else.rb +6 -5
- data/lib/rubocop/cop/style/empty_heredoc.rb +1 -14
- data/lib/rubocop/cop/style/empty_literal.rb +31 -22
- data/lib/rubocop/cop/style/endless_method.rb +1 -14
- data/lib/rubocop/cop/style/eval_with_location.rb +16 -24
- data/lib/rubocop/cop/style/exact_regexp_match.rb +2 -1
- data/lib/rubocop/cop/style/file_read.rb +2 -5
- data/lib/rubocop/cop/style/file_write.rb +2 -5
- data/lib/rubocop/cop/style/for.rb +2 -0
- data/lib/rubocop/cop/style/format_string.rb +9 -9
- data/lib/rubocop/cop/style/format_string_token.rb +2 -2
- data/lib/rubocop/cop/style/global_std_stream.rb +7 -1
- data/lib/rubocop/cop/style/guard_clause.rb +17 -2
- data/lib/rubocop/cop/style/hash_each_methods.rb +35 -8
- data/lib/rubocop/cop/style/hash_except.rb +8 -5
- data/lib/rubocop/cop/style/hash_syntax.rb +26 -4
- data/lib/rubocop/cop/style/identical_conditional_branches.rb +5 -2
- data/lib/rubocop/cop/style/if_inside_else.rb +1 -1
- data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +5 -4
- data/lib/rubocop/cop/style/if_with_semicolon.rb +49 -6
- data/lib/rubocop/cop/style/in_pattern_then.rb +6 -2
- data/lib/rubocop/cop/style/inverse_methods.rb +8 -8
- data/lib/rubocop/cop/style/invertible_unless_condition.rb +46 -4
- data/lib/rubocop/cop/style/keyword_arguments_merging.rb +67 -0
- data/lib/rubocop/cop/style/lambda.rb +1 -1
- data/lib/rubocop/cop/style/magic_comment_format.rb +1 -1
- data/lib/rubocop/cop/style/map_compact_with_conditional_block.rb +81 -50
- data/lib/rubocop/cop/style/map_into_array.rb +233 -0
- data/lib/rubocop/cop/style/map_to_hash.rb +10 -6
- data/lib/rubocop/cop/style/map_to_set.rb +1 -1
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +29 -11
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +2 -4
- data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +2 -2
- data/lib/rubocop/cop/style/missing_else.rb +0 -4
- data/lib/rubocop/cop/style/multiline_memoization.rb +1 -1
- data/lib/rubocop/cop/style/multiline_method_signature.rb +10 -1
- data/lib/rubocop/cop/style/multiline_ternary_operator.rb +5 -3
- data/lib/rubocop/cop/style/multiline_when_then.rb +0 -4
- data/lib/rubocop/cop/style/multiple_comparison.rb +28 -47
- data/lib/rubocop/cop/style/nested_modifier.rb +1 -1
- data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +1 -1
- data/lib/rubocop/cop/style/nil_comparison.rb +2 -0
- data/lib/rubocop/cop/style/numeric_literal_prefix.rb +1 -1
- data/lib/rubocop/cop/style/numeric_predicate.rb +12 -4
- data/lib/rubocop/cop/style/object_then.rb +5 -3
- data/lib/rubocop/cop/style/one_line_conditional.rb +6 -2
- data/lib/rubocop/cop/style/operator_method_call.rb +25 -6
- data/lib/rubocop/cop/style/parallel_assignment.rb +8 -9
- data/lib/rubocop/cop/style/parentheses_around_condition.rb +8 -0
- data/lib/rubocop/cop/style/quoted_symbols.rb +1 -3
- data/lib/rubocop/cop/style/raise_args.rb +4 -1
- data/lib/rubocop/cop/style/redundant_argument.rb +25 -2
- data/lib/rubocop/cop/style/redundant_assignment.rb +10 -2
- data/lib/rubocop/cop/style/redundant_begin.rb +5 -1
- data/lib/rubocop/cop/style/redundant_condition.rb +4 -4
- data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +5 -4
- data/lib/rubocop/cop/style/redundant_each.rb +7 -4
- data/lib/rubocop/cop/style/redundant_file_extension_in_require.rb +1 -1
- data/lib/rubocop/cop/style/redundant_filter_chain.rb +1 -1
- data/lib/rubocop/cop/style/redundant_interpolation_unfreeze.rb +46 -0
- data/lib/rubocop/cop/style/redundant_line_continuation.rb +40 -7
- data/lib/rubocop/cop/style/redundant_parentheses.rb +27 -13
- data/lib/rubocop/cop/style/redundant_percent_q.rb +1 -1
- data/lib/rubocop/cop/style/redundant_regexp_argument.rb +4 -1
- data/lib/rubocop/cop/style/redundant_regexp_escape.rb +8 -24
- data/lib/rubocop/cop/style/redundant_return.rb +6 -0
- data/lib/rubocop/cop/style/require_order.rb +2 -2
- data/lib/rubocop/cop/style/rescue_modifier.rb +13 -1
- data/lib/rubocop/cop/style/return_nil_in_predicate_method_definition.rb +54 -12
- data/lib/rubocop/cop/style/safe_navigation.rb +106 -52
- data/lib/rubocop/cop/style/safe_navigation_chain_length.rb +52 -0
- data/lib/rubocop/cop/style/sample.rb +1 -3
- data/lib/rubocop/cop/style/select_by_regexp.rb +9 -6
- data/lib/rubocop/cop/style/semicolon.rb +1 -1
- data/lib/rubocop/cop/style/send.rb +4 -4
- data/lib/rubocop/cop/style/send_with_literal_method_name.rb +104 -0
- data/lib/rubocop/cop/style/slicing_with_range.rb +76 -10
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +21 -2
- data/lib/rubocop/cop/style/special_global_vars.rb +1 -2
- data/lib/rubocop/cop/style/struct_inheritance.rb +1 -1
- data/lib/rubocop/cop/style/super_arguments.rb +174 -0
- data/lib/rubocop/cop/style/symbol_proc.rb +75 -5
- data/lib/rubocop/cop/style/ternary_parentheses.rb +26 -5
- data/lib/rubocop/cop/style/top_level_method_definition.rb +1 -1
- data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
- data/lib/rubocop/cop/style/while_until_do.rb +0 -2
- data/lib/rubocop/cop/style/while_until_modifier.rb +0 -1
- data/lib/rubocop/cop/style/zero_length_predicate.rb +32 -24
- data/lib/rubocop/cop/team.rb +27 -3
- data/lib/rubocop/cop/util.rb +8 -2
- data/lib/rubocop/cop/utils/regexp_ranges.rb +1 -1
- data/lib/rubocop/cop/variable_force/assignment.rb +18 -3
- data/lib/rubocop/cop/variable_force/branch.rb +1 -1
- data/lib/rubocop/cop/variable_force/variable.rb +5 -1
- data/lib/rubocop/cop/variable_force/variable_table.rb +2 -2
- data/lib/rubocop/cop/variable_force.rb +13 -1
- data/lib/rubocop/cops_documentation_generator.rb +96 -43
- data/lib/rubocop/core_ext/string.rb +2 -6
- data/lib/rubocop/directive_comment.rb +10 -8
- data/lib/rubocop/ext/regexp_node.rb +18 -35
- data/lib/rubocop/ext/regexp_parser.rb +4 -21
- data/lib/rubocop/file_finder.rb +9 -4
- data/lib/rubocop/formatter/clang_style_formatter.rb +3 -7
- data/lib/rubocop/formatter/disabled_config_formatter.rb +24 -9
- data/lib/rubocop/formatter/formatter_set.rb +7 -1
- data/lib/rubocop/formatter/html_formatter.rb +32 -10
- data/lib/rubocop/formatter/json_formatter.rb +0 -1
- data/lib/rubocop/formatter/junit_formatter.rb +70 -23
- data/lib/rubocop/formatter/offense_count_formatter.rb +12 -2
- data/lib/rubocop/formatter/tap_formatter.rb +3 -7
- data/lib/rubocop/formatter.rb +1 -1
- data/lib/rubocop/lockfile.rb +58 -7
- data/lib/rubocop/lsp/logger.rb +1 -1
- data/lib/rubocop/lsp/routes.rb +12 -15
- data/lib/rubocop/lsp/runtime.rb +3 -1
- data/lib/rubocop/lsp/server.rb +6 -2
- data/lib/rubocop/lsp/severity.rb +1 -1
- data/lib/rubocop/lsp.rb +36 -0
- data/lib/rubocop/magic_comment.rb +1 -1
- data/lib/rubocop/options.rb +17 -12
- data/lib/rubocop/path_util.rb +6 -2
- data/lib/rubocop/rake_task.rb +1 -1
- data/lib/rubocop/remote_config.rb +5 -1
- data/lib/rubocop/result_cache.rb +2 -8
- data/lib/rubocop/rspec/cop_helper.rb +8 -2
- data/lib/rubocop/rspec/expect_offense.rb +17 -8
- data/lib/rubocop/rspec/shared_contexts.rb +75 -18
- data/lib/rubocop/rspec/support.rb +3 -0
- data/lib/rubocop/runner.rb +31 -9
- data/lib/rubocop/server/cache.rb +16 -2
- data/lib/rubocop/server/client_command/exec.rb +2 -3
- data/lib/rubocop/server/client_command/start.rb +1 -1
- data/lib/rubocop/server/core.rb +5 -0
- data/lib/rubocop/server/server_command/exec.rb +0 -1
- data/lib/rubocop/target_finder.rb +84 -78
- data/lib/rubocop/target_ruby.rb +87 -81
- data/lib/rubocop/version.rb +45 -9
- data/lib/rubocop/yaml_duplication_checker.rb +20 -26
- data/lib/rubocop.rb +21 -1
- metadata +33 -35
- /data/lib/rubocop/formatter/{git_hub_actions_formatter.rb → github_actions_formatter.rb} +0 -0
@@ -23,6 +23,7 @@ module RuboCop
|
|
23
23
|
# # bad
|
24
24
|
# open(something)
|
25
25
|
# open("| #{something}")
|
26
|
+
# open("| foo")
|
26
27
|
# URI.open(something)
|
27
28
|
#
|
28
29
|
# # good
|
@@ -32,7 +33,6 @@ module RuboCop
|
|
32
33
|
#
|
33
34
|
# # good (literal strings)
|
34
35
|
# open("foo.text")
|
35
|
-
# open("| foo")
|
36
36
|
# URI.open("http://example.com")
|
37
37
|
class Open < Base
|
38
38
|
MSG = 'The use of `%<receiver>sopen` is a serious security risk.'
|
@@ -40,7 +40,7 @@ module RuboCop
|
|
40
40
|
|
41
41
|
# @!method open?(node)
|
42
42
|
def_node_matcher :open?, <<~PATTERN
|
43
|
-
(send ${nil? (const {nil? cbase} :URI)} :open
|
43
|
+
(send ${nil? (const {nil? cbase} :URI)} :open $_ ...)
|
44
44
|
PATTERN
|
45
45
|
|
46
46
|
def on_send(node)
|
@@ -8,6 +8,17 @@ module RuboCop
|
|
8
8
|
# EnforcedStyle config covers only method definitions.
|
9
9
|
# Applications of visibility methods to symbols can be controlled
|
10
10
|
# using AllowModifiersOnSymbols config.
|
11
|
+
# Also, the visibility of `attr*` methods can be controlled using
|
12
|
+
# AllowModifiersOnAttrs config.
|
13
|
+
#
|
14
|
+
# In Ruby 3.0, `attr*` methods now return an array of defined method names
|
15
|
+
# as symbols. So we can write the modifier and `attr*` in inline style.
|
16
|
+
# AllowModifiersOnAttrs config allows `attr*` methods to be written in
|
17
|
+
# inline style without modifying applications that have been maintained
|
18
|
+
# for a long time in group style. Furthermore, developers who are not very
|
19
|
+
# familiar with Ruby may know that the modifier applies to `def`, but they
|
20
|
+
# may not know that it also applies to `attr*` methods. It would be easier
|
21
|
+
# to understand if we could write `attr*` methods in inline style.
|
11
22
|
#
|
12
23
|
# @safety
|
13
24
|
# Autocorrection is not safe, because the visibility of dynamically
|
@@ -57,6 +68,8 @@ module RuboCop
|
|
57
68
|
# class Foo
|
58
69
|
#
|
59
70
|
# private :bar, :baz
|
71
|
+
# private *%i[qux quux]
|
72
|
+
# private *METHOD_NAMES
|
60
73
|
#
|
61
74
|
# end
|
62
75
|
#
|
@@ -65,6 +78,36 @@ module RuboCop
|
|
65
78
|
# class Foo
|
66
79
|
#
|
67
80
|
# private :bar, :baz
|
81
|
+
# private *%i[qux quux]
|
82
|
+
# private *METHOD_NAMES
|
83
|
+
#
|
84
|
+
# end
|
85
|
+
#
|
86
|
+
# @example AllowModifiersOnAttrs: true (default)
|
87
|
+
# # good
|
88
|
+
# class Foo
|
89
|
+
#
|
90
|
+
# public attr_reader :bar
|
91
|
+
# protected attr_writer :baz
|
92
|
+
# private attr_accessor :qux
|
93
|
+
# private attr :quux
|
94
|
+
#
|
95
|
+
# def public_method; end
|
96
|
+
#
|
97
|
+
# private
|
98
|
+
#
|
99
|
+
# def private_method; end
|
100
|
+
#
|
101
|
+
# end
|
102
|
+
#
|
103
|
+
# @example AllowModifiersOnAttrs: false
|
104
|
+
# # bad
|
105
|
+
# class Foo
|
106
|
+
#
|
107
|
+
# public attr_reader :bar
|
108
|
+
# protected attr_writer :baz
|
109
|
+
# private attr_accessor :qux
|
110
|
+
# private attr :quux
|
68
111
|
#
|
69
112
|
# end
|
70
113
|
class AccessModifierDeclarations < Base
|
@@ -89,13 +132,22 @@ module RuboCop
|
|
89
132
|
|
90
133
|
# @!method access_modifier_with_symbol?(node)
|
91
134
|
def_node_matcher :access_modifier_with_symbol?, <<~PATTERN
|
92
|
-
(send nil? {:private :protected :public :module_function}
|
135
|
+
(send nil? {:private :protected :public :module_function}
|
136
|
+
{(sym _) (splat {#percent_symbol_array? const})}
|
137
|
+
)
|
138
|
+
PATTERN
|
139
|
+
|
140
|
+
# @!method access_modifier_with_attr?(node)
|
141
|
+
def_node_matcher :access_modifier_with_attr?, <<~PATTERN
|
142
|
+
(send nil? {:private :protected :public :module_function}
|
143
|
+
(send nil? {:attr :attr_reader :attr_writer :attr_accessor} _))
|
93
144
|
PATTERN
|
94
145
|
|
95
146
|
def on_send(node)
|
96
147
|
return unless node.access_modifier?
|
97
148
|
return if ALLOWED_NODE_TYPES.include?(node.parent&.type)
|
98
149
|
return if allow_modifiers_on_symbols?(node)
|
150
|
+
return if allow_modifiers_on_attrs?(node)
|
99
151
|
|
100
152
|
if offense?(node)
|
101
153
|
add_offense(node.loc.selector) do |corrector|
|
@@ -124,10 +176,18 @@ module RuboCop
|
|
124
176
|
end
|
125
177
|
end
|
126
178
|
|
179
|
+
def percent_symbol_array?(node)
|
180
|
+
node.array_type? && node.percent_literal?(:symbol)
|
181
|
+
end
|
182
|
+
|
127
183
|
def allow_modifiers_on_symbols?(node)
|
128
184
|
cop_config['AllowModifiersOnSymbols'] && access_modifier_with_symbol?(node)
|
129
185
|
end
|
130
186
|
|
187
|
+
def allow_modifiers_on_attrs?(node)
|
188
|
+
cop_config['AllowModifiersOnAttrs'] && access_modifier_with_attr?(node)
|
189
|
+
end
|
190
|
+
|
131
191
|
def offense?(node)
|
132
192
|
(group_style? && access_modifier_is_inlined?(node) &&
|
133
193
|
!right_siblings_same_inline_method?(node)) ||
|
@@ -168,7 +228,7 @@ module RuboCop
|
|
168
228
|
|
169
229
|
def find_corresponding_def_node(node)
|
170
230
|
if access_modifier_with_symbol?(node)
|
171
|
-
method_name = node.first_argument.value
|
231
|
+
method_name = node.first_argument.respond_to?(:value) && node.first_argument.value
|
172
232
|
node.parent.each_child_node(:def).find do |child|
|
173
233
|
child.method?(method_name)
|
174
234
|
end
|
@@ -10,6 +10,9 @@ module RuboCop
|
|
10
10
|
# NOTE: If there is a method call before the accessor method it is always allowed
|
11
11
|
# as it might be intended like Sorbet.
|
12
12
|
#
|
13
|
+
# NOTE: If there is a RBS::Inline annotation comment just after the accessor method
|
14
|
+
# it is always allowed.
|
15
|
+
#
|
13
16
|
# @example EnforcedStyle: grouped (default)
|
14
17
|
# # bad
|
15
18
|
# class Foo
|
@@ -92,7 +95,7 @@ module RuboCop
|
|
92
95
|
comment_line?(processed_source[node.first_line - 2])
|
93
96
|
end
|
94
97
|
|
95
|
-
# rubocop:disable Metrics/CyclomaticComplexity
|
98
|
+
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
96
99
|
def groupable_accessor?(node)
|
97
100
|
return true unless (previous_expression = node.left_siblings.last)
|
98
101
|
|
@@ -105,11 +108,16 @@ module RuboCop
|
|
105
108
|
|
106
109
|
return true unless previous_expression.send_type?
|
107
110
|
|
111
|
+
# Accessors with RBS::Inline annotations shouldn't be groupable.
|
112
|
+
return false if processed_source.comments.any? do |c|
|
113
|
+
same_line?(c, previous_expression) && c.text.start_with?('#:')
|
114
|
+
end
|
115
|
+
|
108
116
|
previous_expression.attribute_accessor? ||
|
109
117
|
previous_expression.access_modifier? ||
|
110
118
|
node.first_line - previous_expression.last_line > 1 # there is a space between nodes
|
111
119
|
end
|
112
|
-
# rubocop:enable Metrics/CyclomaticComplexity
|
120
|
+
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
113
121
|
|
114
122
|
def class_send_elements(class_node)
|
115
123
|
class_def = class_node.body
|
@@ -41,6 +41,7 @@ module RuboCop
|
|
41
41
|
def on_send(node)
|
42
42
|
return unless node.command?(:alias_method)
|
43
43
|
return unless style == :prefer_alias && alias_keyword_possible?(node)
|
44
|
+
return unless node.arguments.count == 2
|
44
45
|
|
45
46
|
msg = format(MSG_ALIAS_METHOD, current: lexical_scope_type(node))
|
46
47
|
add_offense(node.loc.selector, message: msg) do |corrector|
|
@@ -79,7 +80,7 @@ module RuboCop
|
|
79
80
|
def alias_method_possible?(node)
|
80
81
|
scope_type(node) != :instance_eval &&
|
81
82
|
node.children.none?(&:gvar_type?) &&
|
82
|
-
node
|
83
|
+
node.each_ancestor(:def).none?
|
83
84
|
end
|
84
85
|
|
85
86
|
def add_offense_for_args(node, &block)
|
@@ -0,0 +1,79 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Style
|
6
|
+
# Looks for endless methods inside operations of lower precedence (`and`, `or`, and
|
7
|
+
# modifier forms of `if`, `unless`, `while`, `until`) that are ambiguous due to
|
8
|
+
# lack of parentheses. This may lead to unexpected behavior as the code may appear
|
9
|
+
# to use these keywords as part of the method but in fact they modify
|
10
|
+
# the method definition itself.
|
11
|
+
#
|
12
|
+
# In these cases, using a normal method definition is more clear.
|
13
|
+
#
|
14
|
+
# @example
|
15
|
+
#
|
16
|
+
# # bad
|
17
|
+
# def foo = true if bar
|
18
|
+
#
|
19
|
+
# # good - using a non-endless method is more explicit
|
20
|
+
# def foo
|
21
|
+
# true
|
22
|
+
# end if bar
|
23
|
+
#
|
24
|
+
# # ok - method body is explicit
|
25
|
+
# def foo = (true if bar)
|
26
|
+
#
|
27
|
+
# # ok - method definition is explicit
|
28
|
+
# (def foo = true) if bar
|
29
|
+
class AmbiguousEndlessMethodDefinition < Base
|
30
|
+
extend TargetRubyVersion
|
31
|
+
extend AutoCorrector
|
32
|
+
include EndlessMethodRewriter
|
33
|
+
include RangeHelp
|
34
|
+
|
35
|
+
minimum_target_ruby_version 3.0
|
36
|
+
|
37
|
+
MSG = 'Avoid using `%<keyword>s` statements with endless methods.'
|
38
|
+
|
39
|
+
# @!method ambiguous_endless_method_body(node)
|
40
|
+
def_node_matcher :ambiguous_endless_method_body, <<~PATTERN
|
41
|
+
^${
|
42
|
+
(if _ <def _>)
|
43
|
+
({and or} def _)
|
44
|
+
({while until} _ def)
|
45
|
+
}
|
46
|
+
PATTERN
|
47
|
+
|
48
|
+
def on_def(node)
|
49
|
+
return unless node.endless?
|
50
|
+
|
51
|
+
operation = ambiguous_endless_method_body(node)
|
52
|
+
return unless operation
|
53
|
+
|
54
|
+
return unless modifier_form?(operation)
|
55
|
+
|
56
|
+
add_offense(operation, message: format(MSG, keyword: keyword(operation))) do |corrector|
|
57
|
+
correct_to_multiline(corrector, node)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
def modifier_form?(operation)
|
64
|
+
return true if operation.and_type? || operation.or_type?
|
65
|
+
|
66
|
+
operation.modifier_form?
|
67
|
+
end
|
68
|
+
|
69
|
+
def keyword(operation)
|
70
|
+
if operation.respond_to?(:keyword)
|
71
|
+
operation.keyword
|
72
|
+
else
|
73
|
+
operation.operator
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -8,6 +8,12 @@ module RuboCop
|
|
8
8
|
# This cop identifies places where `do_something(*args, &block)`
|
9
9
|
# can be replaced by `do_something(...)`.
|
10
10
|
#
|
11
|
+
# In Ruby 3.1, anonymous block forwarding has been added.
|
12
|
+
#
|
13
|
+
# This cop identifies places where `do_something(&block)` can be replaced
|
14
|
+
# by `do_something(&)`; if desired, this functionality can be disabled
|
15
|
+
# by setting `UseAnonymousForwarding: false`.
|
16
|
+
#
|
11
17
|
# In Ruby 3.2, anonymous args/kwargs forwarding has been added.
|
12
18
|
#
|
13
19
|
# This cop also identifies places where `use_args(*args)`/`use_kwargs(**kwargs)` can be
|
@@ -23,6 +29,8 @@ module RuboCop
|
|
23
29
|
#
|
24
30
|
# Names not on this list are likely to be meaningful and are allowed by default.
|
25
31
|
#
|
32
|
+
# This cop handles not only method forwarding but also forwarding to `super`.
|
33
|
+
#
|
26
34
|
# @example
|
27
35
|
# # bad
|
28
36
|
# def foo(*args, &block)
|
@@ -41,22 +49,25 @@ module RuboCop
|
|
41
49
|
#
|
42
50
|
# @example UseAnonymousForwarding: true (default, only relevant for Ruby >= 3.2)
|
43
51
|
# # bad
|
44
|
-
# def foo(*args, **kwargs)
|
52
|
+
# def foo(*args, **kwargs, &block)
|
45
53
|
# args_only(*args)
|
46
54
|
# kwargs_only(**kwargs)
|
55
|
+
# block_only(&block)
|
47
56
|
# end
|
48
57
|
#
|
49
58
|
# # good
|
50
|
-
# def foo(*,
|
59
|
+
# def foo(*, **, &)
|
51
60
|
# args_only(*)
|
52
61
|
# kwargs_only(**)
|
62
|
+
# block_only(&)
|
53
63
|
# end
|
54
64
|
#
|
55
65
|
# @example UseAnonymousForwarding: false (only relevant for Ruby >= 3.2)
|
56
66
|
# # good
|
57
|
-
# def foo(*args, **kwargs)
|
67
|
+
# def foo(*args, **kwargs, &block)
|
58
68
|
# args_only(*args)
|
59
69
|
# kwargs_only(**kwargs)
|
70
|
+
# block_only(&block)
|
60
71
|
# end
|
61
72
|
#
|
62
73
|
# @example AllowOnlyRestArgument: true (default, only relevant for Ruby < 3.2)
|
@@ -104,7 +115,7 @@ module RuboCop
|
|
104
115
|
# end
|
105
116
|
#
|
106
117
|
# @example RedundantBlockArgumentNames: ['blk', 'block', 'proc'] (default)
|
107
|
-
# # bad
|
118
|
+
# # bad - But it is good with `EnforcedStyle: explicit` set for `Naming/BlockForwarding`.
|
108
119
|
# def foo(&block)
|
109
120
|
# bar(&block)
|
110
121
|
# end
|
@@ -126,6 +137,7 @@ module RuboCop
|
|
126
137
|
FORWARDING_MSG = 'Use shorthand syntax `...` for arguments forwarding.'
|
127
138
|
ARGS_MSG = 'Use anonymous positional arguments forwarding (`*`).'
|
128
139
|
KWARGS_MSG = 'Use anonymous keyword arguments forwarding (`**`).'
|
140
|
+
BLOCK_MSG = 'Use anonymous block arguments forwarding (`&`).'
|
129
141
|
|
130
142
|
def self.autocorrect_incompatible_with
|
131
143
|
[Naming::BlockForwarding]
|
@@ -136,7 +148,7 @@ module RuboCop
|
|
136
148
|
|
137
149
|
restarg, kwrestarg, blockarg = extract_forwardable_args(node.arguments)
|
138
150
|
forwardable_args = redundant_forwardable_named_args(restarg, kwrestarg, blockarg)
|
139
|
-
send_nodes = node.each_descendant(:send).to_a
|
151
|
+
send_nodes = node.each_descendant(:send, :csend, :super, :yield).to_a
|
140
152
|
|
141
153
|
send_classifications = classify_send_nodes(
|
142
154
|
node, send_nodes, non_splat_or_block_pass_lvar_references(node.body), forwardable_args
|
@@ -168,35 +180,64 @@ module RuboCop
|
|
168
180
|
end
|
169
181
|
|
170
182
|
def only_forwards_all?(send_classifications)
|
171
|
-
|
183
|
+
all_classifications = %i[all all_anonymous].freeze
|
184
|
+
send_classifications.all? { |_, c, _, _| all_classifications.include?(c) }
|
172
185
|
end
|
173
186
|
|
187
|
+
# rubocop:disable Metrics/MethodLength
|
174
188
|
def add_forward_all_offenses(node, send_classifications, forwardable_args)
|
175
|
-
|
176
|
-
|
189
|
+
_rest_arg, _kwrest_arg, block_arg = *forwardable_args
|
190
|
+
registered_block_arg_offense = false
|
191
|
+
|
192
|
+
send_classifications.each do |send_node, c, forward_rest, forward_kwrest, forward_block_arg| # rubocop:disable Layout/LineLength
|
193
|
+
if !forward_rest && !forward_kwrest && c != :all_anonymous
|
194
|
+
# Prevents `anonymous block parameter is also used within block (SyntaxError)` occurs
|
195
|
+
# in Ruby 3.3.0.
|
196
|
+
if outside_block?(forward_block_arg)
|
197
|
+
register_forward_block_arg_offense(!forward_rest, node.arguments, block_arg)
|
198
|
+
register_forward_block_arg_offense(!forward_rest, send_node, forward_block_arg)
|
199
|
+
end
|
200
|
+
registered_block_arg_offense = true
|
201
|
+
break
|
202
|
+
else
|
203
|
+
register_forward_all_offense(send_node, send_node, forward_rest)
|
204
|
+
end
|
177
205
|
end
|
178
206
|
|
207
|
+
return if registered_block_arg_offense
|
208
|
+
|
179
209
|
rest_arg, _kwrest_arg, _block_arg = *forwardable_args
|
180
210
|
register_forward_all_offense(node, node.arguments, rest_arg)
|
181
211
|
end
|
212
|
+
# rubocop:enable Metrics/MethodLength
|
182
213
|
|
214
|
+
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
183
215
|
def add_post_ruby_32_offenses(def_node, send_classifications, forwardable_args)
|
184
216
|
return unless use_anonymous_forwarding?
|
217
|
+
return if send_inside_block?(send_classifications)
|
185
218
|
|
186
|
-
rest_arg, kwrest_arg,
|
219
|
+
rest_arg, kwrest_arg, block_arg = *forwardable_args
|
187
220
|
|
188
|
-
send_classifications.each do |send_node, _c, forward_rest, forward_kwrest|
|
189
|
-
if forward_rest
|
221
|
+
send_classifications.each do |send_node, _c, forward_rest, forward_kwrest, forward_block_arg| # rubocop:disable Layout/LineLength
|
222
|
+
if outside_block?(forward_rest)
|
190
223
|
register_forward_args_offense(def_node.arguments, rest_arg)
|
191
224
|
register_forward_args_offense(send_node, forward_rest)
|
192
225
|
end
|
193
226
|
|
194
|
-
if forward_kwrest
|
227
|
+
if outside_block?(forward_kwrest)
|
195
228
|
register_forward_kwargs_offense(!forward_rest, def_node.arguments, kwrest_arg)
|
196
229
|
register_forward_kwargs_offense(!forward_rest, send_node, forward_kwrest)
|
197
230
|
end
|
231
|
+
|
232
|
+
# Prevents `anonymous block parameter is also used within block (SyntaxError)` occurs
|
233
|
+
# in Ruby 3.3.0.
|
234
|
+
if outside_block?(forward_block_arg)
|
235
|
+
register_forward_block_arg_offense(!forward_rest, def_node.arguments, block_arg)
|
236
|
+
register_forward_block_arg_offense(!forward_rest, send_node, forward_block_arg)
|
237
|
+
end
|
198
238
|
end
|
199
239
|
end
|
240
|
+
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength
|
200
241
|
|
201
242
|
def non_splat_or_block_pass_lvar_references(body)
|
202
243
|
body.each_descendant(:lvar, :lvasgn).filter_map do |lvar|
|
@@ -225,10 +266,7 @@ module RuboCop
|
|
225
266
|
|
226
267
|
def classification_and_forwards(def_node, send_node, referenced_lvars, forwardable_args)
|
227
268
|
classifier = SendNodeClassifier.new(
|
228
|
-
def_node,
|
229
|
-
send_node,
|
230
|
-
referenced_lvars,
|
231
|
-
forwardable_args,
|
269
|
+
def_node, send_node, referenced_lvars, forwardable_args,
|
232
270
|
target_ruby_version: target_ruby_version,
|
233
271
|
allow_only_rest_arguments: allow_only_rest_arguments?
|
234
272
|
)
|
@@ -237,7 +275,12 @@ module RuboCop
|
|
237
275
|
|
238
276
|
return unless classification
|
239
277
|
|
240
|
-
[
|
278
|
+
[
|
279
|
+
classification,
|
280
|
+
classifier.forwarded_rest_arg,
|
281
|
+
classifier.forwarded_kwrest_arg,
|
282
|
+
classifier.forwarded_block_arg
|
283
|
+
]
|
241
284
|
end
|
242
285
|
|
243
286
|
def redundant_named_arg(arg, config_name, keyword)
|
@@ -250,6 +293,12 @@ module RuboCop
|
|
250
293
|
redundant_arg_names.include?(arg.source) ? arg : nil
|
251
294
|
end
|
252
295
|
|
296
|
+
def outside_block?(node)
|
297
|
+
return false unless node
|
298
|
+
|
299
|
+
node.each_ancestor(:block, :numblock).none?
|
300
|
+
end
|
301
|
+
|
253
302
|
def register_forward_args_offense(def_arguments_or_send, rest_arg_or_splat)
|
254
303
|
add_offense(rest_arg_or_splat, message: ARGS_MSG) do |corrector|
|
255
304
|
add_parens_if_missing(def_arguments_or_send, corrector)
|
@@ -266,6 +315,17 @@ module RuboCop
|
|
266
315
|
end
|
267
316
|
end
|
268
317
|
|
318
|
+
def register_forward_block_arg_offense(add_parens, def_arguments_or_send, block_arg)
|
319
|
+
return if target_ruby_version <= 3.0 ||
|
320
|
+
block_arg.nil? || block_arg.source == '&' || explicit_block_name?
|
321
|
+
|
322
|
+
add_offense(block_arg, message: BLOCK_MSG) do |corrector|
|
323
|
+
add_parens_if_missing(def_arguments_or_send, corrector) if add_parens
|
324
|
+
|
325
|
+
corrector.replace(block_arg, '&')
|
326
|
+
end
|
327
|
+
end
|
328
|
+
|
269
329
|
def register_forward_all_offense(def_or_send, send_or_arguments, rest_or_splat)
|
270
330
|
arg_range = arguments_range(def_or_send, rest_or_splat)
|
271
331
|
|
@@ -276,13 +336,18 @@ module RuboCop
|
|
276
336
|
end
|
277
337
|
end
|
278
338
|
|
339
|
+
# rubocop:disable Metrics/AbcSize
|
279
340
|
def arguments_range(node, first_node)
|
280
|
-
arguments = node.arguments.reject
|
341
|
+
arguments = node.arguments.reject do |arg|
|
342
|
+
next true if ADDITIONAL_ARG_TYPES.include?(arg.type) || arg.variable? || arg.call_type?
|
281
343
|
|
282
|
-
|
344
|
+
arg.literal? && arg.each_descendant(:kwsplat).none?
|
345
|
+
end
|
283
346
|
|
284
|
-
|
347
|
+
start_node = first_node || arguments.first
|
348
|
+
start_node.source_range.begin.join(arguments.last.source_range.end)
|
285
349
|
end
|
350
|
+
# rubocop:enable Metrics/AbcSize
|
286
351
|
|
287
352
|
def allow_only_rest_arguments?
|
288
353
|
cop_config.fetch('AllowOnlyRestArgument', true)
|
@@ -292,8 +357,15 @@ module RuboCop
|
|
292
357
|
cop_config.fetch('UseAnonymousForwarding', false)
|
293
358
|
end
|
294
359
|
|
360
|
+
def send_inside_block?(send_classifications)
|
361
|
+
send_classifications.any? do |send_node, *|
|
362
|
+
send_node.each_ancestor(:block, :numblock).any?
|
363
|
+
end
|
364
|
+
end
|
365
|
+
|
295
366
|
def add_parens_if_missing(node, corrector)
|
296
367
|
return if parentheses?(node)
|
368
|
+
return if node.send_type? && node.method?(:[])
|
297
369
|
|
298
370
|
add_parentheses(node, corrector)
|
299
371
|
end
|
@@ -311,6 +383,23 @@ module RuboCop
|
|
311
383
|
# @!method forwarded_block_arg?(node, block_name)
|
312
384
|
def_node_matcher :forwarded_block_arg?, '(block_pass {(lvar %1) nil?})'
|
313
385
|
|
386
|
+
# @!method def_all_anonymous_args?(node)
|
387
|
+
def_node_matcher :def_all_anonymous_args?, <<~PATTERN
|
388
|
+
(
|
389
|
+
def _
|
390
|
+
(args ... (restarg) (kwrestarg) (blockarg nil?))
|
391
|
+
_
|
392
|
+
)
|
393
|
+
PATTERN
|
394
|
+
|
395
|
+
# @!method send_all_anonymous_args?(node)
|
396
|
+
def_node_matcher :send_all_anonymous_args?, <<~PATTERN
|
397
|
+
(
|
398
|
+
send _ _
|
399
|
+
... (forwarded_restarg) (hash (forwarded_kwrestarg)) (block_pass nil?)
|
400
|
+
)
|
401
|
+
PATTERN
|
402
|
+
|
314
403
|
def initialize(def_node, send_node, referenced_lvars, forwardable_args, **config)
|
315
404
|
@def_node = def_node
|
316
405
|
@send_node = send_node
|
@@ -340,9 +429,11 @@ module RuboCop
|
|
340
429
|
end
|
341
430
|
|
342
431
|
def classification
|
343
|
-
return nil unless forwarded_rest_arg || forwarded_kwrest_arg
|
432
|
+
return nil unless forwarded_rest_arg || forwarded_kwrest_arg || forwarded_block_arg
|
344
433
|
|
345
|
-
if
|
434
|
+
if ruby_32_only_anonymous_forwarding?
|
435
|
+
:all_anonymous
|
436
|
+
elsif can_forward_all?
|
346
437
|
:all
|
347
438
|
else
|
348
439
|
:rest_or_kwrest
|
@@ -351,16 +442,28 @@ module RuboCop
|
|
351
442
|
|
352
443
|
private
|
353
444
|
|
445
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
354
446
|
def can_forward_all?
|
355
447
|
return false if any_arg_referenced?
|
356
|
-
return false if
|
448
|
+
return false if ruby_30_or_lower_optarg?
|
449
|
+
return false if ruby_32_or_higher_missing_rest_or_kwest?
|
357
450
|
return false unless offensive_block_forwarding?
|
358
451
|
return false if additional_kwargs_or_forwarded_kwargs?
|
359
452
|
|
360
453
|
no_additional_args? || (target_ruby_version >= 3.0 && no_post_splat_args?)
|
361
454
|
end
|
455
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
362
456
|
|
363
|
-
def
|
457
|
+
# def foo(a = 41, ...) is a syntax error in 3.0.
|
458
|
+
def ruby_30_or_lower_optarg?
|
459
|
+
target_ruby_version <= 3.0 && @def_node.arguments.any?(&:optarg_type?)
|
460
|
+
end
|
461
|
+
|
462
|
+
def ruby_32_only_anonymous_forwarding?
|
463
|
+
def_all_anonymous_args?(@def_node) && send_all_anonymous_args?(@send_node)
|
464
|
+
end
|
465
|
+
|
466
|
+
def ruby_32_or_higher_missing_rest_or_kwest?
|
364
467
|
target_ruby_version >= 3.2 && !forwarded_rest_and_kwrest_args
|
365
468
|
end
|
366
469
|
|
@@ -424,9 +527,23 @@ module RuboCop
|
|
424
527
|
def no_additional_args?
|
425
528
|
forwardable_count = [@rest_arg, @kwrest_arg, @block_arg].compact.size
|
426
529
|
|
530
|
+
return false if missing_rest_arg_or_kwrest_arg?
|
531
|
+
|
427
532
|
@def_node.arguments.size == forwardable_count &&
|
428
533
|
@send_node.arguments.size == forwardable_count
|
429
534
|
end
|
535
|
+
|
536
|
+
def missing_rest_arg_or_kwrest_arg?
|
537
|
+
(@rest_arg_name && !forwarded_rest_arg) ||
|
538
|
+
(@kwrest_arg_name && !forwarded_kwrest_arg)
|
539
|
+
end
|
540
|
+
end
|
541
|
+
|
542
|
+
def explicit_block_name?
|
543
|
+
block_forwarding_config = config.for_cop('Naming/BlockForwarding')
|
544
|
+
return false unless block_forwarding_config['Enabled']
|
545
|
+
|
546
|
+
block_forwarding_config['EnforcedStyle'] == 'explicit'
|
430
547
|
end
|
431
548
|
end
|
432
549
|
end
|