rubocop 1.50.2 → 1.62.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/LICENSE.txt +1 -1
- data/README.md +7 -5
- data/assets/output.css.erb +159 -0
- data/assets/output.html.erb +1 -160
- data/config/default.yml +196 -28
- data/config/obsoletion.yml +5 -0
- data/lib/rubocop/cli/command/auto_generate_config.rb +22 -8
- data/lib/rubocop/cli/command/lsp.rb +19 -0
- data/lib/rubocop/cli.rb +10 -2
- data/lib/rubocop/config.rb +8 -2
- data/lib/rubocop/config_finder.rb +14 -4
- data/lib/rubocop/config_loader.rb +0 -1
- data/lib/rubocop/config_loader_resolver.rb +4 -3
- data/lib/rubocop/config_obsoletion/parameter_rule.rb +9 -1
- data/lib/rubocop/config_obsoletion.rb +13 -10
- data/lib/rubocop/config_validator.rb +14 -7
- data/lib/rubocop/cop/autocorrect_logic.rb +9 -2
- data/lib/rubocop/cop/base.rb +23 -4
- data/lib/rubocop/cop/bundler/duplicated_gem.rb +1 -0
- data/lib/rubocop/cop/bundler/duplicated_group.rb +127 -0
- data/lib/rubocop/cop/bundler/gem_comment.rb +3 -3
- data/lib/rubocop/cop/bundler/gem_version.rb +2 -2
- data/lib/rubocop/cop/bundler/ordered_gems.rb +9 -1
- data/lib/rubocop/cop/correctors/alignment_corrector.rb +1 -1
- 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/lambda_literal_to_method_corrector.rb +7 -4
- data/lib/rubocop/cop/exclude_limit.rb +1 -1
- data/lib/rubocop/cop/gemspec/dependency_version.rb +2 -2
- data/lib/rubocop/cop/gemspec/deprecated_attribute_assignment.rb +2 -2
- data/lib/rubocop/cop/gemspec/development_dependencies.rb +1 -1
- data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +9 -1
- data/lib/rubocop/cop/gemspec/required_ruby_version.rb +5 -1
- data/lib/rubocop/cop/generator/require_file_injector.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/cop_description.rb +32 -8
- data/lib/rubocop/cop/internal_affairs/example_description.rb +45 -24
- data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +3 -1
- data/lib/rubocop/cop/internal_affairs/method_name_end_with.rb +8 -6
- data/lib/rubocop/cop/internal_affairs/method_name_equal.rb +19 -20
- data/lib/rubocop/cop/internal_affairs/node_first_or_last_argument.rb +53 -0
- data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +127 -33
- data/lib/rubocop/cop/internal_affairs/redundant_expect_offense_arguments.rb +34 -0
- data/lib/rubocop/cop/internal_affairs/redundant_method_dispatch_node.rb +11 -2
- data/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +2 -0
- data/lib/rubocop/cop/internal_affairs.rb +2 -0
- data/lib/rubocop/cop/layout/argument_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/class_structure.rb +7 -0
- data/lib/rubocop/cop/layout/closing_heredoc_indentation.rb +1 -2
- data/lib/rubocop/cop/layout/dot_position.rb +1 -5
- data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +42 -9
- data/lib/rubocop/cop/layout/empty_line_after_magic_comment.rb +14 -7
- data/lib/rubocop/cop/layout/empty_line_between_defs.rb +27 -4
- data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +2 -0
- data/lib/rubocop/cop/layout/end_alignment.rb +15 -3
- data/lib/rubocop/cop/layout/extra_spacing.rb +4 -10
- data/lib/rubocop/cop/layout/first_array_element_indentation.rb +22 -7
- data/lib/rubocop/cop/layout/first_parameter_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +4 -4
- data/lib/rubocop/cop/layout/heredoc_indentation.rb +4 -1
- data/lib/rubocop/cop/layout/indentation_style.rb +1 -1
- data/lib/rubocop/cop/layout/indentation_width.rb +3 -3
- data/lib/rubocop/cop/layout/leading_comment_space.rb +1 -1
- data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +17 -9
- data/lib/rubocop/cop/layout/line_continuation_spacing.rb +1 -1
- data/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb +2 -0
- data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +18 -3
- data/lib/rubocop/cop/layout/redundant_line_break.rb +30 -7
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +4 -4
- data/lib/rubocop/cop/layout/single_line_block_chain.rb +5 -0
- data/lib/rubocop/cop/layout/space_after_comma.rb +9 -1
- data/lib/rubocop/cop/layout/space_after_not.rb +1 -1
- data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +2 -2
- data/lib/rubocop/cop/layout/space_around_operators.rb +53 -21
- data/lib/rubocop/cop/layout/space_before_block_braces.rb +19 -10
- data/lib/rubocop/cop/layout/space_inside_block_braces.rb +2 -0
- data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +1 -1
- data/lib/rubocop/cop/layout/space_inside_parens.rb +1 -1
- data/lib/rubocop/cop/layout/space_inside_range_literal.rb +1 -1
- data/lib/rubocop/cop/layout/trailing_empty_lines.rb +5 -0
- data/lib/rubocop/cop/lint/ambiguous_block_association.rb +13 -1
- data/lib/rubocop/cop/lint/assignment_in_condition.rb +4 -4
- data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +2 -2
- data/lib/rubocop/cop/lint/constant_overwritten_in_rescue.rb +1 -1
- data/lib/rubocop/cop/lint/debugger.rb +19 -5
- data/lib/rubocop/cop/lint/duplicate_hash_key.rb +2 -1
- data/lib/rubocop/cop/lint/duplicate_methods.rb +1 -1
- data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +46 -19
- data/lib/rubocop/cop/lint/empty_block.rb +1 -1
- data/lib/rubocop/cop/lint/empty_conditional_body.rb +1 -1
- data/lib/rubocop/cop/lint/erb_new_arguments.rb +6 -7
- data/lib/rubocop/cop/lint/float_comparison.rb +10 -0
- data/lib/rubocop/cop/lint/hash_compare_by_identity.rb +2 -1
- data/lib/rubocop/cop/lint/heredoc_method_call_position.rb +1 -1
- data/lib/rubocop/cop/lint/identity_comparison.rb +0 -1
- data/lib/rubocop/cop/lint/incompatible_io_select_with_fiber_scheduler.rb +5 -3
- data/lib/rubocop/cop/lint/inherit_exception.rb +9 -0
- data/lib/rubocop/cop/lint/it_without_arguments_in_block.rb +56 -0
- data/lib/rubocop/cop/lint/lambda_without_literal_block.rb +1 -1
- data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +85 -0
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +1 -1
- data/lib/rubocop/cop/lint/missing_super.rb +34 -5
- data/lib/rubocop/cop/lint/mixed_case_range.rb +111 -0
- data/lib/rubocop/cop/lint/next_without_accumulator.rb +6 -21
- data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +10 -7
- data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +3 -5
- data/lib/rubocop/cop/lint/number_conversion.rb +14 -4
- data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +2 -2
- data/lib/rubocop/cop/lint/ordered_magic_comments.rb +0 -1
- data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +2 -2
- data/lib/rubocop/cop/lint/redundant_regexp_quantifiers.rb +130 -0
- data/lib/rubocop/cop/lint/redundant_require_statement.rb +12 -3
- data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +72 -8
- data/lib/rubocop/cop/lint/redundant_string_coercion.rb +1 -1
- data/lib/rubocop/cop/lint/redundant_with_index.rb +3 -2
- data/lib/rubocop/cop/lint/redundant_with_object.rb +2 -2
- data/lib/rubocop/cop/lint/rescue_type.rb +1 -3
- data/lib/rubocop/cop/lint/safe_navigation_chain.rb +14 -8
- data/lib/rubocop/cop/lint/script_permission.rb +3 -3
- data/lib/rubocop/cop/lint/self_assignment.rb +38 -0
- data/lib/rubocop/cop/lint/send_with_mixin_argument.rb +1 -2
- data/lib/rubocop/cop/lint/shadowed_argument.rb +1 -0
- data/lib/rubocop/cop/lint/shadowed_exception.rb +5 -11
- data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +7 -1
- data/lib/rubocop/cop/lint/struct_new_override.rb +12 -12
- data/lib/rubocop/cop/lint/suppressed_exception.rb +2 -2
- data/lib/rubocop/cop/lint/symbol_conversion.rb +8 -3
- data/lib/rubocop/cop/lint/syntax.rb +6 -3
- data/lib/rubocop/cop/lint/to_enum_arguments.rb +12 -5
- data/lib/rubocop/cop/lint/top_level_return_with_argument.rb +23 -9
- data/lib/rubocop/cop/lint/trailing_comma_in_attribute_declaration.rb +1 -1
- data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +2 -2
- data/lib/rubocop/cop/lint/useless_access_modifier.rb +2 -2
- data/lib/rubocop/cop/lint/useless_assignment.rb +94 -10
- data/lib/rubocop/cop/lint/useless_times.rb +2 -2
- data/lib/rubocop/cop/lint/void.rb +97 -11
- data/lib/rubocop/cop/metrics/abc_size.rb +3 -3
- data/lib/rubocop/cop/metrics/block_length.rb +1 -1
- data/lib/rubocop/cop/metrics/class_length.rb +8 -3
- data/lib/rubocop/cop/metrics/method_length.rb +1 -1
- data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +1 -2
- data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +32 -4
- data/lib/rubocop/cop/migration/department_name.rb +2 -2
- data/lib/rubocop/cop/mixin/allowed_receivers.rb +34 -0
- data/lib/rubocop/cop/mixin/check_line_breakable.rb +1 -1
- data/lib/rubocop/cop/mixin/comments_help.rb +19 -11
- data/lib/rubocop/cop/mixin/configurable_formatting.rb +1 -0
- data/lib/rubocop/cop/mixin/def_node.rb +1 -1
- data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +1 -1
- data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +14 -11
- data/lib/rubocop/cop/mixin/heredoc.rb +6 -2
- data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +4 -3
- data/lib/rubocop/cop/mixin/percent_literal.rb +1 -1
- data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +6 -8
- data/lib/rubocop/cop/mixin/space_after_punctuation.rb +1 -1
- data/lib/rubocop/cop/mixin/space_before_punctuation.rb +1 -1
- data/lib/rubocop/cop/mixin/string_help.rb +4 -2
- data/lib/rubocop/cop/mixin/trailing_comma.rb +1 -1
- data/lib/rubocop/cop/naming/block_forwarding.rb +13 -5
- data/lib/rubocop/cop/naming/constant_name.rb +2 -3
- data/lib/rubocop/cop/naming/file_name.rb +1 -1
- data/lib/rubocop/cop/naming/heredoc_delimiter_naming.rb +3 -1
- data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +26 -11
- data/lib/rubocop/cop/naming/predicate_name.rb +2 -2
- data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +11 -3
- data/lib/rubocop/cop/naming/variable_name.rb +6 -1
- data/lib/rubocop/cop/registry.rb +1 -1
- data/lib/rubocop/cop/security/open.rb +2 -2
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +2 -2
- data/lib/rubocop/cop/style/accessor_grouping.rb +6 -2
- data/lib/rubocop/cop/style/alias.rb +9 -8
- data/lib/rubocop/cop/style/arguments_forwarding.rb +411 -63
- data/lib/rubocop/cop/style/array_first_last.rb +64 -0
- data/lib/rubocop/cop/style/array_intersect.rb +13 -5
- data/lib/rubocop/cop/style/attr.rb +11 -1
- data/lib/rubocop/cop/style/auto_resource_cleanup.rb +21 -14
- data/lib/rubocop/cop/style/begin_block.rb +1 -2
- data/lib/rubocop/cop/style/bisected_attr_accessor.rb +2 -2
- data/lib/rubocop/cop/style/block_comments.rb +1 -1
- data/lib/rubocop/cop/style/block_delimiters.rb +5 -4
- data/lib/rubocop/cop/style/case_like_if.rb +5 -5
- data/lib/rubocop/cop/style/class_and_module_children.rb +1 -1
- data/lib/rubocop/cop/style/class_check.rb +1 -0
- data/lib/rubocop/cop/style/class_equality_comparison.rb +24 -39
- data/lib/rubocop/cop/style/class_vars.rb +3 -3
- data/lib/rubocop/cop/style/collection_compact.rb +32 -12
- data/lib/rubocop/cop/style/collection_methods.rb +2 -0
- data/lib/rubocop/cop/style/colon_method_call.rb +2 -2
- data/lib/rubocop/cop/style/combinable_loops.rb +36 -8
- data/lib/rubocop/cop/style/commented_keyword.rb +5 -2
- data/lib/rubocop/cop/style/concat_array_literals.rb +2 -1
- data/lib/rubocop/cop/style/conditional_assignment.rb +11 -10
- data/lib/rubocop/cop/style/copyright.rb +5 -2
- data/lib/rubocop/cop/style/date_time.rb +5 -4
- data/lib/rubocop/cop/style/dir.rb +1 -1
- data/lib/rubocop/cop/style/dir_empty.rb +8 -14
- data/lib/rubocop/cop/style/document_dynamic_eval_definition.rb +1 -1
- data/lib/rubocop/cop/style/documentation.rb +1 -1
- data/lib/rubocop/cop/style/each_for_simple_loop.rb +7 -7
- data/lib/rubocop/cop/style/each_with_object.rb +2 -2
- data/lib/rubocop/cop/style/empty_case_condition.rb +6 -1
- data/lib/rubocop/cop/style/empty_literal.rb +1 -1
- data/lib/rubocop/cop/style/eval_with_location.rb +8 -19
- data/lib/rubocop/cop/style/exact_regexp_match.rb +69 -0
- data/lib/rubocop/cop/style/explicit_block_argument.rb +2 -2
- data/lib/rubocop/cop/style/file_read.rb +2 -2
- data/lib/rubocop/cop/style/for.rb +3 -1
- data/lib/rubocop/cop/style/format_string.rb +24 -3
- data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +3 -1
- data/lib/rubocop/cop/style/guard_clause.rb +28 -0
- data/lib/rubocop/cop/style/hash_conversion.rb +10 -0
- data/lib/rubocop/cop/style/hash_each_methods.rb +106 -33
- data/lib/rubocop/cop/style/hash_except.rb +21 -9
- data/lib/rubocop/cop/style/hash_syntax.rb +6 -2
- data/lib/rubocop/cop/style/hash_transform_keys.rb +2 -2
- data/lib/rubocop/cop/style/hash_transform_values.rb +2 -2
- data/lib/rubocop/cop/style/identical_conditional_branches.rb +34 -5
- data/lib/rubocop/cop/style/if_inside_else.rb +6 -0
- data/lib/rubocop/cop/style/if_unless_modifier.rb +3 -0
- data/lib/rubocop/cop/style/if_with_semicolon.rb +2 -2
- data/lib/rubocop/cop/style/inverse_methods.rb +14 -13
- data/lib/rubocop/cop/style/invertible_unless_condition.rb +54 -8
- data/lib/rubocop/cop/style/lambda.rb +3 -3
- data/lib/rubocop/cop/style/lambda_call.rb +5 -0
- data/lib/rubocop/cop/style/map_compact_with_conditional_block.rb +8 -10
- data/lib/rubocop/cop/style/map_to_hash.rb +17 -7
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +24 -9
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +2 -4
- data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +20 -0
- data/lib/rubocop/cop/style/method_def_parentheses.rb +1 -1
- data/lib/rubocop/cop/style/missing_respond_to_missing.rb +2 -2
- data/lib/rubocop/cop/style/mixin_grouping.rb +1 -1
- data/lib/rubocop/cop/style/multiline_block_chain.rb +1 -1
- data/lib/rubocop/cop/style/multiline_method_signature.rb +10 -1
- data/lib/rubocop/cop/style/multiline_ternary_operator.rb +6 -4
- data/lib/rubocop/cop/style/multiple_comparison.rb +14 -0
- data/lib/rubocop/cop/style/nested_ternary_operator.rb +3 -11
- data/lib/rubocop/cop/style/next.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_literals.rb +1 -1
- data/lib/rubocop/cop/style/object_then.rb +5 -3
- data/lib/rubocop/cop/style/open_struct_use.rb +1 -1
- data/lib/rubocop/cop/style/operator_method_call.rb +8 -2
- data/lib/rubocop/cop/style/parallel_assignment.rb +3 -5
- data/lib/rubocop/cop/style/parentheses_around_condition.rb +8 -0
- data/lib/rubocop/cop/style/percent_literal_delimiters.rb +1 -1
- data/lib/rubocop/cop/style/preferred_hash_methods.rb +1 -1
- data/lib/rubocop/cop/style/raise_args.rb +4 -1
- data/lib/rubocop/cop/style/redundant_argument.rb +10 -4
- data/lib/rubocop/cop/style/redundant_array_constructor.rb +77 -0
- data/lib/rubocop/cop/style/redundant_assignment.rb +10 -2
- data/lib/rubocop/cop/style/redundant_begin.rb +10 -2
- data/lib/rubocop/cop/style/redundant_conditional.rb +2 -10
- data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +39 -0
- data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +93 -5
- data/lib/rubocop/cop/style/redundant_each.rb +7 -4
- data/lib/rubocop/cop/style/redundant_exception.rb +32 -12
- data/lib/rubocop/cop/style/redundant_fetch_block.rb +3 -3
- data/lib/rubocop/cop/style/redundant_filter_chain.rb +118 -0
- data/lib/rubocop/cop/style/redundant_line_continuation.rb +32 -8
- data/lib/rubocop/cop/style/redundant_parentheses.rb +72 -23
- data/lib/rubocop/cop/style/redundant_regexp_argument.rb +100 -0
- data/lib/rubocop/cop/style/redundant_regexp_constructor.rb +46 -0
- data/lib/rubocop/cop/style/redundant_regexp_escape.rb +2 -1
- data/lib/rubocop/cop/style/redundant_return.rb +14 -3
- data/lib/rubocop/cop/style/redundant_self.rb +17 -2
- data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +8 -1
- data/lib/rubocop/cop/style/redundant_sort.rb +10 -9
- data/lib/rubocop/cop/style/redundant_sort_by.rb +2 -2
- data/lib/rubocop/cop/style/redundant_string_escape.rb +3 -1
- data/lib/rubocop/cop/style/regexp_literal.rb +11 -2
- data/lib/rubocop/cop/style/require_order.rb +11 -5
- data/lib/rubocop/cop/style/rescue_modifier.rb +1 -3
- data/lib/rubocop/cop/style/return_nil.rb +6 -2
- data/lib/rubocop/cop/style/return_nil_in_predicate_method_definition.rb +95 -0
- data/lib/rubocop/cop/style/sample.rb +3 -4
- data/lib/rubocop/cop/style/select_by_regexp.rb +22 -11
- data/lib/rubocop/cop/style/self_assignment.rb +1 -1
- data/lib/rubocop/cop/style/semicolon.rb +20 -4
- data/lib/rubocop/cop/style/signal_exception.rb +1 -1
- data/lib/rubocop/cop/style/single_argument_dig.rb +7 -3
- data/lib/rubocop/cop/style/single_line_do_end_block.rb +67 -0
- data/lib/rubocop/cop/style/single_line_methods.rb +1 -1
- data/lib/rubocop/cop/style/slicing_with_range.rb +76 -10
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +6 -2
- data/lib/rubocop/cop/style/special_global_vars.rb +3 -4
- data/lib/rubocop/cop/style/string_chars.rb +1 -0
- data/lib/rubocop/cop/style/string_literals_in_interpolation.rb +30 -5
- data/lib/rubocop/cop/style/strip.rb +7 -4
- data/lib/rubocop/cop/style/super_with_args_parentheses.rb +35 -0
- data/lib/rubocop/cop/style/symbol_array.rb +35 -15
- data/lib/rubocop/cop/style/symbol_proc.rb +36 -0
- data/lib/rubocop/cop/style/unpack_first.rb +11 -14
- data/lib/rubocop/cop/style/yaml_file_read.rb +66 -0
- data/lib/rubocop/cop/style/yoda_condition.rb +4 -2
- data/lib/rubocop/cop/style/yoda_expression.rb +8 -7
- data/lib/rubocop/cop/team.rb +1 -1
- data/lib/rubocop/cop/util.rb +1 -1
- data/lib/rubocop/cop/utils/regexp_ranges.rb +113 -0
- data/lib/rubocop/cop/variable_force/assignment.rb +45 -4
- data/lib/rubocop/cop/variable_force/variable_table.rb +2 -2
- data/lib/rubocop/cop/variable_force.rb +1 -0
- data/lib/rubocop/cops_documentation_generator.rb +16 -4
- data/lib/rubocop/directive_comment.rb +10 -8
- data/lib/rubocop/ext/regexp_node.rb +9 -4
- data/lib/rubocop/ext/regexp_parser.rb +4 -1
- data/lib/rubocop/file_finder.rb +4 -7
- data/lib/rubocop/formatter/disabled_config_formatter.rb +17 -6
- data/lib/rubocop/formatter/html_formatter.rb +35 -14
- data/lib/rubocop/formatter/json_formatter.rb +0 -1
- data/lib/rubocop/formatter/junit_formatter.rb +1 -1
- data/lib/rubocop/formatter/offense_count_formatter.rb +12 -2
- data/lib/rubocop/formatter.rb +1 -1
- data/lib/rubocop/lsp/logger.rb +22 -0
- data/lib/rubocop/lsp/routes.rb +246 -0
- data/lib/rubocop/lsp/runtime.rb +99 -0
- data/lib/rubocop/lsp/server.rb +71 -0
- data/lib/rubocop/lsp/severity.rb +27 -0
- data/lib/rubocop/lsp.rb +29 -0
- data/lib/rubocop/magic_comment.rb +13 -11
- data/lib/rubocop/options.rb +22 -9
- data/lib/rubocop/path_util.rb +6 -2
- data/lib/rubocop/result_cache.rb +5 -2
- data/lib/rubocop/rspec/cop_helper.rb +8 -2
- data/lib/rubocop/rspec/expect_offense.rb +8 -8
- data/lib/rubocop/rspec/shared_contexts.rb +42 -18
- data/lib/rubocop/rspec/support.rb +2 -0
- data/lib/rubocop/runner.rb +15 -6
- data/lib/rubocop/server/cache.rb +1 -1
- data/lib/rubocop/server/client_command/exec.rb +3 -3
- data/lib/rubocop/server/server_command/exec.rb +0 -1
- data/lib/rubocop/string_interpreter.rb +3 -3
- data/lib/rubocop/target_finder.rb +91 -81
- data/lib/rubocop/target_ruby.rb +85 -78
- data/lib/rubocop/version.rb +27 -8
- data/lib/rubocop.rb +19 -0
- metadata +56 -14
- /data/lib/rubocop/formatter/{git_hub_actions_formatter.rb → github_actions_formatter.rb} +0 -0
@@ -70,6 +70,10 @@ module RuboCop
|
|
70
70
|
|
71
71
|
MSG = 'Redundant line continuation.'
|
72
72
|
ALLOWED_STRING_TOKENS = %i[tSTRING tSTRING_CONTENT].freeze
|
73
|
+
ARGUMENT_TYPES = %i[
|
74
|
+
kFALSE kNIL kSELF kTRUE tCONSTANT tCVAR tFLOAT tGVAR tIDENTIFIER tINTEGER tIVAR
|
75
|
+
tLABEL tLBRACK tLCURLY tLPAREN_ARG tSTRING tSTRING_BEG tSYMBOL tXSTRING_BEG
|
76
|
+
].freeze
|
73
77
|
|
74
78
|
def on_new_investigation
|
75
79
|
return unless processed_source.ast
|
@@ -90,7 +94,8 @@ module RuboCop
|
|
90
94
|
!ends_with_backslash_without_comment?(range.source_line) ||
|
91
95
|
string_concatenation?(range.source_line) ||
|
92
96
|
start_with_arithmetic_operator?(processed_source[range.line]) ||
|
93
|
-
inside_string_literal_or_method_with_argument?(range)
|
97
|
+
inside_string_literal_or_method_with_argument?(range) ||
|
98
|
+
leading_dot_method_chain_with_blank_line?(range)
|
94
99
|
end
|
95
100
|
|
96
101
|
def ends_with_backslash_without_comment?(source_line)
|
@@ -103,16 +108,26 @@ module RuboCop
|
|
103
108
|
|
104
109
|
def inside_string_literal_or_method_with_argument?(range)
|
105
110
|
processed_source.tokens.each_cons(2).any? do |token, next_token|
|
111
|
+
next if token.line == next_token.line
|
112
|
+
|
106
113
|
inside_string_literal?(range, token) || method_with_argument?(token, next_token)
|
107
114
|
end
|
108
115
|
end
|
109
116
|
|
117
|
+
def leading_dot_method_chain_with_blank_line?(range)
|
118
|
+
return false unless range.source_line.strip.start_with?('.', '&.')
|
119
|
+
|
120
|
+
processed_source[range.line].strip.empty?
|
121
|
+
end
|
122
|
+
|
110
123
|
def redundant_line_continuation?(range)
|
111
124
|
return true unless (node = find_node_for_line(range.line))
|
112
125
|
return false if argument_newline?(node)
|
113
126
|
|
114
|
-
|
115
|
-
|
127
|
+
continuation_node = node.parent || node
|
128
|
+
return false if allowed_type?(node) || allowed_type?(continuation_node)
|
129
|
+
|
130
|
+
continuation_node.source.include?("\n") || continuation_node.source.include?("\\\n")
|
116
131
|
end
|
117
132
|
|
118
133
|
def inside_string_literal?(range, token)
|
@@ -124,20 +139,25 @@ module RuboCop
|
|
124
139
|
# do_something \
|
125
140
|
# argument
|
126
141
|
def method_with_argument?(current_token, next_token)
|
127
|
-
current_token.type == :tIDENTIFIER && next_token.type
|
142
|
+
current_token.type == :tIDENTIFIER && ARGUMENT_TYPES.include?(next_token.type)
|
128
143
|
end
|
129
144
|
|
145
|
+
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
130
146
|
def argument_newline?(node)
|
147
|
+
node = node.to_a.last if node.assignment?
|
148
|
+
return false if node.parenthesized_call?
|
149
|
+
|
131
150
|
node = node.children.first if node.root? && node.begin_type?
|
132
151
|
|
133
|
-
if argument_is_method?(node)
|
134
|
-
argument_newline?(node.
|
152
|
+
if argument_is_method?(node) || node.begin_type?
|
153
|
+
argument_newline?(node.children.first)
|
135
154
|
else
|
136
155
|
return false unless method_call_with_arguments?(node)
|
137
156
|
|
138
|
-
node
|
157
|
+
!same_line?(node, node.first_argument)
|
139
158
|
end
|
140
159
|
end
|
160
|
+
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
141
161
|
|
142
162
|
def find_node_for_line(line)
|
143
163
|
processed_source.ast.each_node do |node|
|
@@ -145,8 +165,12 @@ module RuboCop
|
|
145
165
|
end
|
146
166
|
end
|
147
167
|
|
168
|
+
def allowed_type?(node)
|
169
|
+
node.and_type? || node.or_type? || (node.if_type? && node.ternary?)
|
170
|
+
end
|
171
|
+
|
148
172
|
def same_line?(node, line)
|
149
|
-
return unless (source_range = node.source_range)
|
173
|
+
return false unless (source_range = node.source_range)
|
150
174
|
|
151
175
|
if node.is_a?(AST::StrNode)
|
152
176
|
if node.heredoc?
|
@@ -17,12 +17,11 @@ module RuboCop
|
|
17
17
|
include Parentheses
|
18
18
|
extend AutoCorrector
|
19
19
|
|
20
|
+
ALLOWED_NODE_TYPES = %i[and or send splat kwsplat].freeze
|
21
|
+
|
20
22
|
# @!method square_brackets?(node)
|
21
23
|
def_node_matcher :square_brackets?, '(send {(send _recv _msg) str array hash} :[] ...)'
|
22
24
|
|
23
|
-
# @!method range_end?(node)
|
24
|
-
def_node_matcher :range_end?, '^^{irange erange}'
|
25
|
-
|
26
25
|
# @!method method_node_and_args(node)
|
27
26
|
def_node_matcher :method_node_and_args, '$(call _recv _msg $...)'
|
28
27
|
|
@@ -54,15 +53,16 @@ module RuboCop
|
|
54
53
|
def ignore_syntax?(node)
|
55
54
|
return false unless (parent = node.parent)
|
56
55
|
|
57
|
-
parent.while_post_type? || parent.until_post_type? ||
|
58
|
-
like_method_argument_parentheses?(parent)
|
56
|
+
parent.while_post_type? || parent.until_post_type? || parent.match_with_lvasgn_type? ||
|
57
|
+
like_method_argument_parentheses?(parent) || multiline_control_flow_statements?(node)
|
59
58
|
end
|
60
59
|
|
61
60
|
def allowed_expression?(node)
|
62
61
|
allowed_ancestor?(node) ||
|
63
62
|
allowed_method_call?(node) ||
|
64
63
|
allowed_multiple_expression?(node) ||
|
65
|
-
allowed_ternary?(node)
|
64
|
+
allowed_ternary?(node) ||
|
65
|
+
node.parent&.range_type?
|
66
66
|
end
|
67
67
|
|
68
68
|
def allowed_ancestor?(node)
|
@@ -85,7 +85,7 @@ module RuboCop
|
|
85
85
|
end
|
86
86
|
|
87
87
|
def allowed_ternary?(node)
|
88
|
-
return unless node&.parent&.if_type?
|
88
|
+
return false unless node&.parent&.if_type?
|
89
89
|
|
90
90
|
node.parent.ternary? && ternary_parentheses_required?
|
91
91
|
end
|
@@ -98,10 +98,19 @@ module RuboCop
|
|
98
98
|
end
|
99
99
|
|
100
100
|
def like_method_argument_parentheses?(node)
|
101
|
-
node.send_type? && node.
|
101
|
+
return false if !node.send_type? && !node.super_type? && !node.yield_type?
|
102
|
+
|
103
|
+
node.arguments.one? && !node.parenthesized? &&
|
102
104
|
!node.arithmetic_operation? && node.first_argument.begin_type?
|
103
105
|
end
|
104
106
|
|
107
|
+
def multiline_control_flow_statements?(node)
|
108
|
+
return false unless (parent = node.parent)
|
109
|
+
return false if parent.single_line?
|
110
|
+
|
111
|
+
parent.return_type? || parent.next_type? || parent.break_type?
|
112
|
+
end
|
113
|
+
|
105
114
|
def empty_parentheses?(node)
|
106
115
|
# Don't flag `()`
|
107
116
|
node.children.empty?
|
@@ -109,34 +118,69 @@ module RuboCop
|
|
109
118
|
|
110
119
|
def first_arg_begins_with_hash_literal?(node)
|
111
120
|
# Don't flag `method ({key: value})` or `method ({key: value}.method)`
|
112
|
-
method_chain_begins_with_hash_literal
|
113
|
-
|
114
|
-
|
121
|
+
hash_literal = method_chain_begins_with_hash_literal(node.children.first)
|
122
|
+
if (root_method = node.each_ancestor(:send).to_a.last)
|
123
|
+
parenthesized = root_method.parenthesized_call?
|
124
|
+
end
|
125
|
+
hash_literal && first_argument?(node) && !parentheses?(hash_literal) && !parenthesized
|
115
126
|
end
|
116
127
|
|
117
|
-
def method_chain_begins_with_hash_literal
|
118
|
-
return
|
119
|
-
return
|
120
|
-
return
|
128
|
+
def method_chain_begins_with_hash_literal(node)
|
129
|
+
return if node.nil?
|
130
|
+
return node if node.hash_type?
|
131
|
+
return unless node.send_type?
|
121
132
|
|
122
|
-
method_chain_begins_with_hash_literal
|
133
|
+
method_chain_begins_with_hash_literal(node.children.first)
|
123
134
|
end
|
124
135
|
|
125
136
|
def check(begin_node)
|
126
137
|
node = begin_node.children.first
|
127
|
-
return offense(begin_node, 'a keyword') if keyword_with_redundant_parentheses?(node)
|
128
|
-
return offense(begin_node, 'a literal') if disallowed_literal?(begin_node, node)
|
129
|
-
return offense(begin_node, 'a variable') if node.variable?
|
130
|
-
return offense(begin_node, 'a constant') if node.const_type?
|
131
138
|
|
132
|
-
|
139
|
+
if (message = find_offense_message(begin_node, node))
|
140
|
+
return offense(begin_node, message)
|
141
|
+
end
|
133
142
|
|
134
143
|
check_send(begin_node, node) if node.call_type?
|
135
144
|
end
|
136
145
|
|
146
|
+
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
147
|
+
def find_offense_message(begin_node, node)
|
148
|
+
return 'a keyword' if keyword_with_redundant_parentheses?(node)
|
149
|
+
return 'a literal' if disallowed_literal?(begin_node, node)
|
150
|
+
return 'a variable' if node.variable?
|
151
|
+
return 'a constant' if node.const_type?
|
152
|
+
if node.lambda_or_proc? && (node.braces? || node.send_node.lambda_literal?)
|
153
|
+
return 'an expression'
|
154
|
+
end
|
155
|
+
return 'an interpolated expression' if interpolation?(begin_node)
|
156
|
+
|
157
|
+
return if begin_node.chained?
|
158
|
+
|
159
|
+
if node.and_type? || node.or_type?
|
160
|
+
return if node.semantic_operator? && begin_node.parent
|
161
|
+
return if node.multiline? && allow_in_multiline_conditions?
|
162
|
+
return if ALLOWED_NODE_TYPES.include?(begin_node.parent&.type)
|
163
|
+
return if begin_node.parent&.if_type? && begin_node.parent&.ternary?
|
164
|
+
|
165
|
+
'a logical expression'
|
166
|
+
elsif node.respond_to?(:comparison_method?) && node.comparison_method?
|
167
|
+
return unless begin_node.parent.nil?
|
168
|
+
|
169
|
+
'a comparison expression'
|
170
|
+
end
|
171
|
+
end
|
172
|
+
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
173
|
+
|
137
174
|
# @!method interpolation?(node)
|
138
175
|
def_node_matcher :interpolation?, '[^begin ^^dstr]'
|
139
176
|
|
177
|
+
def allow_in_multiline_conditions?
|
178
|
+
parentheses_around_condition_config = config.for_cop('Style/ParenthesesAroundCondition')
|
179
|
+
return false unless parentheses_around_condition_config['Enabled']
|
180
|
+
|
181
|
+
!!parentheses_around_condition_config['AllowInMultilineConditions']
|
182
|
+
end
|
183
|
+
|
140
184
|
def check_send(begin_node, node)
|
141
185
|
return check_unary(begin_node, node) if node.unary_operation?
|
142
186
|
|
@@ -201,7 +245,6 @@ module RuboCop
|
|
201
245
|
def method_call_with_redundant_parentheses?(node)
|
202
246
|
return false unless node.call_type?
|
203
247
|
return false if node.prefix_not?
|
204
|
-
return false if range_end?(node)
|
205
248
|
|
206
249
|
send_node, args = method_node_and_args(node)
|
207
250
|
|
@@ -213,7 +256,13 @@ module RuboCop
|
|
213
256
|
end
|
214
257
|
|
215
258
|
def first_argument?(node)
|
216
|
-
first_send_argument?(node) ||
|
259
|
+
if first_send_argument?(node) ||
|
260
|
+
first_super_argument?(node) ||
|
261
|
+
first_yield_argument?(node)
|
262
|
+
return true
|
263
|
+
end
|
264
|
+
|
265
|
+
node.each_ancestor.any? { |ancestor| first_argument?(ancestor) }
|
217
266
|
end
|
218
267
|
|
219
268
|
# @!method first_send_argument?(node)
|
@@ -0,0 +1,100 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Style
|
6
|
+
# Identifies places where argument can be replaced from
|
7
|
+
# a deterministic regexp to a string.
|
8
|
+
#
|
9
|
+
# @example
|
10
|
+
# # bad
|
11
|
+
# 'foo'.byteindex(/f/)
|
12
|
+
# 'foo'.byterindex(/f/)
|
13
|
+
# 'foo'.gsub(/f/, 'x')
|
14
|
+
# 'foo'.gsub!(/f/, 'x')
|
15
|
+
# 'foo'.partition(/f/)
|
16
|
+
# 'foo'.rpartition(/f/)
|
17
|
+
# 'foo'.scan(/f/)
|
18
|
+
# 'foo'.split(/f/)
|
19
|
+
# 'foo'.start_with?(/f/)
|
20
|
+
# 'foo'.sub(/f/, 'x')
|
21
|
+
# 'foo'.sub!(/f/, 'x')
|
22
|
+
#
|
23
|
+
# # good
|
24
|
+
# 'foo'.byteindex('f')
|
25
|
+
# 'foo'.byterindex('f')
|
26
|
+
# 'foo'.gsub('f', 'x')
|
27
|
+
# 'foo'.gsub!('f', 'x')
|
28
|
+
# 'foo'.partition('f')
|
29
|
+
# 'foo'.rpartition('f')
|
30
|
+
# 'foo'.scan('f')
|
31
|
+
# 'foo'.split('f')
|
32
|
+
# 'foo'.start_with?('f')
|
33
|
+
# 'foo'.sub('f', 'x')
|
34
|
+
# 'foo'.sub!('f', 'x')
|
35
|
+
class RedundantRegexpArgument < Base
|
36
|
+
extend AutoCorrector
|
37
|
+
|
38
|
+
MSG = 'Use string `%<prefer>s` as argument instead of regexp `%<current>s`.'
|
39
|
+
RESTRICT_ON_SEND = %i[
|
40
|
+
byteindex byterindex gsub gsub! partition rpartition scan split start_with? sub sub!
|
41
|
+
].freeze
|
42
|
+
DETERMINISTIC_REGEX = /\A(?:#{LITERAL_REGEX})+\Z/.freeze
|
43
|
+
STR_SPECIAL_CHARS = %w[
|
44
|
+
\a \c \C \e \f \M \n \" \' \\\\ \t \b \f \r \u \v \x \0 \1 \2 \3 \4 \5 \6 \7
|
45
|
+
].freeze
|
46
|
+
|
47
|
+
def on_send(node)
|
48
|
+
return unless (regexp_node = node.first_argument)
|
49
|
+
return unless regexp_node.regexp_type?
|
50
|
+
return if !regexp_node.regopt.children.empty? || regexp_node.content == ' '
|
51
|
+
return unless determinist_regexp?(regexp_node)
|
52
|
+
|
53
|
+
prefer = preferred_argument(regexp_node)
|
54
|
+
message = format(MSG, prefer: prefer, current: regexp_node.source)
|
55
|
+
|
56
|
+
add_offense(regexp_node, message: message) do |corrector|
|
57
|
+
corrector.replace(regexp_node, prefer)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
alias on_csend on_send
|
61
|
+
|
62
|
+
private
|
63
|
+
|
64
|
+
def determinist_regexp?(regexp_node)
|
65
|
+
DETERMINISTIC_REGEX.match?(regexp_node.source)
|
66
|
+
end
|
67
|
+
|
68
|
+
def preferred_argument(regexp_node)
|
69
|
+
new_argument = replacement(regexp_node)
|
70
|
+
|
71
|
+
if new_argument.include?('"')
|
72
|
+
new_argument.gsub!("'", "\\\\'")
|
73
|
+
quote = "'"
|
74
|
+
else
|
75
|
+
quote = '"'
|
76
|
+
end
|
77
|
+
|
78
|
+
"#{quote}#{new_argument}#{quote}"
|
79
|
+
end
|
80
|
+
|
81
|
+
def replacement(regexp_node)
|
82
|
+
regexp_content = regexp_node.content
|
83
|
+
stack = []
|
84
|
+
chars = regexp_content.chars.each_with_object([]) do |char, strings|
|
85
|
+
if stack.empty? && char == '\\'
|
86
|
+
stack.push(char)
|
87
|
+
else
|
88
|
+
strings << "#{stack.pop}#{char}"
|
89
|
+
end
|
90
|
+
end
|
91
|
+
chars.map do |char|
|
92
|
+
char = char.dup
|
93
|
+
char.delete!('\\') unless STR_SPECIAL_CHARS.include?(char)
|
94
|
+
char
|
95
|
+
end.join
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Style
|
6
|
+
# Checks for the instantiation of regexp using redundant `Regexp.new` or `Regexp.compile`.
|
7
|
+
# Autocorrect replaces to regexp literal which is the simplest and fastest.
|
8
|
+
#
|
9
|
+
# @example
|
10
|
+
#
|
11
|
+
# # bad
|
12
|
+
# Regexp.new(/regexp/)
|
13
|
+
# Regexp.compile(/regexp/)
|
14
|
+
#
|
15
|
+
# # good
|
16
|
+
# /regexp/
|
17
|
+
# Regexp.new('regexp')
|
18
|
+
# Regexp.compile('regexp')
|
19
|
+
#
|
20
|
+
class RedundantRegexpConstructor < Base
|
21
|
+
extend AutoCorrector
|
22
|
+
|
23
|
+
MSG = 'Remove the redundant `Regexp.%<method>s`.'
|
24
|
+
RESTRICT_ON_SEND = %i[new compile].freeze
|
25
|
+
|
26
|
+
# @!method redundant_regexp_constructor(node)
|
27
|
+
def_node_matcher :redundant_regexp_constructor, <<~PATTERN
|
28
|
+
(send
|
29
|
+
(const {nil? cbase} :Regexp) {:new :compile}
|
30
|
+
(regexp $... (regopt $...)))
|
31
|
+
PATTERN
|
32
|
+
|
33
|
+
def on_send(node)
|
34
|
+
return unless (regexp, regopt = redundant_regexp_constructor(node))
|
35
|
+
|
36
|
+
add_offense(node, message: format(MSG, method: node.method_name)) do |corrector|
|
37
|
+
pattern = regexp.map(&:source).join
|
38
|
+
regopt = regopt.join
|
39
|
+
|
40
|
+
corrector.replace(node, "/#{pattern}/#{regopt}")
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -44,7 +44,8 @@ module RuboCop
|
|
44
44
|
|
45
45
|
def on_regexp(node)
|
46
46
|
each_escape(node) do |char, index, within_character_class|
|
47
|
-
next if allowed_escape?(node, char, index,
|
47
|
+
next if char.valid_encoding? && allowed_escape?(node, char, index,
|
48
|
+
within_character_class)
|
48
49
|
|
49
50
|
location = escape_range_at_index(node, index)
|
50
51
|
|
@@ -22,13 +22,18 @@ module RuboCop
|
|
22
22
|
# return something
|
23
23
|
# end
|
24
24
|
#
|
25
|
-
# #
|
25
|
+
# # bad
|
26
26
|
# def test
|
27
27
|
# return something if something_else
|
28
28
|
# end
|
29
29
|
#
|
30
30
|
# # good
|
31
31
|
# def test
|
32
|
+
# something if something_else
|
33
|
+
# end
|
34
|
+
#
|
35
|
+
# # good
|
36
|
+
# def test
|
32
37
|
# if x
|
33
38
|
# elsif y
|
34
39
|
# else
|
@@ -53,7 +58,7 @@ module RuboCop
|
|
53
58
|
|
54
59
|
MSG = 'Redundant `return` detected.'
|
55
60
|
MULTI_RETURN_MSG = 'To return multiple values, use an array.'
|
56
|
-
RESTRICT_ON_SEND = %i[define_method define_singleton_method].freeze
|
61
|
+
RESTRICT_ON_SEND = %i[define_method define_singleton_method lambda].freeze
|
57
62
|
|
58
63
|
def on_send(node)
|
59
64
|
return unless (parent = node.parent) && parent.block_type?
|
@@ -108,6 +113,7 @@ module RuboCop
|
|
108
113
|
case node.type
|
109
114
|
when :return then check_return_node(node)
|
110
115
|
when :case then check_case_node(node)
|
116
|
+
when :case_match then check_case_match_node(node)
|
111
117
|
when :if then check_if_node(node)
|
112
118
|
when :rescue then check_rescue_node(node)
|
113
119
|
when :resbody then check_resbody_node(node)
|
@@ -135,8 +141,13 @@ module RuboCop
|
|
135
141
|
check_branch(node.else_branch)
|
136
142
|
end
|
137
143
|
|
144
|
+
def check_case_match_node(node)
|
145
|
+
node.in_pattern_branches.each { |in_pattern_node| check_branch(in_pattern_node.body) }
|
146
|
+
check_branch(node.else_branch)
|
147
|
+
end
|
148
|
+
|
138
149
|
def check_if_node(node)
|
139
|
-
return if node.
|
150
|
+
return if node.ternary?
|
140
151
|
|
141
152
|
check_branch(node.if_branch)
|
142
153
|
check_branch(node.else_branch)
|
@@ -17,7 +17,8 @@ module RuboCop
|
|
17
17
|
# protected scope, you cannot send private messages this way.
|
18
18
|
#
|
19
19
|
# Note we allow uses of `self` with operators because it would be awkward
|
20
|
-
# otherwise.
|
20
|
+
# otherwise. Also allows the use of `self.it` without arguments in blocks,
|
21
|
+
# as in `0.times { self.it }`, following `Lint/ItWithoutArgumentsInBlock` cop.
|
21
22
|
#
|
22
23
|
# @example
|
23
24
|
#
|
@@ -107,8 +108,8 @@ module RuboCop
|
|
107
108
|
def on_send(node)
|
108
109
|
return unless node.self_receiver? && regular_method_call?(node)
|
109
110
|
return if node.parent&.mlhs_type?
|
110
|
-
|
111
111
|
return if allowed_send_node?(node)
|
112
|
+
return if it_method_in_block?(node)
|
112
113
|
|
113
114
|
add_offense(node.receiver) do |corrector|
|
114
115
|
corrector.remove(node.receiver)
|
@@ -155,6 +156,20 @@ module RuboCop
|
|
155
156
|
KERNEL_METHODS.include?(node.method_name)
|
156
157
|
end
|
157
158
|
|
159
|
+
# Respects `Lint/ItWithoutArgumentsInBlock` cop and the following Ruby 3.3's warning:
|
160
|
+
#
|
161
|
+
# $ ruby -e '0.times { begin; it; end }'
|
162
|
+
# -e:1: warning: `it` calls without arguments will refer to the first block param in
|
163
|
+
# Ruby 3.4; use it() or self.it
|
164
|
+
#
|
165
|
+
def it_method_in_block?(node)
|
166
|
+
return false unless node.method?(:it)
|
167
|
+
return false unless (block_node = node.each_ancestor(:block).first)
|
168
|
+
return false unless block_node.arguments.empty_and_without_delimiters?
|
169
|
+
|
170
|
+
node.arguments.empty? && !node.block_literal?
|
171
|
+
end
|
172
|
+
|
158
173
|
def regular_method_call?(node)
|
159
174
|
!(node.operator_method? ||
|
160
175
|
KEYWORDS.include?(node.method_name) ||
|
@@ -62,7 +62,9 @@ module RuboCop
|
|
62
62
|
end
|
63
63
|
|
64
64
|
def multiple_statements?(branch)
|
65
|
-
|
65
|
+
return false unless branch&.begin_type?
|
66
|
+
|
67
|
+
!branch.children.empty?
|
66
68
|
end
|
67
69
|
|
68
70
|
def self_assign?(variable, branch)
|
@@ -73,6 +75,11 @@ module RuboCop
|
|
73
75
|
add_offense(offense_branch) do |corrector|
|
74
76
|
assignment_value = opposite_branch ? opposite_branch.source : 'nil'
|
75
77
|
replacement = "#{assignment_value} #{keyword} #{if_node.condition.source}"
|
78
|
+
if opposite_branch.respond_to?(:heredoc?) && opposite_branch.heredoc?
|
79
|
+
replacement += opposite_branch.loc.heredoc_end.with(
|
80
|
+
begin_pos: opposite_branch.source_range.end_pos
|
81
|
+
).source
|
82
|
+
end
|
76
83
|
|
77
84
|
corrector.replace(if_node, replacement)
|
78
85
|
end
|
@@ -16,7 +16,7 @@ module RuboCop
|
|
16
16
|
# This cop is unsafe, because `sort...last` and `max` may not return the
|
17
17
|
# same element in all cases.
|
18
18
|
#
|
19
|
-
# In an enumerable where there are multiple elements where
|
19
|
+
# In an enumerable where there are multiple elements where ``a <=> b == 0``,
|
20
20
|
# or where the transformation done by the `sort_by` block has the
|
21
21
|
# same result, `sort.last` and `max` (or `sort_by.last` and `max_by`)
|
22
22
|
# will return different elements. `sort.last` will return the last
|
@@ -87,15 +87,15 @@ module RuboCop
|
|
87
87
|
# @!method redundant_sort?(node)
|
88
88
|
def_node_matcher :redundant_sort?, <<~MATCHER
|
89
89
|
{
|
90
|
-
(
|
91
|
-
(
|
90
|
+
(call $(call _ $:sort) ${:last :first})
|
91
|
+
(call $(call _ $:sort) ${:[] :at :slice} {(int 0) (int -1)})
|
92
92
|
|
93
|
-
(
|
93
|
+
(call $(call _ $:sort_by _) ${:last :first})
|
94
94
|
(send $(send _ $:sort_by _) ${:[] :at :slice} {(int 0) (int -1)})
|
95
95
|
|
96
|
-
(
|
97
|
-
(
|
98
|
-
({block numblock} $(
|
96
|
+
(call ({block numblock} $(call _ ${:sort_by :sort}) ...) ${:last :first})
|
97
|
+
(call
|
98
|
+
({block numblock} $(call _ ${:sort_by :sort}) ...)
|
99
99
|
${:[] :at :slice} {(int 0) (int -1)}
|
100
100
|
)
|
101
101
|
}
|
@@ -108,6 +108,7 @@ module RuboCop
|
|
108
108
|
|
109
109
|
register_offense(ancestor, sort_node, sorter, accessor)
|
110
110
|
end
|
111
|
+
alias on_csend on_send
|
111
112
|
|
112
113
|
private
|
113
114
|
|
@@ -180,7 +181,7 @@ module RuboCop
|
|
180
181
|
end
|
181
182
|
|
182
183
|
def arg_node(node)
|
183
|
-
node.
|
184
|
+
node.first_argument
|
184
185
|
end
|
185
186
|
|
186
187
|
def arg_value(node)
|
@@ -198,7 +199,7 @@ module RuboCop
|
|
198
199
|
end
|
199
200
|
|
200
201
|
def with_logical_operator?(node)
|
201
|
-
return unless (parent = node.parent)
|
202
|
+
return false unless (parent = node.parent)
|
202
203
|
|
203
204
|
parent.or_type? || parent.and_type?
|
204
205
|
end
|
@@ -46,12 +46,12 @@ module RuboCop
|
|
46
46
|
|
47
47
|
# @!method redundant_sort_by_block(node)
|
48
48
|
def_node_matcher :redundant_sort_by_block, <<~PATTERN
|
49
|
-
(block $(
|
49
|
+
(block $(call _ :sort_by) (args (arg $_x)) (lvar _x))
|
50
50
|
PATTERN
|
51
51
|
|
52
52
|
# @!method redundant_sort_by_numblock(node)
|
53
53
|
def_node_matcher :redundant_sort_by_numblock, <<~PATTERN
|
54
|
-
(numblock $(
|
54
|
+
(numblock $(call _ :sort_by) 1 (lvar :_1))
|
55
55
|
PATTERN
|
56
56
|
|
57
57
|
def sort_by_range(send, node)
|
@@ -133,7 +133,7 @@ module RuboCop
|
|
133
133
|
end
|
134
134
|
|
135
135
|
def percent_array_literal?(node)
|
136
|
-
|
136
|
+
percent_w_literal?(node) || percent_w_upper_literal?(node)
|
137
137
|
end
|
138
138
|
|
139
139
|
def heredoc_with_disabled_interpolation?(node)
|
@@ -157,6 +157,8 @@ module RuboCop
|
|
157
157
|
return delimiter?(node.parent, char)
|
158
158
|
end
|
159
159
|
|
160
|
+
return true unless node.loc.begin
|
161
|
+
|
160
162
|
delimiters = [node.loc.begin.source[-1], node.loc.end.source[0]]
|
161
163
|
|
162
164
|
delimiters.include?(char)
|
@@ -3,7 +3,16 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module Style
|
6
|
-
# Enforces using
|
6
|
+
# Enforces using `//` or `%r` around regular expressions.
|
7
|
+
#
|
8
|
+
# NOTE: The following `%r` cases using a regexp starts with a blank or `=`
|
9
|
+
# as a method argument allowed to prevent syntax errors.
|
10
|
+
#
|
11
|
+
# [source,ruby]
|
12
|
+
# ----
|
13
|
+
# do_something %r{ regexp} # `do_something / regexp/` is an invalid syntax.
|
14
|
+
# do_something %r{=regexp} # `do_something /=regexp/` is an invalid syntax.
|
15
|
+
# ----
|
7
16
|
#
|
8
17
|
# @example EnforcedStyle: slashes (default)
|
9
18
|
# # bad
|
@@ -151,7 +160,7 @@ module RuboCop
|
|
151
160
|
|
152
161
|
def allowed_omit_parentheses_with_percent_r_literal?(node)
|
153
162
|
return false unless node.parent&.call_type?
|
154
|
-
return true if node.content.start_with?(' ')
|
163
|
+
return true if node.content.start_with?(' ', '=')
|
155
164
|
|
156
165
|
enforced_style = config.for_cop('Style/MethodCallWithArgsParentheses')['EnforcedStyle']
|
157
166
|
|