rubocop 1.41.1 → 1.57.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 +6 -4
- data/config/default.yml +243 -48
- data/config/obsoletion.yml +5 -0
- data/lib/rubocop/cli/command/auto_generate_config.rb +7 -0
- data/lib/rubocop/cli/command/execute_runner.rb +7 -2
- data/lib/rubocop/cli/command/lsp.rb +19 -0
- data/lib/rubocop/cli.rb +59 -10
- data/lib/rubocop/comment_config.rb +19 -0
- data/lib/rubocop/config.rb +14 -10
- data/lib/rubocop/config_finder.rb +2 -2
- data/lib/rubocop/config_loader.rb +20 -23
- data/lib/rubocop/config_loader_resolver.rb +5 -1
- data/lib/rubocop/config_obsoletion/parameter_rule.rb +9 -1
- data/lib/rubocop/config_obsoletion.rb +2 -2
- data/lib/rubocop/cop/autocorrect_logic.rb +31 -13
- data/lib/rubocop/cop/base.rb +96 -73
- 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 +2 -2
- data/lib/rubocop/cop/bundler/gem_version.rb +2 -2
- data/lib/rubocop/cop/bundler/ordered_gems.rb +9 -1
- data/lib/rubocop/cop/commissioner.rb +8 -2
- data/lib/rubocop/cop/cop.rb +53 -33
- data/lib/rubocop/cop/corrector.rb +31 -11
- data/lib/rubocop/cop/correctors/alignment_corrector.rb +3 -3
- data/lib/rubocop/cop/correctors/each_to_for_corrector.rb +3 -3
- data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +3 -3
- data/lib/rubocop/cop/correctors/lambda_literal_to_method_corrector.rb +7 -4
- data/lib/rubocop/cop/correctors/line_break_corrector.rb +1 -1
- data/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +2 -2
- data/lib/rubocop/cop/correctors/ordered_gem_corrector.rb +2 -7
- data/lib/rubocop/cop/correctors/parentheses_corrector.rb +1 -1
- data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +2 -2
- data/lib/rubocop/cop/gemspec/dependency_version.rb +19 -21
- data/lib/rubocop/cop/gemspec/deprecated_attribute_assignment.rb +1 -1
- data/lib/rubocop/cop/gemspec/development_dependencies.rb +107 -0
- data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +9 -1
- data/lib/rubocop/cop/generator/require_file_injector.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/cop_description.rb +37 -13
- data/lib/rubocop/cop/internal_affairs/example_description.rb +42 -21
- data/lib/rubocop/cop/internal_affairs/example_heredoc_delimiter.rb +3 -3
- data/lib/rubocop/cop/internal_affairs/inherit_deprecated_cop_class.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/location_expression.rb +37 -0
- data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +3 -1
- data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +6 -6
- data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/processed_source_buffer_name.rb +42 -0
- data/lib/rubocop/cop/internal_affairs/redundant_let_rubocop_config_new.rb +11 -3
- data/lib/rubocop/cop/internal_affairs/redundant_location_argument.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/redundant_message_argument.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/redundant_method_dispatch_node.rb +11 -2
- data/lib/rubocop/cop/internal_affairs/redundant_source_range.rb +66 -0
- data/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +2 -0
- data/lib/rubocop/cop/internal_affairs.rb +3 -0
- data/lib/rubocop/cop/layout/array_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/block_end_newline.rb +7 -15
- data/lib/rubocop/cop/layout/class_structure.rb +44 -26
- data/lib/rubocop/cop/layout/closing_heredoc_indentation.rb +2 -3
- data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +2 -6
- data/lib/rubocop/cop/layout/comment_indentation.rb +3 -1
- data/lib/rubocop/cop/layout/dot_position.rb +1 -5
- data/lib/rubocop/cop/layout/empty_comment.rb +3 -3
- data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +42 -9
- data/lib/rubocop/cop/layout/empty_line_between_defs.rb +28 -5
- data/lib/rubocop/cop/layout/empty_lines.rb +1 -1
- data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +2 -0
- data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +2 -0
- data/lib/rubocop/cop/layout/end_alignment.rb +9 -1
- data/lib/rubocop/cop/layout/extra_spacing.rb +6 -1
- data/lib/rubocop/cop/layout/first_argument_indentation.rb +8 -3
- data/lib/rubocop/cop/layout/first_array_element_line_break.rb +25 -34
- data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +7 -19
- data/lib/rubocop/cop/layout/first_method_argument_line_break.rb +42 -52
- data/lib/rubocop/cop/layout/first_method_parameter_line_break.rb +38 -55
- data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +10 -4
- data/lib/rubocop/cop/layout/heredoc_indentation.rb +11 -11
- data/lib/rubocop/cop/layout/indentation_style.rb +5 -2
- data/lib/rubocop/cop/layout/indentation_width.rb +3 -3
- data/lib/rubocop/cop/layout/initial_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/leading_comment_space.rb +2 -2
- data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +18 -12
- data/lib/rubocop/cop/layout/line_continuation_spacing.rb +17 -13
- data/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb +2 -0
- data/lib/rubocop/cop/layout/multiline_array_line_breaks.rb +8 -27
- data/lib/rubocop/cop/layout/multiline_block_layout.rb +1 -1
- data/lib/rubocop/cop/layout/multiline_hash_key_line_breaks.rb +7 -26
- data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +4 -21
- data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +18 -3
- data/lib/rubocop/cop/layout/multiline_method_parameter_line_breaks.rb +6 -30
- data/lib/rubocop/cop/layout/redundant_line_break.rb +20 -11
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +2 -2
- 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_keyword.rb +2 -2
- data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +2 -2
- data/lib/rubocop/cop/layout/space_around_operators.rb +4 -2
- data/lib/rubocop/cop/layout/space_before_first_arg.rb +1 -1
- data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +2 -2
- data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +11 -13
- data/lib/rubocop/cop/layout/space_inside_block_braces.rb +3 -1
- data/lib/rubocop/cop/layout/space_inside_parens.rb +3 -3
- data/lib/rubocop/cop/layout/space_inside_percent_literal_delimiters.rb +1 -1
- data/lib/rubocop/cop/layout/space_inside_range_literal.rb +1 -1
- data/lib/rubocop/cop/layout/space_inside_reference_brackets.rb +4 -4
- data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +5 -4
- data/lib/rubocop/cop/layout/trailing_empty_lines.rb +5 -0
- data/lib/rubocop/cop/layout/trailing_whitespace.rb +6 -3
- data/lib/rubocop/cop/lint/ambiguous_block_association.rb +13 -1
- data/lib/rubocop/cop/lint/ambiguous_operator.rb +4 -0
- data/lib/rubocop/cop/lint/constant_resolution.rb +1 -1
- data/lib/rubocop/cop/lint/debugger.rb +22 -25
- data/lib/rubocop/cop/lint/deprecated_class_methods.rb +62 -112
- data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +1 -1
- data/lib/rubocop/cop/lint/duplicate_hash_key.rb +2 -1
- data/lib/rubocop/cop/lint/duplicate_match_pattern.rb +122 -0
- data/lib/rubocop/cop/lint/duplicate_methods.rb +2 -2
- data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +47 -22
- data/lib/rubocop/cop/lint/else_layout.rb +3 -7
- data/lib/rubocop/cop/lint/empty_block.rb +2 -2
- data/lib/rubocop/cop/lint/empty_conditional_body.rb +4 -2
- data/lib/rubocop/cop/lint/empty_interpolation.rb +1 -1
- data/lib/rubocop/cop/lint/erb_new_arguments.rb +3 -4
- data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +14 -7
- data/lib/rubocop/cop/lint/heredoc_method_call_position.rb +16 -18
- data/lib/rubocop/cop/lint/identity_comparison.rb +0 -1
- data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +1 -1
- data/lib/rubocop/cop/lint/incompatible_io_select_with_fiber_scheduler.rb +5 -3
- data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +1 -1
- data/lib/rubocop/cop/lint/inherit_exception.rb +9 -0
- data/lib/rubocop/cop/lint/lambda_without_literal_block.rb +1 -1
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +47 -5
- data/lib/rubocop/cop/lint/missing_super.rb +63 -5
- data/lib/rubocop/cop/lint/mixed_case_range.rb +111 -0
- data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +1 -0
- data/lib/rubocop/cop/lint/nested_method_definition.rb +4 -9
- data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +10 -7
- data/lib/rubocop/cop/lint/number_conversion.rb +5 -0
- data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +2 -2
- data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +2 -0
- data/lib/rubocop/cop/lint/ordered_magic_comments.rb +0 -1
- data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +16 -1
- data/lib/rubocop/cop/lint/percent_string_array.rb +1 -1
- data/lib/rubocop/cop/lint/percent_symbol_array.rb +1 -1
- data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +11 -5
- data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +5 -5
- data/lib/rubocop/cop/lint/redundant_regexp_quantifiers.rb +130 -0
- data/lib/rubocop/cop/lint/redundant_require_statement.rb +21 -2
- data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +20 -4
- data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +1 -1
- data/lib/rubocop/cop/lint/redundant_string_coercion.rb +35 -15
- data/lib/rubocop/cop/lint/redundant_with_index.rb +1 -1
- data/lib/rubocop/cop/lint/redundant_with_object.rb +1 -1
- data/lib/rubocop/cop/lint/refinement_import_methods.rb +2 -1
- data/lib/rubocop/cop/lint/regexp_as_condition.rb +6 -0
- data/lib/rubocop/cop/lint/require_parentheses.rb +3 -1
- data/lib/rubocop/cop/lint/rescue_type.rb +3 -3
- data/lib/rubocop/cop/lint/safe_navigation_chain.rb +11 -4
- data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +1 -1
- data/lib/rubocop/cop/lint/script_permission.rb +1 -1
- data/lib/rubocop/cop/lint/send_with_mixin_argument.rb +1 -2
- data/lib/rubocop/cop/lint/shadowed_exception.rb +6 -12
- 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 +1 -1
- data/lib/rubocop/cop/lint/syntax.rb +4 -0
- data/lib/rubocop/cop/lint/to_enum_arguments.rb +18 -6
- data/lib/rubocop/cop/lint/top_level_return_with_argument.rb +23 -9
- data/lib/rubocop/cop/lint/unreachable_loop.rb +3 -3
- data/lib/rubocop/cop/lint/unused_method_argument.rb +2 -1
- data/lib/rubocop/cop/lint/useless_access_modifier.rb +10 -7
- data/lib/rubocop/cop/lint/useless_assignment.rb +94 -10
- data/lib/rubocop/cop/lint/useless_method_definition.rb +12 -4
- data/lib/rubocop/cop/lint/useless_rescue.rb +89 -0
- data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +14 -4
- data/lib/rubocop/cop/lint/useless_times.rb +1 -1
- data/lib/rubocop/cop/lint/void.rb +79 -16
- data/lib/rubocop/cop/metrics/block_length.rb +2 -2
- data/lib/rubocop/cop/metrics/block_nesting.rb +2 -2
- data/lib/rubocop/cop/metrics/class_length.rb +3 -2
- data/lib/rubocop/cop/metrics/collection_literal_length.rb +76 -0
- data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +1 -1
- data/lib/rubocop/cop/metrics/method_length.rb +1 -1
- data/lib/rubocop/cop/metrics/parameter_lists.rb +27 -0
- data/lib/rubocop/cop/metrics/perceived_complexity.rb +1 -1
- data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +4 -8
- data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +33 -5
- data/lib/rubocop/cop/migration/department_name.rb +3 -3
- data/lib/rubocop/cop/mixin/alignment.rb +1 -1
- data/lib/rubocop/cop/mixin/allowed_methods.rb +3 -1
- data/lib/rubocop/cop/mixin/allowed_receivers.rb +34 -0
- data/lib/rubocop/cop/mixin/annotation_comment.rb +2 -2
- data/lib/rubocop/cop/mixin/code_length.rb +1 -1
- data/lib/rubocop/cop/mixin/comments_help.rb +13 -7
- data/lib/rubocop/cop/mixin/def_node.rb +1 -1
- data/lib/rubocop/cop/mixin/documentation_comment.rb +1 -1
- data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +1 -1
- data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +1 -1
- data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +62 -23
- data/lib/rubocop/cop/mixin/hash_transform_method.rb +3 -3
- data/lib/rubocop/cop/mixin/heredoc.rb +6 -2
- data/lib/rubocop/cop/mixin/line_length_help.rb +3 -1
- data/lib/rubocop/cop/mixin/min_branches_count.rb +40 -0
- data/lib/rubocop/cop/mixin/multiline_element_line_breaks.rb +0 -3
- data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +3 -2
- data/lib/rubocop/cop/mixin/ordered_gem_node.rb +1 -1
- 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/range_help.rb +1 -6
- data/lib/rubocop/cop/mixin/space_after_punctuation.rb +1 -1
- data/lib/rubocop/cop/mixin/statement_modifier.rb +4 -3
- data/lib/rubocop/cop/mixin/string_help.rb +4 -2
- data/lib/rubocop/cop/mixin/surrounding_space.rb +3 -3
- data/lib/rubocop/cop/mixin/trailing_comma.rb +3 -3
- data/lib/rubocop/cop/naming/ascii_identifiers.rb +1 -1
- data/lib/rubocop/cop/naming/block_forwarding.rb +5 -1
- data/lib/rubocop/cop/naming/class_and_module_camel_case.rb +1 -1
- data/lib/rubocop/cop/naming/constant_name.rb +1 -1
- data/lib/rubocop/cop/naming/file_name.rb +1 -1
- data/lib/rubocop/cop/naming/heredoc_delimiter_case.rb +1 -1
- data/lib/rubocop/cop/naming/heredoc_delimiter_naming.rb +3 -1
- data/lib/rubocop/cop/naming/inclusive_language.rb +23 -4
- data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +25 -10
- data/lib/rubocop/cop/naming/method_name.rb +3 -3
- data/lib/rubocop/cop/naming/predicate_name.rb +1 -1
- data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +12 -4
- data/lib/rubocop/cop/naming/variable_name.rb +6 -1
- data/lib/rubocop/cop/registry.rb +37 -30
- data/lib/rubocop/cop/security/compound_hash.rb +2 -1
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +26 -11
- data/lib/rubocop/cop/style/accessor_grouping.rb +43 -17
- data/lib/rubocop/cop/style/alias.rb +9 -8
- data/lib/rubocop/cop/style/arguments_forwarding.rb +280 -62
- data/lib/rubocop/cop/style/array_intersect.rb +14 -6
- data/lib/rubocop/cop/style/ascii_comments.rb +1 -1
- data/lib/rubocop/cop/style/attr.rb +11 -1
- data/lib/rubocop/cop/style/begin_block.rb +1 -2
- data/lib/rubocop/cop/style/bisected_attr_accessor.rb +1 -1
- data/lib/rubocop/cop/style/block_comments.rb +3 -3
- data/lib/rubocop/cop/style/block_delimiters.rb +22 -6
- data/lib/rubocop/cop/style/case_like_if.rb +20 -3
- data/lib/rubocop/cop/style/class_and_module_children.rb +5 -12
- data/lib/rubocop/cop/style/class_equality_comparison.rb +58 -40
- data/lib/rubocop/cop/style/collection_compact.rb +20 -7
- 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 +30 -8
- data/lib/rubocop/cop/style/command_literal.rb +1 -1
- data/lib/rubocop/cop/style/comment_annotation.rb +1 -1
- data/lib/rubocop/cop/style/commented_keyword.rb +2 -2
- data/lib/rubocop/cop/style/comparable_clamp.rb +125 -0
- data/lib/rubocop/cop/style/concat_array_literals.rb +32 -4
- data/lib/rubocop/cop/style/conditional_assignment.rb +11 -15
- data/lib/rubocop/cop/style/copyright.rb +6 -3
- data/lib/rubocop/cop/style/data_inheritance.rb +75 -0
- data/lib/rubocop/cop/style/dir.rb +1 -1
- data/lib/rubocop/cop/style/dir_empty.rb +54 -0
- data/lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb +2 -2
- data/lib/rubocop/cop/style/document_dynamic_eval_definition.rb +3 -3
- data/lib/rubocop/cop/style/documentation.rb +12 -6
- data/lib/rubocop/cop/style/documentation_method.rb +10 -4
- data/lib/rubocop/cop/style/double_negation.rb +2 -2
- data/lib/rubocop/cop/style/each_with_object.rb +1 -1
- data/lib/rubocop/cop/style/empty_block_parameter.rb +1 -1
- data/lib/rubocop/cop/style/empty_case_condition.rb +6 -1
- data/lib/rubocop/cop/style/empty_lambda_parameter.rb +1 -1
- data/lib/rubocop/cop/style/eval_with_location.rb +8 -8
- data/lib/rubocop/cop/style/exact_regexp_match.rb +68 -0
- data/lib/rubocop/cop/style/explicit_block_argument.rb +1 -1
- data/lib/rubocop/cop/style/file_empty.rb +71 -0
- data/lib/rubocop/cop/style/file_read.rb +3 -3
- data/lib/rubocop/cop/style/file_write.rb +1 -1
- data/lib/rubocop/cop/style/for.rb +1 -1
- data/lib/rubocop/cop/style/format_string.rb +24 -3
- data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +4 -2
- data/lib/rubocop/cop/style/guard_clause.rb +40 -8
- data/lib/rubocop/cop/style/hash_conversion.rb +10 -0
- data/lib/rubocop/cop/style/hash_each_methods.rb +1 -10
- data/lib/rubocop/cop/style/hash_except.rb +23 -12
- data/lib/rubocop/cop/style/hash_like_case.rb +3 -9
- data/lib/rubocop/cop/style/hash_syntax.rb +16 -9
- 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 +36 -3
- data/lib/rubocop/cop/style/if_inside_else.rb +6 -0
- data/lib/rubocop/cop/style/if_unless_modifier.rb +111 -15
- data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +2 -0
- data/lib/rubocop/cop/style/if_with_semicolon.rb +2 -2
- data/lib/rubocop/cop/style/infinite_loop.rb +2 -5
- data/lib/rubocop/cop/style/inverse_methods.rb +5 -5
- data/lib/rubocop/cop/style/invertible_unless_condition.rb +118 -0
- 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 +2 -2
- data/lib/rubocop/cop/style/map_to_hash.rb +4 -1
- data/lib/rubocop/cop/style/map_to_set.rb +64 -0
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +35 -24
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +44 -37
- data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +2 -0
- data/lib/rubocop/cop/style/method_def_parentheses.rb +11 -4
- data/lib/rubocop/cop/style/min_max.rb +3 -3
- data/lib/rubocop/cop/style/min_max_comparison.rb +83 -0
- data/lib/rubocop/cop/style/missing_else.rb +13 -1
- data/lib/rubocop/cop/style/mixin_grouping.rb +5 -5
- data/lib/rubocop/cop/style/multiline_block_chain.rb +1 -1
- data/lib/rubocop/cop/style/multiline_if_modifier.rb +0 -4
- data/lib/rubocop/cop/style/multiline_memoization.rb +2 -2
- data/lib/rubocop/cop/style/multiline_method_signature.rb +7 -4
- data/lib/rubocop/cop/style/multiline_ternary_operator.rb +19 -4
- data/lib/rubocop/cop/style/multiple_comparison.rb +14 -0
- data/lib/rubocop/cop/style/negated_if_else_condition.rb +13 -12
- data/lib/rubocop/cop/style/nested_ternary_operator.rb +3 -11
- data/lib/rubocop/cop/style/nil_lambda.rb +2 -2
- data/lib/rubocop/cop/style/numbered_parameters_limit.rb +11 -3
- data/lib/rubocop/cop/style/numeric_literals.rb +1 -1
- data/lib/rubocop/cop/style/one_line_conditional.rb +3 -6
- data/lib/rubocop/cop/style/open_struct_use.rb +1 -1
- data/lib/rubocop/cop/style/operator_method_call.rb +22 -2
- data/lib/rubocop/cop/style/parallel_assignment.rb +29 -19
- data/lib/rubocop/cop/style/percent_literal_delimiters.rb +2 -3
- data/lib/rubocop/cop/style/percent_q_literals.rb +1 -1
- data/lib/rubocop/cop/style/preferred_hash_methods.rb +1 -1
- data/lib/rubocop/cop/style/redundant_argument.rb +6 -1
- data/lib/rubocop/cop/style/redundant_array_constructor.rb +77 -0
- data/lib/rubocop/cop/style/redundant_begin.rb +10 -2
- data/lib/rubocop/cop/style/redundant_condition.rb +18 -3
- data/lib/rubocop/cop/style/redundant_conditional.rb +2 -14
- data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +38 -0
- data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +96 -9
- data/lib/rubocop/cop/style/redundant_exception.rb +32 -12
- data/lib/rubocop/cop/style/redundant_fetch_block.rb +6 -4
- data/lib/rubocop/cop/style/redundant_filter_chain.rb +117 -0
- data/lib/rubocop/cop/style/redundant_heredoc_delimiter_quotes.rb +58 -0
- data/lib/rubocop/cop/style/redundant_interpolation.rb +2 -2
- data/lib/rubocop/cop/style/redundant_line_continuation.rb +183 -0
- data/lib/rubocop/cop/style/redundant_parentheses.rb +26 -8
- data/lib/rubocop/cop/style/redundant_percent_q.rb +1 -1
- data/lib/rubocop/cop/style/redundant_regexp_argument.rb +100 -0
- data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +7 -8
- data/lib/rubocop/cop/style/redundant_regexp_constructor.rb +46 -0
- data/lib/rubocop/cop/style/redundant_regexp_escape.rb +13 -4
- data/lib/rubocop/cop/style/redundant_return.rb +7 -2
- data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +8 -1
- data/lib/rubocop/cop/style/redundant_sort.rb +4 -4
- data/lib/rubocop/cop/style/redundant_string_escape.rb +9 -6
- data/lib/rubocop/cop/style/regexp_literal.rb +11 -2
- data/lib/rubocop/cop/style/require_order.rb +16 -17
- data/lib/rubocop/cop/style/rescue_modifier.rb +1 -3
- data/lib/rubocop/cop/style/rescue_standard_error.rb +2 -2
- 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/safe_navigation.rb +2 -2
- data/lib/rubocop/cop/style/select_by_regexp.rb +20 -6
- data/lib/rubocop/cop/style/self_assignment.rb +2 -2
- data/lib/rubocop/cop/style/semicolon.rb +35 -5
- data/lib/rubocop/cop/style/signal_exception.rb +9 -7
- data/lib/rubocop/cop/style/single_line_do_end_block.rb +65 -0
- data/lib/rubocop/cop/style/single_line_methods.rb +1 -1
- data/lib/rubocop/cop/style/slicing_with_range.rb +1 -1
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +9 -5
- data/lib/rubocop/cop/style/special_global_vars.rb +3 -4
- data/lib/rubocop/cop/style/stderr_puts.rb +1 -1
- data/lib/rubocop/cop/style/string_hash_keys.rb +4 -1
- data/lib/rubocop/cop/style/string_literals_in_interpolation.rb +30 -5
- data/lib/rubocop/cop/style/struct_inheritance.rb +1 -1
- data/lib/rubocop/cop/style/symbol_array.rb +35 -15
- data/lib/rubocop/cop/style/trailing_body_on_class.rb +1 -0
- data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +4 -4
- data/lib/rubocop/cop/style/trailing_underscore_variable.rb +1 -1
- data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
- data/lib/rubocop/cop/style/unless_logical_operators.rb +1 -0
- data/lib/rubocop/cop/style/unpack_first.rb +3 -3
- data/lib/rubocop/cop/style/word_array.rb +54 -1
- data/lib/rubocop/cop/style/yaml_file_read.rb +66 -0
- data/lib/rubocop/cop/style/yoda_condition.rb +17 -8
- data/lib/rubocop/cop/style/yoda_expression.rb +91 -0
- data/lib/rubocop/cop/style/zero_length_predicate.rb +40 -19
- data/lib/rubocop/cop/team.rb +60 -52
- data/lib/rubocop/cop/util.rb +14 -5
- 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/scope.rb +3 -3
- data/lib/rubocop/cop/variable_force/variable.rb +5 -3
- data/lib/rubocop/cop/variable_force/variable_table.rb +5 -3
- data/lib/rubocop/cop/variable_force.rb +2 -4
- data/lib/rubocop/cops_documentation_generator.rb +11 -4
- data/lib/rubocop/directive_comment.rb +3 -3
- data/lib/rubocop/ext/comment.rb +18 -0
- data/lib/rubocop/ext/regexp_node.rb +1 -1
- data/lib/rubocop/ext/regexp_parser.rb +5 -2
- data/lib/rubocop/file_finder.rb +4 -7
- data/lib/rubocop/formatter/junit_formatter.rb +4 -1
- data/lib/rubocop/formatter/simple_text_formatter.rb +1 -1
- data/lib/rubocop/formatter.rb +0 -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 +68 -0
- data/lib/rubocop/lsp/severity.rb +27 -0
- data/lib/rubocop/magic_comment.rb +12 -10
- data/lib/rubocop/options.rb +37 -3
- data/lib/rubocop/path_util.rb +17 -7
- data/lib/rubocop/result_cache.rb +7 -3
- data/lib/rubocop/rspec/cop_helper.rb +2 -2
- data/lib/rubocop/rspec/expect_offense.rb +6 -4
- data/lib/rubocop/rspec/shared_contexts.rb +6 -3
- data/lib/rubocop/rspec/support.rb +1 -0
- data/lib/rubocop/runner.rb +55 -10
- data/lib/rubocop/server/cache.rb +12 -4
- data/lib/rubocop/server/cli.rb +37 -18
- data/lib/rubocop/server/client_command/exec.rb +4 -3
- data/lib/rubocop/server/client_command/start.rb +6 -1
- data/lib/rubocop/server/core.rb +24 -9
- data/lib/rubocop/server/helper.rb +1 -1
- data/lib/rubocop/server/server_command/exec.rb +1 -1
- data/lib/rubocop/string_interpreter.rb +3 -3
- data/lib/rubocop/target_finder.rb +7 -3
- data/lib/rubocop/target_ruby.rb +13 -9
- data/lib/rubocop/version.rb +10 -6
- data/lib/rubocop.rb +31 -0
- metadata +84 -37
@@ -0,0 +1,91 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Style
|
6
|
+
# Forbids Yoda expressions, i.e. binary operations (using `*`, `+`, `&`, `|`,
|
7
|
+
# and `^` operators) where the order of expression is reversed, eg. `1 + x`.
|
8
|
+
# This cop complements `Style/YodaCondition` cop, which has a similar purpose.
|
9
|
+
#
|
10
|
+
# This cop is disabled by default to respect user intentions such as:
|
11
|
+
#
|
12
|
+
# [source,ruby]
|
13
|
+
# ----
|
14
|
+
# config.server_port = 9000 + ENV["TEST_ENV_NUMBER"].to_i
|
15
|
+
# ----
|
16
|
+
#
|
17
|
+
# @safety
|
18
|
+
# This cop is unsafe because binary operators can be defined
|
19
|
+
# differently on different classes, and are not guaranteed to
|
20
|
+
# have the same result if reversed.
|
21
|
+
#
|
22
|
+
# @example SupportedOperators: ['*', '+', '&', '|', '^'] (default)
|
23
|
+
# # bad
|
24
|
+
# 10 * y
|
25
|
+
# 1 + x
|
26
|
+
# 1 & z
|
27
|
+
# 1 | x
|
28
|
+
# 1 ^ x
|
29
|
+
# 1 + CONST
|
30
|
+
#
|
31
|
+
# # good
|
32
|
+
# y * 10
|
33
|
+
# x + 1
|
34
|
+
# z & 1
|
35
|
+
# x | 1
|
36
|
+
# x ^ 1
|
37
|
+
# CONST + 1
|
38
|
+
# 60 * 24
|
39
|
+
#
|
40
|
+
class YodaExpression < Base
|
41
|
+
extend AutoCorrector
|
42
|
+
|
43
|
+
MSG = 'Non-literal operand (`%<source>s`) should be first.'
|
44
|
+
|
45
|
+
RESTRICT_ON_SEND = %i[* + & | ^].freeze
|
46
|
+
|
47
|
+
def on_new_investigation
|
48
|
+
@offended_nodes = nil
|
49
|
+
end
|
50
|
+
|
51
|
+
def on_send(node)
|
52
|
+
return unless supported_operators.include?(node.method_name.to_s)
|
53
|
+
|
54
|
+
lhs = node.receiver
|
55
|
+
rhs = node.first_argument
|
56
|
+
return unless yoda_expression_constant?(lhs, rhs)
|
57
|
+
return if offended_ancestor?(node)
|
58
|
+
|
59
|
+
message = format(MSG, source: rhs.source)
|
60
|
+
add_offense(node, message: message) do |corrector|
|
61
|
+
corrector.swap(lhs, rhs)
|
62
|
+
end
|
63
|
+
|
64
|
+
offended_nodes.add(node)
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
def yoda_expression_constant?(lhs, rhs)
|
70
|
+
constant_portion?(lhs) && !constant_portion?(rhs)
|
71
|
+
end
|
72
|
+
|
73
|
+
def constant_portion?(node)
|
74
|
+
node.numeric_type? || node.const_type?
|
75
|
+
end
|
76
|
+
|
77
|
+
def supported_operators
|
78
|
+
Array(cop_config['SupportedOperators'])
|
79
|
+
end
|
80
|
+
|
81
|
+
def offended_ancestor?(node)
|
82
|
+
node.each_ancestor(:send).any? { |ancestor| @offended_nodes&.include?(ancestor) }
|
83
|
+
end
|
84
|
+
|
85
|
+
def offended_nodes
|
86
|
+
@offended_nodes ||= Set.new.compare_by_identity
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -4,10 +4,13 @@ module RuboCop
|
|
4
4
|
module Cop
|
5
5
|
module Style
|
6
6
|
# Checks for numeric comparisons that can be replaced
|
7
|
-
# by a predicate method, such as receiver.length == 0
|
8
|
-
# receiver.length > 0
|
9
|
-
# receiver.length < 1 and receiver.size == 0 that can be
|
10
|
-
# replaced by receiver.empty
|
7
|
+
# by a predicate method, such as `receiver.length == 0`,
|
8
|
+
# `receiver.length > 0`, and `receiver.length != 0`,
|
9
|
+
# `receiver.length < 1` and `receiver.size == 0` that can be
|
10
|
+
# replaced by `receiver.empty?` and `!receiver.empty?`.
|
11
|
+
#
|
12
|
+
# NOTE: `File`, `Tempfile`, and `StringIO` do not have `empty?`
|
13
|
+
# so allow `size == 0` and `size.zero?`.
|
11
14
|
#
|
12
15
|
# @safety
|
13
16
|
# This cop is unsafe because it cannot be guaranteed that the receiver
|
@@ -34,43 +37,56 @@ module RuboCop
|
|
34
37
|
class ZeroLengthPredicate < Base
|
35
38
|
extend AutoCorrector
|
36
39
|
|
37
|
-
ZERO_MSG = 'Use `empty?` instead of `%<
|
38
|
-
NONZERO_MSG = 'Use `!empty?` instead of `%<
|
40
|
+
ZERO_MSG = 'Use `empty?` instead of `%<current>s`.'
|
41
|
+
NONZERO_MSG = 'Use `!empty?` instead of `%<current>s`.'
|
39
42
|
|
40
43
|
RESTRICT_ON_SEND = %i[size length].freeze
|
41
44
|
|
42
45
|
def on_send(node)
|
43
46
|
check_zero_length_predicate(node)
|
44
|
-
|
47
|
+
check_zero_length_comparison(node)
|
48
|
+
check_nonzero_length_comparison(node)
|
45
49
|
end
|
46
50
|
|
47
51
|
private
|
48
52
|
|
49
53
|
def check_zero_length_predicate(node)
|
50
|
-
|
51
|
-
return
|
54
|
+
return unless (length_method = zero_length_predicate(node.parent))
|
55
|
+
return if non_polymorphic_collection?(node.parent)
|
56
|
+
|
57
|
+
offense = node.loc.selector.join(node.parent.source_range.end)
|
58
|
+
message = format(ZERO_MSG, current: "#{length_method}.zero?")
|
52
59
|
|
53
|
-
|
60
|
+
add_offense(offense, message: message) do |corrector|
|
61
|
+
corrector.replace(offense, 'empty?')
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def check_zero_length_comparison(node)
|
66
|
+
zero_length_comparison = zero_length_comparison(node.parent)
|
67
|
+
return unless zero_length_comparison
|
68
|
+
|
69
|
+
lhs, opr, rhs = zero_length_comparison
|
54
70
|
|
55
71
|
return if non_polymorphic_collection?(node.parent)
|
56
72
|
|
57
73
|
add_offense(
|
58
|
-
node.parent, message: format(ZERO_MSG,
|
74
|
+
node.parent, message: format(ZERO_MSG, current: "#{lhs} #{opr} #{rhs}")
|
59
75
|
) do |corrector|
|
60
76
|
corrector.replace(node.parent, replacement(node.parent))
|
61
77
|
end
|
62
78
|
end
|
63
79
|
|
64
|
-
def
|
65
|
-
|
66
|
-
return unless
|
80
|
+
def check_nonzero_length_comparison(node)
|
81
|
+
nonzero_length_comparison = nonzero_length_comparison(node.parent)
|
82
|
+
return unless nonzero_length_comparison
|
67
83
|
|
68
|
-
lhs, opr, rhs =
|
84
|
+
lhs, opr, rhs = nonzero_length_comparison
|
69
85
|
|
70
86
|
return if non_polymorphic_collection?(node.parent)
|
71
87
|
|
72
88
|
add_offense(
|
73
|
-
node.parent, message: format(NONZERO_MSG,
|
89
|
+
node.parent, message: format(NONZERO_MSG, current: "#{lhs} #{opr} #{rhs}")
|
74
90
|
) do |corrector|
|
75
91
|
corrector.replace(node.parent, replacement(node.parent))
|
76
92
|
end
|
@@ -78,14 +94,19 @@ module RuboCop
|
|
78
94
|
|
79
95
|
# @!method zero_length_predicate(node)
|
80
96
|
def_node_matcher :zero_length_predicate, <<~PATTERN
|
97
|
+
(send (send (...) ${:length :size}) :zero?)
|
98
|
+
PATTERN
|
99
|
+
|
100
|
+
# @!method zero_length_comparison(node)
|
101
|
+
def_node_matcher :zero_length_comparison, <<~PATTERN
|
81
102
|
{(send (send (...) ${:length :size}) $:== (int $0))
|
82
103
|
(send (int $0) $:== (send (...) ${:length :size}))
|
83
104
|
(send (send (...) ${:length :size}) $:< (int $1))
|
84
105
|
(send (int $1) $:> (send (...) ${:length :size}))}
|
85
106
|
PATTERN
|
86
107
|
|
87
|
-
# @!method
|
88
|
-
def_node_matcher :
|
108
|
+
# @!method nonzero_length_comparison(node)
|
109
|
+
def_node_matcher :nonzero_length_comparison, <<~PATTERN
|
89
110
|
{(send (send (...) ${:length :size}) ${:> :!=} (int $0))
|
90
111
|
(send (int $0) ${:< :!=} (send (...) ${:length :size}))}
|
91
112
|
PATTERN
|
@@ -117,7 +138,7 @@ module RuboCop
|
|
117
138
|
# @!method non_polymorphic_collection?(node)
|
118
139
|
def_node_matcher :non_polymorphic_collection?, <<~PATTERN
|
119
140
|
{(send (send (send (const {nil? cbase} :File) :stat _) ...) ...)
|
120
|
-
(send (send (send (const {nil? cbase} {:Tempfile :StringIO}) {:new :open} ...) ...) ...)}
|
141
|
+
(send (send (send (const {nil? cbase} {:File :Tempfile :StringIO}) {:new :open} ...) ...) ...)}
|
121
142
|
PATTERN
|
122
143
|
end
|
123
144
|
end
|
data/lib/rubocop/cop/team.rb
CHANGED
@@ -10,20 +10,6 @@ module RuboCop
|
|
10
10
|
# first the ones needed for autocorrection (if any), then the rest
|
11
11
|
# (unless autocorrections happened).
|
12
12
|
class Team
|
13
|
-
attr_reader :errors, :warnings, :updated_source_file, :cops
|
14
|
-
|
15
|
-
alias updated_source_file? updated_source_file
|
16
|
-
|
17
|
-
def initialize(cops, config = nil, options = {})
|
18
|
-
@cops = cops
|
19
|
-
@config = config
|
20
|
-
@options = options
|
21
|
-
reset
|
22
|
-
@ready = true
|
23
|
-
|
24
|
-
validate_config
|
25
|
-
end
|
26
|
-
|
27
13
|
# @return [Team]
|
28
14
|
def self.new(cop_or_classes, config, options = {})
|
29
15
|
# Support v0 api:
|
@@ -42,11 +28,41 @@ module RuboCop
|
|
42
28
|
def self.mobilize_cops(cop_classes, config, options = {})
|
43
29
|
cop_classes = Registry.new(cop_classes.to_a, options) unless cop_classes.is_a?(Registry)
|
44
30
|
|
45
|
-
cop_classes.
|
31
|
+
cop_classes.map do |cop_class|
|
46
32
|
cop_class.new(config, options)
|
47
33
|
end
|
48
34
|
end
|
49
35
|
|
36
|
+
# @return [Array<Force>] needed for the given cops
|
37
|
+
def self.forces_for(cops)
|
38
|
+
needed = Hash.new { |h, k| h[k] = [] }
|
39
|
+
cops.each do |cop|
|
40
|
+
forces = cop.class.joining_forces
|
41
|
+
if forces.is_a?(Array)
|
42
|
+
forces.each { |force| needed[force] << cop }
|
43
|
+
elsif forces
|
44
|
+
needed[forces] << cop
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
needed.map { |force_class, joining_cops| force_class.new(joining_cops) }
|
49
|
+
end
|
50
|
+
|
51
|
+
attr_reader :errors, :warnings, :updated_source_file, :cops
|
52
|
+
|
53
|
+
alias updated_source_file? updated_source_file
|
54
|
+
|
55
|
+
def initialize(cops, config = nil, options = {})
|
56
|
+
@cops = cops
|
57
|
+
@config = config
|
58
|
+
@options = options
|
59
|
+
reset
|
60
|
+
@ready = true
|
61
|
+
@registry = Registry.new(cops, options.dup)
|
62
|
+
|
63
|
+
validate_config
|
64
|
+
end
|
65
|
+
|
50
66
|
def autocorrect?
|
51
67
|
@options[:autocorrect]
|
52
68
|
end
|
@@ -62,24 +78,25 @@ module RuboCop
|
|
62
78
|
end
|
63
79
|
|
64
80
|
# @return [Commissioner::InvestigationReport]
|
65
|
-
def investigate(processed_source)
|
81
|
+
def investigate(processed_source, offset: 0, original: processed_source)
|
66
82
|
be_ready
|
67
83
|
|
68
84
|
# The autocorrection process may have to be repeated multiple times
|
69
85
|
# until there are no corrections left to perform
|
70
86
|
# To speed things up, run autocorrecting cops by themselves, and only
|
71
87
|
# run the other cops when no corrections are left
|
72
|
-
on_duty = roundup_relevant_cops(processed_source
|
88
|
+
on_duty = roundup_relevant_cops(processed_source)
|
73
89
|
|
74
90
|
autocorrect_cops, other_cops = on_duty.partition(&:autocorrect?)
|
91
|
+
report = investigate_partial(autocorrect_cops, processed_source,
|
92
|
+
offset: offset, original: original)
|
75
93
|
|
76
|
-
report
|
77
|
-
|
78
|
-
unless autocorrect(processed_source, report)
|
94
|
+
unless autocorrect(processed_source, report, offset: offset, original: original)
|
79
95
|
# If we corrected some errors, another round of inspection will be
|
80
96
|
# done, and any other offenses will be caught then, so only need
|
81
97
|
# to check other_cops if no correction was done
|
82
|
-
report = report.merge(investigate_partial(other_cops, processed_source
|
98
|
+
report = report.merge(investigate_partial(other_cops, processed_source,
|
99
|
+
offset: offset, original: original))
|
83
100
|
end
|
84
101
|
|
85
102
|
process_errors(processed_source.path, report.errors)
|
@@ -94,34 +111,19 @@ module RuboCop
|
|
94
111
|
@forces ||= self.class.forces_for(cops)
|
95
112
|
end
|
96
113
|
|
97
|
-
# @return [Array<Force>] needed for the given cops
|
98
|
-
def self.forces_for(cops)
|
99
|
-
needed = Hash.new { |h, k| h[k] = [] }
|
100
|
-
cops.each do |cop|
|
101
|
-
forces = cop.class.joining_forces
|
102
|
-
if forces.is_a?(Array)
|
103
|
-
forces.each { |force| needed[force] << cop }
|
104
|
-
elsif forces
|
105
|
-
needed[forces] << cop
|
106
|
-
end
|
107
|
-
end
|
108
|
-
|
109
|
-
needed.map { |force_class, joining_cops| force_class.new(joining_cops) }
|
110
|
-
end
|
111
|
-
|
112
114
|
def external_dependency_checksum
|
113
|
-
keys = cops.
|
115
|
+
keys = cops.filter_map(&:external_dependency_checksum)
|
114
116
|
Digest::SHA1.hexdigest(keys.join)
|
115
117
|
end
|
116
118
|
|
117
119
|
private
|
118
120
|
|
119
|
-
def autocorrect(processed_source, report)
|
121
|
+
def autocorrect(processed_source, report, original:, offset:)
|
120
122
|
@updated_source_file = false
|
121
123
|
return unless autocorrect?
|
122
124
|
return if report.processed_source.parser_error
|
123
125
|
|
124
|
-
new_source = autocorrect_report(report)
|
126
|
+
new_source = autocorrect_report(report, original: original, offset: offset)
|
125
127
|
|
126
128
|
return unless new_source
|
127
129
|
|
@@ -129,7 +131,7 @@ module RuboCop
|
|
129
131
|
# holds source read in from stdin, when --stdin option is used
|
130
132
|
@options[:stdin] = new_source
|
131
133
|
else
|
132
|
-
filename = processed_source.
|
134
|
+
filename = processed_source.file_path
|
133
135
|
File.write(filename, new_source)
|
134
136
|
end
|
135
137
|
@updated_source_file = true
|
@@ -149,17 +151,19 @@ module RuboCop
|
|
149
151
|
end
|
150
152
|
|
151
153
|
# @return [Commissioner::InvestigationReport]
|
152
|
-
def investigate_partial(cops, processed_source)
|
154
|
+
def investigate_partial(cops, processed_source, offset:, original:)
|
153
155
|
commissioner = Commissioner.new(cops, self.class.forces_for(cops), @options)
|
154
|
-
commissioner.investigate(processed_source)
|
156
|
+
commissioner.investigate(processed_source, offset: offset, original: original)
|
155
157
|
end
|
156
158
|
|
157
159
|
# @return [Array<cop>]
|
158
|
-
def roundup_relevant_cops(
|
159
|
-
cops.
|
160
|
-
|
161
|
-
|
162
|
-
|
160
|
+
def roundup_relevant_cops(processed_source)
|
161
|
+
cops.select do |cop|
|
162
|
+
next true if processed_source.comment_config.cop_opted_in?(cop)
|
163
|
+
next false if cop.excluded_file?(processed_source.file_path)
|
164
|
+
next false unless @registry.enabled?(cop, @config)
|
165
|
+
|
166
|
+
support_target_ruby_version?(cop) && support_target_rails_version?(cop)
|
163
167
|
end
|
164
168
|
end
|
165
169
|
|
@@ -175,18 +179,22 @@ module RuboCop
|
|
175
179
|
cop.class.support_target_rails_version?(cop.target_rails_version)
|
176
180
|
end
|
177
181
|
|
178
|
-
def autocorrect_report(report)
|
179
|
-
corrector = collate_corrections(report)
|
182
|
+
def autocorrect_report(report, offset:, original:)
|
183
|
+
corrector = collate_corrections(report, offset: offset, original: original)
|
180
184
|
|
181
185
|
corrector.rewrite unless corrector.empty?
|
182
186
|
end
|
183
187
|
|
184
|
-
def collate_corrections(report)
|
185
|
-
corrector = Corrector.new(
|
188
|
+
def collate_corrections(report, offset:, original:)
|
189
|
+
corrector = Corrector.new(original)
|
186
190
|
|
187
191
|
each_corrector(report) do |to_merge|
|
188
192
|
suppress_clobbering do
|
189
|
-
|
193
|
+
if offset.positive?
|
194
|
+
corrector.import!(to_merge, offset: offset)
|
195
|
+
else
|
196
|
+
corrector.merge!(to_merge)
|
197
|
+
end
|
190
198
|
end
|
191
199
|
end
|
192
200
|
|
data/lib/rubocop/cop/util.rb
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
# This module contains a collection of useful utility methods.
|
6
|
+
# rubocop:disable Metrics/ModuleLength
|
6
7
|
module Util
|
7
8
|
include PathUtil
|
8
9
|
|
@@ -80,7 +81,7 @@ module RuboCop
|
|
80
81
|
end
|
81
82
|
|
82
83
|
def args_end(node)
|
83
|
-
node.
|
84
|
+
node.source_range.end
|
84
85
|
end
|
85
86
|
|
86
87
|
def on_node(syms, sexp, excludes = [], &block)
|
@@ -92,13 +93,20 @@ module RuboCop
|
|
92
93
|
sexp.each_child_node { |elem| on_node(syms, elem, excludes, &block) }
|
93
94
|
end
|
94
95
|
|
96
|
+
# Arbitrarily chosen value, should be enough to cover
|
97
|
+
# the most nested source code in real world projects.
|
98
|
+
MAX_LINE_BEGINS_REGEX_INDEX = 50
|
95
99
|
LINE_BEGINS_REGEX_CACHE = Hash.new do |hash, index|
|
96
|
-
hash[index] = /^\s{#{index}}\S/
|
100
|
+
hash[index] = /^\s{#{index}}\S/ if index <= MAX_LINE_BEGINS_REGEX_INDEX
|
97
101
|
end
|
98
|
-
private_constant :LINE_BEGINS_REGEX_CACHE
|
102
|
+
private_constant :MAX_LINE_BEGINS_REGEX_INDEX, :LINE_BEGINS_REGEX_CACHE
|
99
103
|
|
100
104
|
def begins_its_line?(range)
|
101
|
-
|
105
|
+
if (regex = LINE_BEGINS_REGEX_CACHE[range.column])
|
106
|
+
range.source_line.match?(regex)
|
107
|
+
else
|
108
|
+
range.source_line.index(/\S/) == range.column
|
109
|
+
end
|
102
110
|
end
|
103
111
|
|
104
112
|
# Returns, for example, a bare `if` node if the given node is an `if`
|
@@ -134,7 +142,7 @@ module RuboCop
|
|
134
142
|
end
|
135
143
|
|
136
144
|
def escape_string(string)
|
137
|
-
string.inspect[1..-2].tap { |s| s.gsub!(
|
145
|
+
string.inspect[1..-2].tap { |s| s.gsub!('\\"', '"') }
|
138
146
|
end
|
139
147
|
|
140
148
|
def to_string_literal(string)
|
@@ -190,5 +198,6 @@ module RuboCop
|
|
190
198
|
source == target || (source.is_a?(Array) && source.include?(target))
|
191
199
|
end
|
192
200
|
end
|
201
|
+
# rubocop:enable Metrics/ModuleLength
|
193
202
|
end
|
194
203
|
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Utils
|
6
|
+
# Helper to abstract complexity of building range pairs
|
7
|
+
# with octal escape reconstruction (needed for regexp_parser < 2.7).
|
8
|
+
class RegexpRanges
|
9
|
+
attr_reader :root
|
10
|
+
|
11
|
+
def initialize(root)
|
12
|
+
@root = root
|
13
|
+
@compound_token = []
|
14
|
+
@pairs = []
|
15
|
+
@populated = false
|
16
|
+
end
|
17
|
+
|
18
|
+
def compound_token
|
19
|
+
populate_all unless @populated
|
20
|
+
|
21
|
+
@compound_token
|
22
|
+
end
|
23
|
+
|
24
|
+
def pairs
|
25
|
+
populate_all unless @populated
|
26
|
+
|
27
|
+
@pairs
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def populate_all
|
33
|
+
populate(@root)
|
34
|
+
|
35
|
+
# If either bound is a compound the first one is an escape
|
36
|
+
# and that's all we need to work with.
|
37
|
+
# If there are any cops that wanted to operate on the compound
|
38
|
+
# expression we could wrap it with a facade class.
|
39
|
+
@pairs.map! { |pair| pair.map(&:first) }
|
40
|
+
|
41
|
+
@populated = true
|
42
|
+
end
|
43
|
+
|
44
|
+
def populate(expr)
|
45
|
+
expressions = expr.expressions.to_a
|
46
|
+
|
47
|
+
until expressions.empty?
|
48
|
+
current = expressions.shift
|
49
|
+
|
50
|
+
if escaped_octal?(current)
|
51
|
+
@compound_token << current
|
52
|
+
@compound_token.concat(pop_octal_digits(expressions))
|
53
|
+
# If we have all the digits we can discard.
|
54
|
+
end
|
55
|
+
|
56
|
+
next unless current.type == :set
|
57
|
+
|
58
|
+
process_set(expressions, current)
|
59
|
+
@compound_token.clear
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def process_set(expressions, current)
|
64
|
+
case current.token
|
65
|
+
when :range
|
66
|
+
@pairs << compose_range(expressions, current)
|
67
|
+
when :character
|
68
|
+
# Child expressions may include the range we are looking for.
|
69
|
+
populate(current)
|
70
|
+
when :intersection
|
71
|
+
# Each child expression could have child expressions that lead to ranges.
|
72
|
+
current.expressions.each do |intersected|
|
73
|
+
populate(intersected)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def compose_range(expressions, current)
|
79
|
+
range_start, range_end = current.expressions
|
80
|
+
range_start = if @compound_token.size.between?(1, 2) && octal_digit?(range_start.text)
|
81
|
+
@compound_token.dup << range_start
|
82
|
+
else
|
83
|
+
[range_start]
|
84
|
+
end
|
85
|
+
range_end = [range_end]
|
86
|
+
range_end.concat(pop_octal_digits(expressions)) if escaped_octal?(range_end.first)
|
87
|
+
[range_start, range_end]
|
88
|
+
end
|
89
|
+
|
90
|
+
def escaped_octal?(expr)
|
91
|
+
expr.text =~ /^\\[0-7]$/
|
92
|
+
end
|
93
|
+
|
94
|
+
def octal_digit?(char)
|
95
|
+
('0'..'7').cover?(char)
|
96
|
+
end
|
97
|
+
|
98
|
+
def pop_octal_digits(expressions)
|
99
|
+
digits = []
|
100
|
+
|
101
|
+
2.times do
|
102
|
+
next unless (next_child = expressions.first)
|
103
|
+
next unless next_child.type == :literal && next_child.text =~ /^[0-7]$/
|
104
|
+
|
105
|
+
digits << expressions.shift
|
106
|
+
end
|
107
|
+
|
108
|
+
digits
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
@@ -47,6 +47,10 @@ module RuboCop
|
|
47
47
|
@node.type == REGEXP_NAMED_CAPTURE_TYPE
|
48
48
|
end
|
49
49
|
|
50
|
+
def exception_assignment?
|
51
|
+
node.parent&.resbody_type? && node.parent.exception_variable == node
|
52
|
+
end
|
53
|
+
|
50
54
|
def operator_assignment?
|
51
55
|
return false unless meta_assignment_node
|
52
56
|
|
@@ -59,6 +63,18 @@ module RuboCop
|
|
59
63
|
meta_assignment_node.type == MULTIPLE_ASSIGNMENT_TYPE
|
60
64
|
end
|
61
65
|
|
66
|
+
def rest_assignment?
|
67
|
+
return false unless meta_assignment_node
|
68
|
+
|
69
|
+
meta_assignment_node.type == REST_ASSIGNMENT_TYPE
|
70
|
+
end
|
71
|
+
|
72
|
+
def for_assignment?
|
73
|
+
return false unless meta_assignment_node
|
74
|
+
|
75
|
+
meta_assignment_node.for_type?
|
76
|
+
end
|
77
|
+
|
62
78
|
def operator
|
63
79
|
assignment_node = meta_assignment_node || @node
|
64
80
|
assignment_node.loc.operator.source
|
@@ -66,7 +82,10 @@ module RuboCop
|
|
66
82
|
|
67
83
|
def meta_assignment_node
|
68
84
|
unless instance_variable_defined?(:@meta_assignment_node)
|
69
|
-
@meta_assignment_node = operator_assignment_node ||
|
85
|
+
@meta_assignment_node = operator_assignment_node ||
|
86
|
+
multiple_assignment_node ||
|
87
|
+
rest_assignment_node ||
|
88
|
+
for_assignment_node
|
70
89
|
end
|
71
90
|
|
72
91
|
@meta_assignment_node
|
@@ -83,13 +102,35 @@ module RuboCop
|
|
83
102
|
end
|
84
103
|
|
85
104
|
def multiple_assignment_node
|
86
|
-
grandparent_node = node.parent&.parent
|
87
|
-
|
105
|
+
return nil unless (grandparent_node = node.parent&.parent)
|
106
|
+
if (node = find_multiple_assignment_node(grandparent_node))
|
107
|
+
return node
|
108
|
+
end
|
88
109
|
return nil unless grandparent_node.type == MULTIPLE_ASSIGNMENT_TYPE
|
89
|
-
return nil unless node.parent.type == MULTIPLE_LEFT_HAND_SIDE_TYPE
|
90
110
|
|
91
111
|
grandparent_node
|
92
112
|
end
|
113
|
+
|
114
|
+
def rest_assignment_node
|
115
|
+
return nil unless node.parent
|
116
|
+
return nil unless node.parent.type == REST_ASSIGNMENT_TYPE
|
117
|
+
|
118
|
+
node.parent
|
119
|
+
end
|
120
|
+
|
121
|
+
def for_assignment_node
|
122
|
+
node.ancestors.find(&:for_type?)
|
123
|
+
end
|
124
|
+
|
125
|
+
def find_multiple_assignment_node(grandparent_node)
|
126
|
+
return unless grandparent_node.type == MULTIPLE_LEFT_HAND_SIDE_TYPE
|
127
|
+
return if grandparent_node.children.any?(&:splat_type?)
|
128
|
+
|
129
|
+
parent = grandparent_node.parent
|
130
|
+
return parent if parent.type == MULTIPLE_ASSIGNMENT_TYPE
|
131
|
+
|
132
|
+
find_multiple_assignment_node(parent)
|
133
|
+
end
|
93
134
|
end
|
94
135
|
end
|
95
136
|
end
|
@@ -45,9 +45,9 @@ module RuboCop
|
|
45
45
|
node
|
46
46
|
else
|
47
47
|
child_index = case node.type
|
48
|
-
when :module, :sclass
|
49
|
-
when :def, :class, :block then 2
|
50
|
-
when :defs
|
48
|
+
when :module, :sclass then 1
|
49
|
+
when :def, :class, :block, :numblock then 2
|
50
|
+
when :defs then 3
|
51
51
|
end
|
52
52
|
|
53
53
|
node.children[child_index]
|
@@ -52,7 +52,7 @@ module RuboCop
|
|
52
52
|
# if/unless keyword. A preceding assignment is needed to put the
|
53
53
|
# variable in scope. For this reason we skip to the next assignment
|
54
54
|
# here.
|
55
|
-
next if
|
55
|
+
next if in_modifier_conditional?(assignment)
|
56
56
|
|
57
57
|
break if !assignment.branch || assignment.branch == reference.branch
|
58
58
|
|
@@ -63,10 +63,12 @@ module RuboCop
|
|
63
63
|
end
|
64
64
|
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
65
65
|
|
66
|
-
def
|
66
|
+
def in_modifier_conditional?(assignment)
|
67
67
|
parent = assignment.node.parent
|
68
68
|
parent = parent.parent if parent&.begin_type?
|
69
|
-
|
69
|
+
return false if parent.nil?
|
70
|
+
|
71
|
+
(parent.if_type? || parent.while_type? || parent.until_type?) && parent.modifier_form?
|
70
72
|
end
|
71
73
|
|
72
74
|
def capture_with_block!
|