rubocop 1.69.0 → 1.76.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 +22 -16
- data/config/default.yml +234 -47
- data/config/internal_affairs.yml +20 -0
- data/config/obsoletion.yml +8 -3
- data/lib/rubocop/cli/command/execute_runner.rb +3 -3
- data/lib/rubocop/cli/command/show_cops.rb +24 -2
- data/lib/rubocop/cli/command/suggest_extensions.rb +7 -1
- data/lib/rubocop/cli.rb +1 -1
- data/lib/rubocop/comment_config.rb +2 -2
- data/lib/rubocop/config.rb +52 -10
- data/lib/rubocop/config_loader.rb +52 -9
- data/lib/rubocop/config_loader_resolver.rb +36 -10
- data/lib/rubocop/config_obsoletion/extracted_cop.rb +4 -3
- data/lib/rubocop/config_obsoletion/renamed_cop.rb +18 -3
- data/lib/rubocop/config_obsoletion.rb +46 -2
- data/lib/rubocop/config_validator.rb +25 -14
- data/lib/rubocop/cop/autocorrect_logic.rb +44 -39
- data/lib/rubocop/cop/base.rb +6 -0
- data/lib/rubocop/cop/bundler/duplicated_gem.rb +2 -2
- data/lib/rubocop/cop/bundler/gem_comment.rb +1 -1
- data/lib/rubocop/cop/bundler/ordered_gems.rb +1 -1
- data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +50 -6
- data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +1 -1
- data/lib/rubocop/cop/generator.rb +6 -0
- data/lib/rubocop/cop/internal_affairs/cop_enabled.rb +85 -0
- data/lib/rubocop/cop/internal_affairs/example_description.rb +8 -4
- data/lib/rubocop/cop/internal_affairs/location_exists.rb +116 -0
- data/lib/rubocop/cop/internal_affairs/location_expression.rb +2 -1
- data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +1 -0
- data/lib/rubocop/cop/internal_affairs/node_first_or_last_argument.rb +3 -2
- data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_processor.rb +63 -0
- data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_walker.rb +131 -0
- data/lib/rubocop/cop/internal_affairs/node_pattern_groups.rb +231 -0
- data/lib/rubocop/cop/internal_affairs/node_type_group.rb +91 -0
- data/lib/rubocop/cop/internal_affairs/node_type_multiple_predicates.rb +126 -0
- data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +4 -3
- data/lib/rubocop/cop/internal_affairs/on_send_without_on_csend.rb +90 -0
- data/lib/rubocop/cop/internal_affairs/operator_keyword.rb +4 -2
- data/lib/rubocop/cop/internal_affairs/plugin.rb +33 -0
- data/lib/rubocop/cop/internal_affairs/redundant_described_class_as_subject.rb +6 -5
- data/lib/rubocop/cop/internal_affairs/redundant_source_range.rb +3 -1
- data/lib/rubocop/cop/internal_affairs/single_line_comparison.rb +5 -4
- data/lib/rubocop/cop/internal_affairs/undefined_config.rb +13 -2
- data/lib/rubocop/cop/internal_affairs.rb +6 -16
- data/lib/rubocop/cop/layout/access_modifier_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/argument_alignment.rb +2 -8
- data/lib/rubocop/cop/layout/block_alignment.rb +3 -1
- data/lib/rubocop/cop/layout/block_end_newline.rb +1 -0
- data/lib/rubocop/cop/layout/class_structure.rb +44 -9
- data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +4 -4
- data/lib/rubocop/cop/layout/def_end_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/dot_position.rb +1 -1
- data/lib/rubocop/cop/layout/else_alignment.rb +2 -2
- data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +2 -2
- data/lib/rubocop/cop/layout/empty_line_between_defs.rb +7 -11
- data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +34 -3
- data/lib/rubocop/cop/layout/empty_lines_around_begin_body.rb +5 -6
- data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +1 -0
- data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +1 -1
- data/lib/rubocop/cop/layout/empty_lines_around_method_body.rb +22 -2
- data/lib/rubocop/cop/layout/end_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/extra_spacing.rb +1 -1
- data/lib/rubocop/cop/layout/first_argument_indentation.rb +4 -9
- data/lib/rubocop/cop/layout/first_array_element_indentation.rb +2 -7
- data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +2 -7
- data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +1 -1
- data/lib/rubocop/cop/layout/first_parameter_indentation.rb +2 -2
- data/lib/rubocop/cop/layout/hash_alignment.rb +8 -6
- data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +2 -1
- data/lib/rubocop/cop/layout/indentation_width.rb +1 -0
- data/lib/rubocop/cop/layout/leading_comment_space.rb +13 -1
- data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +11 -2
- data/lib/rubocop/cop/layout/line_continuation_spacing.rb +7 -1
- data/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb +2 -2
- data/lib/rubocop/cop/layout/line_length.rb +9 -4
- data/lib/rubocop/cop/layout/multiline_block_layout.rb +1 -0
- data/lib/rubocop/cop/layout/multiline_hash_key_line_breaks.rb +1 -1
- data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +25 -0
- data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +1 -0
- data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +4 -4
- data/lib/rubocop/cop/layout/multiline_method_parameter_line_breaks.rb +1 -0
- data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/redundant_line_break.rb +16 -11
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +3 -5
- data/lib/rubocop/cop/layout/single_line_block_chain.rb +1 -1
- data/lib/rubocop/cop/layout/space_after_colon.rb +2 -2
- data/lib/rubocop/cop/layout/space_after_comma.rb +1 -1
- data/lib/rubocop/cop/layout/space_after_method_name.rb +1 -1
- data/lib/rubocop/cop/layout/space_after_semicolon.rb +11 -1
- data/lib/rubocop/cop/layout/space_around_keyword.rb +1 -0
- data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +1 -1
- data/lib/rubocop/cop/layout/space_around_operators.rb +7 -4
- data/lib/rubocop/cop/layout/space_before_block_braces.rb +1 -0
- data/lib/rubocop/cop/layout/space_before_brackets.rb +6 -32
- data/lib/rubocop/cop/layout/space_before_comma.rb +1 -1
- data/lib/rubocop/cop/layout/space_before_semicolon.rb +1 -1
- data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +5 -1
- data/lib/rubocop/cop/layout/space_inside_block_braces.rb +1 -0
- data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +3 -0
- data/lib/rubocop/cop/layout/trailing_whitespace.rb +5 -3
- data/lib/rubocop/cop/lint/ambiguous_block_association.rb +1 -1
- data/lib/rubocop/cop/lint/array_literal_in_regexp.rb +118 -0
- data/lib/rubocop/cop/lint/assignment_in_condition.rb +1 -3
- data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +2 -3
- data/lib/rubocop/cop/lint/boolean_symbol.rb +1 -1
- data/lib/rubocop/cop/lint/circular_argument_reference.rb +4 -3
- data/lib/rubocop/cop/lint/constant_definition_in_block.rb +3 -3
- data/lib/rubocop/cop/lint/constant_reassignment.rb +148 -0
- data/lib/rubocop/cop/lint/cop_directive_syntax.rb +84 -0
- data/lib/rubocop/cop/lint/debugger.rb +3 -3
- data/lib/rubocop/cop/lint/deprecated_class_methods.rb +1 -1
- data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +2 -1
- data/lib/rubocop/cop/lint/duplicate_match_pattern.rb +1 -1
- data/lib/rubocop/cop/lint/duplicate_methods.rb +86 -19
- data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +1 -1
- data/lib/rubocop/cop/lint/duplicate_set_element.rb +20 -7
- data/lib/rubocop/cop/lint/empty_conditional_body.rb +14 -64
- data/lib/rubocop/cop/lint/empty_expression.rb +0 -2
- data/lib/rubocop/cop/lint/empty_interpolation.rb +3 -1
- data/lib/rubocop/cop/lint/erb_new_arguments.rb +0 -6
- data/lib/rubocop/cop/lint/float_comparison.rb +33 -8
- data/lib/rubocop/cop/lint/float_out_of_range.rb +1 -1
- data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +2 -2
- data/lib/rubocop/cop/lint/identity_comparison.rb +19 -15
- data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +1 -1
- data/lib/rubocop/cop/lint/literal_as_condition.rb +110 -9
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +24 -6
- data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +1 -1
- data/lib/rubocop/cop/lint/missing_super.rb +2 -2
- data/lib/rubocop/cop/lint/mixed_case_range.rb +3 -3
- data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +1 -1
- data/lib/rubocop/cop/lint/nested_method_definition.rb +9 -5
- data/lib/rubocop/cop/lint/next_without_accumulator.rb +1 -1
- data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +4 -2
- data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +3 -3
- data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +3 -3
- data/lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +18 -31
- data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +1 -1
- data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +2 -1
- data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +1 -5
- data/lib/rubocop/cop/lint/raise_exception.rb +29 -10
- data/lib/rubocop/cop/lint/redundant_regexp_quantifiers.rb +1 -1
- data/lib/rubocop/cop/lint/redundant_require_statement.rb +0 -21
- data/lib/rubocop/cop/lint/redundant_string_coercion.rb +2 -2
- data/lib/rubocop/cop/lint/redundant_type_conversion.rb +261 -0
- data/lib/rubocop/cop/lint/redundant_with_index.rb +3 -0
- data/lib/rubocop/cop/lint/redundant_with_object.rb +3 -0
- data/lib/rubocop/cop/lint/refinement_import_methods.rb +1 -1
- data/lib/rubocop/cop/lint/rescue_exception.rb +1 -1
- data/lib/rubocop/cop/lint/return_in_void_context.rb +9 -11
- data/lib/rubocop/cop/lint/safe_navigation_chain.rb +8 -1
- data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +13 -1
- data/lib/rubocop/cop/lint/shared_mutable_default.rb +76 -0
- data/lib/rubocop/cop/lint/suppressed_exception.rb +1 -1
- data/lib/rubocop/cop/lint/suppressed_exception_in_number_conversion.rb +111 -0
- data/lib/rubocop/cop/lint/symbol_conversion.rb +1 -1
- data/lib/rubocop/cop/lint/syntax.rb +4 -1
- data/lib/rubocop/cop/lint/to_enum_arguments.rb +1 -1
- data/lib/rubocop/cop/lint/top_level_return_with_argument.rb +1 -1
- data/lib/rubocop/cop/lint/unescaped_bracket_in_regexp.rb +1 -1
- data/lib/rubocop/cop/lint/unexpected_block_arity.rb +3 -1
- data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +1 -1
- data/lib/rubocop/cop/lint/unreachable_code.rb +52 -2
- data/lib/rubocop/cop/lint/unreachable_loop.rb +6 -6
- data/lib/rubocop/cop/lint/useless_access_modifier.rb +5 -4
- data/lib/rubocop/cop/lint/useless_assignment.rb +3 -1
- data/lib/rubocop/cop/lint/useless_constant_scoping.rb +71 -0
- data/lib/rubocop/cop/lint/useless_default_value_argument.rb +87 -0
- data/lib/rubocop/cop/lint/useless_else_without_rescue.rb +4 -0
- data/lib/rubocop/cop/lint/useless_method_definition.rb +1 -1
- data/lib/rubocop/cop/lint/useless_numeric_operation.rb +2 -1
- data/lib/rubocop/cop/lint/useless_or.rb +98 -0
- data/lib/rubocop/cop/lint/useless_rescue.rb +1 -1
- data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +2 -2
- data/lib/rubocop/cop/lint/void.rb +14 -11
- data/lib/rubocop/cop/message_annotator.rb +7 -3
- data/lib/rubocop/cop/metrics/abc_size.rb +1 -1
- data/lib/rubocop/cop/metrics/block_length.rb +1 -0
- data/lib/rubocop/cop/metrics/block_nesting.rb +1 -1
- data/lib/rubocop/cop/metrics/class_length.rb +9 -9
- data/lib/rubocop/cop/metrics/collection_literal_length.rb +7 -0
- data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +1 -1
- data/lib/rubocop/cop/metrics/method_length.rb +9 -1
- data/lib/rubocop/cop/metrics/module_length.rb +1 -1
- data/lib/rubocop/cop/metrics/perceived_complexity.rb +1 -1
- data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +2 -2
- data/lib/rubocop/cop/metrics/utils/repeated_attribute_discount.rb +7 -7
- data/lib/rubocop/cop/mixin/alignment.rb +2 -2
- data/lib/rubocop/cop/mixin/allowed_pattern.rb +4 -4
- data/lib/rubocop/cop/mixin/check_line_breakable.rb +13 -13
- data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +2 -2
- data/lib/rubocop/cop/mixin/comments_help.rb +8 -3
- data/lib/rubocop/cop/mixin/def_node.rb +1 -1
- data/lib/rubocop/cop/mixin/dig_help.rb +1 -1
- data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +1 -1
- data/lib/rubocop/cop/mixin/forbidden_identifiers.rb +20 -0
- data/lib/rubocop/cop/mixin/forbidden_pattern.rb +16 -0
- data/lib/rubocop/cop/mixin/frozen_string_literal.rb +0 -1
- data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +15 -14
- data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +22 -22
- data/lib/rubocop/cop/mixin/hash_subset.rb +203 -0
- data/lib/rubocop/cop/mixin/hash_transform_method.rb +74 -74
- data/lib/rubocop/cop/mixin/line_length_help.rb +5 -4
- data/lib/rubocop/cop/mixin/method_complexity.rb +2 -1
- data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +2 -0
- 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 +68 -30
- data/lib/rubocop/cop/mixin/range_help.rb +15 -3
- data/lib/rubocop/cop/mixin/space_before_punctuation.rb +1 -1
- data/lib/rubocop/cop/mixin/statement_modifier.rb +8 -3
- data/lib/rubocop/cop/mixin/string_help.rb +2 -2
- data/lib/rubocop/cop/mixin/string_literals_help.rb +1 -1
- data/lib/rubocop/cop/mixin/target_ruby_version.rb +1 -1
- data/lib/rubocop/cop/mixin/trailing_comma.rb +21 -5
- data/lib/rubocop/cop/naming/accessor_method_name.rb +6 -6
- data/lib/rubocop/cop/naming/block_forwarding.rb +19 -15
- data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +1 -1
- data/lib/rubocop/cop/naming/method_name.rb +64 -8
- data/lib/rubocop/cop/naming/predicate_method.rb +216 -0
- data/lib/rubocop/cop/naming/{predicate_name.rb → predicate_prefix.rb} +46 -2
- data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +4 -4
- data/lib/rubocop/cop/naming/variable_name.rb +51 -6
- data/lib/rubocop/cop/registry.rb +9 -6
- data/lib/rubocop/cop/security/compound_hash.rb +2 -0
- data/lib/rubocop/cop/security/yaml_load.rb +3 -2
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +66 -15
- data/lib/rubocop/cop/style/accessor_grouping.rb +19 -5
- data/lib/rubocop/cop/style/and_or.rb +1 -1
- data/lib/rubocop/cop/style/arguments_forwarding.rb +47 -28
- data/lib/rubocop/cop/style/array_first_last.rb +18 -2
- data/lib/rubocop/cop/style/array_intersect.rb +39 -28
- data/lib/rubocop/cop/style/block_delimiters.rb +26 -23
- data/lib/rubocop/cop/style/class_and_module_children.rb +52 -11
- data/lib/rubocop/cop/style/class_equality_comparison.rb +1 -1
- data/lib/rubocop/cop/style/collection_methods.rb +2 -1
- data/lib/rubocop/cop/style/combinable_defined.rb +1 -1
- data/lib/rubocop/cop/style/combinable_loops.rb +3 -2
- data/lib/rubocop/cop/style/command_literal.rb +1 -1
- data/lib/rubocop/cop/style/commented_keyword.rb +12 -5
- data/lib/rubocop/cop/style/comparable_between.rb +78 -0
- data/lib/rubocop/cop/style/concat_array_literals.rb +1 -1
- data/lib/rubocop/cop/style/conditional_assignment.rb +20 -6
- data/lib/rubocop/cop/style/data_inheritance.rb +7 -0
- data/lib/rubocop/cop/style/def_with_parentheses.rb +18 -5
- data/lib/rubocop/cop/style/dig_chain.rb +5 -6
- data/lib/rubocop/cop/style/documentation.rb +1 -1
- data/lib/rubocop/cop/style/double_negation.rb +4 -4
- data/lib/rubocop/cop/style/each_for_simple_loop.rb +4 -7
- data/lib/rubocop/cop/style/each_with_object.rb +2 -3
- data/lib/rubocop/cop/style/empty_else.rb +4 -2
- data/lib/rubocop/cop/style/empty_literal.rb +5 -1
- data/lib/rubocop/cop/style/empty_method.rb +1 -1
- data/lib/rubocop/cop/style/empty_string_inside_interpolation.rb +100 -0
- data/lib/rubocop/cop/style/endless_method.rb +163 -18
- data/lib/rubocop/cop/style/eval_with_location.rb +4 -4
- data/lib/rubocop/cop/style/exact_regexp_match.rb +2 -3
- data/lib/rubocop/cop/style/expand_path_arguments.rb +2 -7
- data/lib/rubocop/cop/style/explicit_block_argument.rb +16 -3
- data/lib/rubocop/cop/style/exponential_notation.rb +3 -3
- data/lib/rubocop/cop/style/fetch_env_var.rb +2 -1
- data/lib/rubocop/cop/style/file_null.rb +20 -4
- data/lib/rubocop/cop/style/float_division.rb +8 -4
- data/lib/rubocop/cop/style/for.rb +1 -0
- data/lib/rubocop/cop/style/format_string_token.rb +38 -11
- data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +3 -2
- data/lib/rubocop/cop/style/global_std_stream.rb +3 -0
- data/lib/rubocop/cop/style/guard_clause.rb +2 -1
- data/lib/rubocop/cop/style/hash_each_methods.rb +6 -8
- data/lib/rubocop/cop/style/hash_except.rb +35 -147
- data/lib/rubocop/cop/style/hash_fetch_chain.rb +104 -0
- data/lib/rubocop/cop/style/hash_slice.rb +80 -0
- data/lib/rubocop/cop/style/hash_syntax.rb +9 -3
- 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 +25 -6
- data/lib/rubocop/cop/style/if_inside_else.rb +10 -13
- data/lib/rubocop/cop/style/if_unless_modifier.rb +25 -7
- data/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +4 -7
- data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +2 -2
- data/lib/rubocop/cop/style/if_with_semicolon.rb +7 -5
- data/lib/rubocop/cop/style/infinite_loop.rb +1 -1
- data/lib/rubocop/cop/style/inverse_methods.rb +15 -11
- data/lib/rubocop/cop/style/invertible_unless_condition.rb +2 -2
- data/lib/rubocop/cop/style/ip_addresses.rb +2 -2
- data/lib/rubocop/cop/style/it_assignment.rb +36 -0
- data/lib/rubocop/cop/style/it_block_parameter.rb +119 -0
- data/lib/rubocop/cop/style/keyword_parameters_order.rb +14 -8
- data/lib/rubocop/cop/style/lambda.rb +1 -0
- data/lib/rubocop/cop/style/lambda_call.rb +10 -3
- data/lib/rubocop/cop/style/line_end_concatenation.rb +10 -4
- data/lib/rubocop/cop/style/map_into_array.rb +5 -2
- data/lib/rubocop/cop/style/map_to_hash.rb +12 -1
- data/lib/rubocop/cop/style/map_to_set.rb +3 -2
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +26 -16
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +2 -0
- data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +3 -2
- data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +3 -4
- data/lib/rubocop/cop/style/method_def_parentheses.rb +1 -1
- data/lib/rubocop/cop/style/missing_else.rb +2 -0
- data/lib/rubocop/cop/style/multiline_block_chain.rb +3 -2
- data/lib/rubocop/cop/style/multiline_if_modifier.rb +2 -0
- data/lib/rubocop/cop/style/multiline_method_signature.rb +1 -9
- data/lib/rubocop/cop/style/multiple_comparison.rb +34 -22
- data/lib/rubocop/cop/style/mutable_constant.rb +3 -3
- data/lib/rubocop/cop/style/negated_if_else_condition.rb +1 -1
- data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +1 -1
- data/lib/rubocop/cop/style/next.rb +44 -0
- data/lib/rubocop/cop/style/object_then.rb +15 -15
- data/lib/rubocop/cop/style/open_struct_use.rb +5 -5
- data/lib/rubocop/cop/style/parallel_assignment.rb +1 -5
- data/lib/rubocop/cop/style/parentheses_around_condition.rb +2 -2
- data/lib/rubocop/cop/style/percent_literal_delimiters.rb +1 -1
- data/lib/rubocop/cop/style/percent_q_literals.rb +1 -1
- data/lib/rubocop/cop/style/proc.rb +2 -2
- data/lib/rubocop/cop/style/quoted_symbols.rb +1 -1
- data/lib/rubocop/cop/style/raise_args.rb +14 -12
- data/lib/rubocop/cop/style/random_with_offset.rb +3 -3
- data/lib/rubocop/cop/style/redundant_argument.rb +3 -1
- data/lib/rubocop/cop/style/redundant_array_flatten.rb +50 -0
- data/lib/rubocop/cop/style/redundant_begin.rb +2 -1
- data/lib/rubocop/cop/style/redundant_condition.rb +59 -2
- data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +16 -5
- data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +6 -10
- data/lib/rubocop/cop/style/redundant_each.rb +1 -1
- data/lib/rubocop/cop/style/redundant_exception.rb +2 -2
- data/lib/rubocop/cop/style/redundant_format.rb +262 -0
- data/lib/rubocop/cop/style/redundant_freeze.rb +3 -3
- data/lib/rubocop/cop/style/redundant_initialize.rb +12 -3
- data/lib/rubocop/cop/style/redundant_line_continuation.rb +38 -21
- data/lib/rubocop/cop/style/redundant_parentheses.rb +61 -17
- data/lib/rubocop/cop/style/redundant_regexp_argument.rb +3 -0
- data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +1 -1
- data/lib/rubocop/cop/style/redundant_regexp_escape.rb +1 -1
- data/lib/rubocop/cop/style/redundant_self.rb +2 -1
- data/lib/rubocop/cop/style/redundant_self_assignment.rb +14 -28
- data/lib/rubocop/cop/style/redundant_sort.rb +2 -2
- data/lib/rubocop/cop/style/redundant_sort_by.rb +17 -1
- data/lib/rubocop/cop/style/redundant_string_escape.rb +2 -2
- data/lib/rubocop/cop/style/regexp_literal.rb +1 -1
- data/lib/rubocop/cop/style/rescue_modifier.rb +3 -0
- data/lib/rubocop/cop/style/return_nil.rb +2 -2
- data/lib/rubocop/cop/style/safe_navigation.rb +44 -16
- data/lib/rubocop/cop/style/select_by_regexp.rb +4 -1
- data/lib/rubocop/cop/style/semicolon.rb +1 -1
- data/lib/rubocop/cop/style/send_with_literal_method_name.rb +2 -1
- data/lib/rubocop/cop/style/single_line_block_params.rb +1 -1
- data/lib/rubocop/cop/style/single_line_do_end_block.rb +4 -3
- data/lib/rubocop/cop/style/single_line_methods.rb +6 -7
- data/lib/rubocop/cop/style/slicing_with_range.rb +40 -11
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +42 -105
- data/lib/rubocop/cop/style/string_concatenation.rb +15 -14
- data/lib/rubocop/cop/style/string_literals.rb +1 -1
- data/lib/rubocop/cop/style/string_methods.rb +1 -1
- data/lib/rubocop/cop/style/struct_inheritance.rb +8 -1
- data/lib/rubocop/cop/style/super_arguments.rb +66 -19
- data/lib/rubocop/cop/style/symbol_proc.rb +2 -0
- data/lib/rubocop/cop/style/ternary_parentheses.rb +1 -1
- data/lib/rubocop/cop/style/top_level_method_definition.rb +2 -1
- data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +11 -2
- data/lib/rubocop/cop/style/trailing_comma_in_array_literal.rb +47 -6
- data/lib/rubocop/cop/style/trailing_comma_in_hash_literal.rb +48 -6
- data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
- data/lib/rubocop/cop/style/while_until_modifier.rb +0 -1
- data/lib/rubocop/cop/style/yoda_condition.rb +8 -4
- data/lib/rubocop/cop/style/yoda_expression.rb +2 -1
- data/lib/rubocop/cop/team.rb +1 -1
- data/lib/rubocop/cop/util.rb +12 -5
- data/lib/rubocop/cop/utils/format_string.rb +10 -5
- data/lib/rubocop/cop/variable_force/assignment.rb +7 -3
- data/lib/rubocop/cop/variable_force/scope.rb +1 -1
- data/lib/rubocop/cop/variable_force/variable.rb +10 -3
- data/lib/rubocop/cop/variable_force/variable_table.rb +3 -3
- data/lib/rubocop/cop/variable_force.rb +1 -1
- data/lib/rubocop/cops_documentation_generator.rb +31 -16
- data/lib/rubocop/directive_comment.rb +45 -11
- data/lib/rubocop/ext/regexp_node.rb +0 -1
- data/lib/rubocop/formatter/disabled_config_formatter.rb +2 -1
- data/lib/rubocop/formatter/formatter_set.rb +1 -1
- data/lib/rubocop/formatter/html_formatter.rb +1 -1
- data/lib/rubocop/formatter/pacman_formatter.rb +1 -1
- data/lib/rubocop/lsp/diagnostic.rb +189 -0
- data/lib/rubocop/lsp/logger.rb +2 -2
- data/lib/rubocop/lsp/routes.rb +7 -23
- data/lib/rubocop/lsp/runtime.rb +18 -50
- data/lib/rubocop/lsp/server.rb +0 -2
- data/lib/rubocop/lsp/stdin_runner.rb +85 -0
- data/lib/rubocop/magic_comment.rb +11 -3
- data/lib/rubocop/options.rb +28 -12
- data/lib/rubocop/path_util.rb +15 -8
- data/lib/rubocop/plugin/configuration_integrator.rb +143 -0
- data/lib/rubocop/plugin/load_error.rb +26 -0
- data/lib/rubocop/plugin/loader.rb +100 -0
- data/lib/rubocop/plugin/not_supported_error.rb +29 -0
- data/lib/rubocop/plugin.rb +46 -0
- data/lib/rubocop/rake_task.rb +4 -1
- data/lib/rubocop/result_cache.rb +13 -13
- data/lib/rubocop/rspec/cop_helper.rb +13 -1
- data/lib/rubocop/rspec/expect_offense.rb +15 -5
- data/lib/rubocop/rspec/shared_contexts.rb +38 -1
- data/lib/rubocop/rspec/support.rb +4 -2
- data/lib/rubocop/runner.rb +10 -7
- data/lib/rubocop/server/cache.rb +47 -11
- data/lib/rubocop/server/cli.rb +2 -2
- data/lib/rubocop/target_finder.rb +7 -2
- data/lib/rubocop/target_ruby.rb +16 -1
- data/lib/rubocop/version.rb +30 -8
- data/lib/rubocop.rb +22 -2
- data/lib/ruby_lsp/rubocop/addon.rb +75 -0
- data/lib/ruby_lsp/rubocop/runtime_adapter.rb +65 -0
- metadata +67 -19
- data/lib/rubocop/cop/utils/regexp_ranges.rb +0 -113
- data/lib/rubocop/rspec/host_environment_simulation_helper.rb +0 -28
@@ -3,21 +3,22 @@
|
|
3
3
|
module RuboCop
|
4
4
|
# Handles validation of configuration, for example cop names, parameter
|
5
5
|
# names, and Ruby versions.
|
6
|
+
# rubocop:disable Metrics/ClassLength
|
6
7
|
class ConfigValidator
|
7
8
|
extend SimpleForwardable
|
8
9
|
|
9
10
|
# @api private
|
10
11
|
COMMON_PARAMS = %w[Exclude Include Severity inherit_mode AutoCorrect StyleGuide Details
|
11
|
-
Enabled].freeze
|
12
|
+
Enabled Reference References].freeze
|
12
13
|
# @api private
|
13
14
|
INTERNAL_PARAMS = %w[Description StyleGuide
|
14
15
|
VersionAdded VersionChanged VersionRemoved
|
15
|
-
Reference Safe SafeAutoCorrect].freeze
|
16
|
+
Reference References Safe SafeAutoCorrect].freeze
|
16
17
|
# @api private
|
17
18
|
NEW_COPS_VALUES = %w[pending disable enable].freeze
|
18
19
|
|
19
20
|
# @api private
|
20
|
-
CONFIG_CHECK_KEYS = %w[Enabled Safe SafeAutoCorrect AutoCorrect].to_set.freeze
|
21
|
+
CONFIG_CHECK_KEYS = %w[Enabled Safe SafeAutoCorrect AutoCorrect References].to_set.freeze
|
21
22
|
CONFIG_CHECK_DEPARTMENTS = %w[pending override_department].freeze
|
22
23
|
CONFIG_CHECK_AUTOCORRECTS = %w[always contextual disabled].freeze
|
23
24
|
private_constant :CONFIG_CHECK_KEYS, :CONFIG_CHECK_DEPARTMENTS
|
@@ -41,8 +42,9 @@ module RuboCop
|
|
41
42
|
ConfigLoader.default_configuration.key?(key)
|
42
43
|
end
|
43
44
|
|
44
|
-
|
45
|
+
validate_parameter_shape(valid_cop_names)
|
45
46
|
|
47
|
+
check_obsoletions
|
46
48
|
alert_about_unrecognized_cops(invalid_cop_names)
|
47
49
|
validate_new_cops_parameter
|
48
50
|
validate_parameter_names(valid_cop_names)
|
@@ -64,12 +66,6 @@ module RuboCop
|
|
64
66
|
target_ruby.version
|
65
67
|
end
|
66
68
|
|
67
|
-
def validate_section_presence(name)
|
68
|
-
return unless @config.key?(name) && @config[name].nil?
|
69
|
-
|
70
|
-
raise ValidationError, "empty section #{name} found in #{smart_loaded_path}"
|
71
|
-
end
|
72
|
-
|
73
69
|
private
|
74
70
|
|
75
71
|
attr_reader :target_ruby
|
@@ -122,6 +118,7 @@ module RuboCop
|
|
122
118
|
invalid_cop_names.each do |name|
|
123
119
|
# There could be a custom cop with this name. If so, don't warn
|
124
120
|
next if Cop::Registry.global.contains_cop_matching?([name])
|
121
|
+
next if ConfigObsoletion.deprecated_cop_name?(name)
|
125
122
|
|
126
123
|
# Special case for inherit_mode, which is a directive that we keep in
|
127
124
|
# the configuration (even though it's not a cop), because it's easier
|
@@ -177,9 +174,22 @@ module RuboCop
|
|
177
174
|
raise ValidationError, message
|
178
175
|
end
|
179
176
|
|
177
|
+
def validate_parameter_shape(valid_cop_names)
|
178
|
+
valid_cop_names.each do |name|
|
179
|
+
if @config[name].nil?
|
180
|
+
raise ValidationError, "empty section #{name.inspect} found in #{smart_loaded_path}"
|
181
|
+
elsif !@config[name].is_a?(Hash)
|
182
|
+
raise ValidationError, <<~MESSAGE
|
183
|
+
The configuration for #{name.inspect} in #{smart_loaded_path} is not a Hash.
|
184
|
+
|
185
|
+
Found: #{@config[name].inspect}
|
186
|
+
MESSAGE
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
180
191
|
def validate_parameter_names(valid_cop_names)
|
181
192
|
valid_cop_names.each do |name|
|
182
|
-
validate_section_presence(name)
|
183
193
|
each_invalid_parameter(name) do |param, supported_params|
|
184
194
|
warn Rainbow(<<~MESSAGE).yellow
|
185
195
|
Warning: #{name} does not support #{param} parameter.
|
@@ -250,8 +260,7 @@ module RuboCop
|
|
250
260
|
end
|
251
261
|
end
|
252
262
|
|
253
|
-
# rubocop:disable Metrics/
|
254
|
-
def check_cop_config_value(hash, parent = nil)
|
263
|
+
def check_cop_config_value(hash, parent = nil) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
255
264
|
hash.each do |key, value|
|
256
265
|
check_cop_config_value(value, key) if value.is_a?(Hash)
|
257
266
|
|
@@ -261,6 +270,8 @@ module RuboCop
|
|
261
270
|
supposed_values = 'a boolean'
|
262
271
|
elsif key == 'AutoCorrect' && !CONFIG_CHECK_AUTOCORRECTS.include?(value)
|
263
272
|
supposed_values = '`always`, `contextual`, `disabled`, or a boolean'
|
273
|
+
elsif key == 'References'
|
274
|
+
supposed_values = 'an array of strings'
|
264
275
|
else
|
265
276
|
next
|
266
277
|
end
|
@@ -268,7 +279,6 @@ module RuboCop
|
|
268
279
|
raise ValidationError, param_error_message(parent, key, value, supposed_values)
|
269
280
|
end
|
270
281
|
end
|
271
|
-
# rubocop:enable Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity
|
272
282
|
|
273
283
|
# FIXME: Handling colors in exception messages like this is ugly.
|
274
284
|
def param_error_message(parent, key, value, supposed_values)
|
@@ -277,4 +287,5 @@ module RuboCop
|
|
277
287
|
"is supposed to be #{supposed_values} and #{Rainbow(value).yellow} is not."
|
278
288
|
end
|
279
289
|
end
|
290
|
+
# rubocop:enable Metrics/ClassLength
|
280
291
|
end
|
@@ -49,67 +49,68 @@ module RuboCop
|
|
49
49
|
private
|
50
50
|
|
51
51
|
def disable_offense(offense_range)
|
52
|
-
|
53
|
-
|
54
|
-
|
52
|
+
unbreakable_range = multiline_ranges(offense_range)&.find do |range|
|
53
|
+
eol_comment_would_be_inside_literal?(offense_range, range)
|
54
|
+
end
|
55
55
|
|
56
|
-
if
|
57
|
-
disable_offense_before_and_after(range_by_lines(
|
56
|
+
if unbreakable_range
|
57
|
+
disable_offense_before_and_after(range_by_lines(unbreakable_range))
|
58
58
|
else
|
59
59
|
disable_offense_with_eol_or_surround_comment(offense_range)
|
60
60
|
end
|
61
61
|
end
|
62
62
|
|
63
|
-
def
|
64
|
-
|
65
|
-
needed_line_length = (range.source_line + eol_comment).length
|
63
|
+
def multiline_ranges(offense_range)
|
64
|
+
return if offense_range.empty?
|
66
65
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
66
|
+
processed_source.ast.each_node.filter_map do |node|
|
67
|
+
if surrounding_heredoc?(node)
|
68
|
+
heredoc_range(node)
|
69
|
+
elsif string_continuation?(node)
|
70
|
+
range_by_lines(node.source_range)
|
71
|
+
elsif surrounding_percent_array?(node) || multiline_string?(node)
|
72
|
+
node.source_range
|
73
|
+
end
|
71
74
|
end
|
72
75
|
end
|
73
76
|
|
74
|
-
def
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
node.respond_to?(:heredoc?) && node.heredoc?
|
77
|
+
def disable_offense_with_eol_or_surround_comment(range)
|
78
|
+
if line_with_eol_comment_too_long?(range)
|
79
|
+
disable_offense_before_and_after(range_by_lines(range))
|
80
|
+
else
|
81
|
+
disable_offense_at_end_of_line(range_of_first_line(range))
|
80
82
|
end
|
81
|
-
heredoc_nodes.map { |node| node.source_range.join(node.loc.heredoc_end) }
|
82
|
-
.find { |range| range.contains?(offense_range) }
|
83
83
|
end
|
84
84
|
|
85
|
-
def
|
86
|
-
return
|
85
|
+
def eol_comment_would_be_inside_literal?(offense_range, literal_range)
|
86
|
+
return true if line_with_eol_comment_too_long?(offense_range)
|
87
87
|
|
88
|
-
|
89
|
-
|
90
|
-
end
|
91
|
-
|
92
|
-
percent_array.map(&:source_range).find do |range|
|
93
|
-
range_overlaps_offense?(offense_range, range)
|
94
|
-
end
|
88
|
+
offense_line = offense_range.line
|
89
|
+
offense_line >= literal_range.first_line && offense_line < literal_range.last_line
|
95
90
|
end
|
96
91
|
|
97
|
-
def
|
98
|
-
|
92
|
+
def line_with_eol_comment_too_long?(range)
|
93
|
+
(range.source_line + eol_comment).length > max_line_length
|
94
|
+
end
|
99
95
|
|
100
|
-
|
101
|
-
|
102
|
-
|
96
|
+
def surrounding_heredoc?(node)
|
97
|
+
node.type?(:str, :dstr, :xstr) && node.heredoc?
|
98
|
+
end
|
103
99
|
|
104
|
-
|
100
|
+
def heredoc_range(node)
|
101
|
+
node.source_range.join(node.loc.heredoc_end)
|
105
102
|
end
|
106
103
|
|
107
|
-
def
|
108
|
-
|
104
|
+
def surrounding_percent_array?(node)
|
105
|
+
node.array_type? && node.percent_literal?
|
109
106
|
end
|
110
107
|
|
111
108
|
def string_continuation?(node)
|
112
|
-
|
109
|
+
node.type?(:str, :dstr, :xstr) && node.source.match?(/\\\s*$/)
|
110
|
+
end
|
111
|
+
|
112
|
+
def multiline_string?(node)
|
113
|
+
node.dstr_type? && node.multiline?
|
113
114
|
end
|
114
115
|
|
115
116
|
def range_of_first_line(range)
|
@@ -135,10 +136,14 @@ module RuboCop
|
|
135
136
|
config.for_cop('Layout/LineLength')['Max'] || 120
|
136
137
|
end
|
137
138
|
|
138
|
-
def disable_offense_at_end_of_line(range
|
139
|
+
def disable_offense_at_end_of_line(range)
|
139
140
|
Corrector.new(range).insert_after(range, eol_comment)
|
140
141
|
end
|
141
142
|
|
143
|
+
def eol_comment
|
144
|
+
" # rubocop:todo #{cop_name}"
|
145
|
+
end
|
146
|
+
|
142
147
|
def disable_offense_before_and_after(range_by_lines)
|
143
148
|
range_with_newline = range_by_lines.resize(range_by_lines.size + 1)
|
144
149
|
leading_whitespace = range_by_lines.source_line[/^\s*/]
|
data/lib/rubocop/cop/base.rb
CHANGED
@@ -261,6 +261,12 @@ module RuboCop
|
|
261
261
|
@config.target_ruby_version
|
262
262
|
end
|
263
263
|
|
264
|
+
# Returns a gems locked versions (i.e. from Gemfile.lock or gems.locked)
|
265
|
+
# @returns [Gem::Version | nil] The locked gem version, or nil if the gem is not present.
|
266
|
+
def target_gem_version(gem_name)
|
267
|
+
@config.gem_versions_in_target && @config.gem_versions_in_target[gem_name]
|
268
|
+
end
|
269
|
+
|
264
270
|
def parser_engine
|
265
271
|
@config.parser_engine
|
266
272
|
end
|
@@ -66,14 +66,14 @@ module RuboCop
|
|
66
66
|
|
67
67
|
def conditional_declaration?(nodes)
|
68
68
|
parent = nodes[0].each_ancestor.find { |ancestor| !ancestor.begin_type? }
|
69
|
-
return false unless parent&.
|
69
|
+
return false unless parent&.type?(:if, :when)
|
70
70
|
|
71
71
|
root_conditional_node = parent.if_type? ? parent : parent.parent
|
72
72
|
nodes.all? { |node| within_conditional?(node, root_conditional_node) }
|
73
73
|
end
|
74
74
|
|
75
75
|
def within_conditional?(node, conditional_node)
|
76
|
-
conditional_node.branches.any? do |branch|
|
76
|
+
conditional_node.branches.compact.any? do |branch|
|
77
77
|
branch == node || branch.child_nodes.include?(node)
|
78
78
|
end
|
79
79
|
end
|
@@ -45,7 +45,7 @@ module RuboCop
|
|
45
45
|
|
46
46
|
gem_declarations(processed_source.ast)
|
47
47
|
.each_cons(2) do |previous, current|
|
48
|
-
next unless consecutive_lines(previous, current)
|
48
|
+
next unless consecutive_lines?(previous, current)
|
49
49
|
next unless case_insensitive_out_of_order?(gem_name(current), gem_name(previous))
|
50
50
|
|
51
51
|
register_offense(previous, current)
|
@@ -6,10 +6,11 @@ module RuboCop
|
|
6
6
|
# An attribute assignment method calls should be listed only once
|
7
7
|
# in a gemspec.
|
8
8
|
#
|
9
|
-
# Assigning to an attribute with the same name using `spec.foo =`
|
10
|
-
# an unintended usage. On the other hand,
|
11
|
-
# as `spec.requirements`,
|
12
|
-
# permitted because it is
|
9
|
+
# Assigning to an attribute with the same name using `spec.foo =` or
|
10
|
+
# `spec.attribute#[]=` will be an unintended usage. On the other hand,
|
11
|
+
# duplication of methods such # as `spec.requirements`,
|
12
|
+
# `spec.add_runtime_dependency`, and others are permitted because it is
|
13
|
+
# the intended use of appending values.
|
13
14
|
#
|
14
15
|
# @example
|
15
16
|
# # bad
|
@@ -34,6 +35,18 @@ module RuboCop
|
|
34
35
|
# spec.add_dependency('parallel', '~> 1.10')
|
35
36
|
# spec.add_dependency('parser', '>= 2.3.3.1', '< 3.0')
|
36
37
|
# end
|
38
|
+
#
|
39
|
+
# # bad
|
40
|
+
# Gem::Specification.new do |spec|
|
41
|
+
# spec.metadata["key"] = "value"
|
42
|
+
# spec.metadata["key"] = "value"
|
43
|
+
# end
|
44
|
+
#
|
45
|
+
# # good
|
46
|
+
# Gem::Specification.new do |spec|
|
47
|
+
# spec.metadata["key"] = "value"
|
48
|
+
# end
|
49
|
+
#
|
37
50
|
class DuplicatedAssignment < Base
|
38
51
|
include RangeHelp
|
39
52
|
include GemspecHelp
|
@@ -44,12 +57,29 @@ module RuboCop
|
|
44
57
|
# @!method assignment_method_declarations(node)
|
45
58
|
def_node_search :assignment_method_declarations, <<~PATTERN
|
46
59
|
(send
|
47
|
-
(lvar #match_block_variable_name?) _ ...)
|
60
|
+
(lvar {#match_block_variable_name? :_1 :it}) _ ...)
|
61
|
+
PATTERN
|
62
|
+
|
63
|
+
# @!method indexed_assignment_method_declarations(node)
|
64
|
+
def_node_search :indexed_assignment_method_declarations, <<~PATTERN
|
65
|
+
(send
|
66
|
+
(send (lvar {#match_block_variable_name? :_1 :it}) _)
|
67
|
+
:[]=
|
68
|
+
literal?
|
69
|
+
_
|
70
|
+
)
|
48
71
|
PATTERN
|
49
72
|
|
50
73
|
def on_new_investigation
|
51
74
|
return if processed_source.blank?
|
52
75
|
|
76
|
+
process_assignment_method_nodes
|
77
|
+
process_indexed_assignment_method_nodes
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
|
82
|
+
def process_assignment_method_nodes
|
53
83
|
duplicated_assignment_method_nodes.each do |nodes|
|
54
84
|
nodes[1..].each do |node|
|
55
85
|
register_offense(node, node.method_name, nodes.first.first_line)
|
@@ -57,7 +87,14 @@ module RuboCop
|
|
57
87
|
end
|
58
88
|
end
|
59
89
|
|
60
|
-
|
90
|
+
def process_indexed_assignment_method_nodes
|
91
|
+
duplicated_indexed_assignment_method_nodes.each do |nodes|
|
92
|
+
nodes[1..].each do |node|
|
93
|
+
assignment = "#{node.children.first.method_name}[#{node.first_argument.source}]="
|
94
|
+
register_offense(node, assignment, nodes.first.first_line)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
61
98
|
|
62
99
|
def match_block_variable_name?(receiver_name)
|
63
100
|
gem_specification(processed_source.ast) do |block_variable_name|
|
@@ -73,6 +110,13 @@ module RuboCop
|
|
73
110
|
.select { |nodes| nodes.size > 1 }
|
74
111
|
end
|
75
112
|
|
113
|
+
def duplicated_indexed_assignment_method_nodes
|
114
|
+
indexed_assignment_method_declarations(processed_source.ast)
|
115
|
+
.group_by { |node| [node.children.first.method_name, node.first_argument] }
|
116
|
+
.values
|
117
|
+
.select { |nodes| nodes.size > 1 }
|
118
|
+
end
|
119
|
+
|
76
120
|
def register_offense(node, assignment, line_of_first_occurrence)
|
77
121
|
line_range = node.loc.column...node.loc.last_column
|
78
122
|
offense_location = source_range(processed_source.buffer, node.first_line, line_range)
|
@@ -71,7 +71,7 @@ module RuboCop
|
|
71
71
|
|
72
72
|
dependency_declarations(processed_source.ast)
|
73
73
|
.each_cons(2) do |previous, current|
|
74
|
-
next unless consecutive_lines(previous, current)
|
74
|
+
next unless consecutive_lines?(previous, current)
|
75
75
|
next unless case_insensitive_out_of_order?(gem_name(current), gem_name(previous))
|
76
76
|
next unless get_dependency_name(previous) == get_dependency_name(current)
|
77
77
|
|
@@ -71,11 +71,17 @@ module RuboCop
|
|
71
71
|
(send nil? :bad_method ...)
|
72
72
|
PATTERN
|
73
73
|
|
74
|
+
# Called on every `send` node (method call) while walking the AST.
|
75
|
+
# TODO: remove this method if inspecting `send` nodes is unneeded for your cop.
|
76
|
+
# By default, this is aliased to `on_csend` as well to handle method calls
|
77
|
+
# with safe navigation, remove the alias if this is unnecessary.
|
78
|
+
# If kept, ensure your tests cover safe navigation as well!
|
74
79
|
def on_send(node)
|
75
80
|
return unless bad_method?(node)
|
76
81
|
|
77
82
|
add_offense(node)
|
78
83
|
end
|
84
|
+
alias on_csend on_send
|
79
85
|
end
|
80
86
|
end
|
81
87
|
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module InternalAffairs
|
6
|
+
# Use `config.cop_enabled?('Department/CopName')` instead of
|
7
|
+
# traversing the config hash.
|
8
|
+
#
|
9
|
+
# @example
|
10
|
+
# # `for_cop(...)['Enabled']
|
11
|
+
#
|
12
|
+
# # bad
|
13
|
+
# config.for_cop('Department/CopName')['Enabled']
|
14
|
+
#
|
15
|
+
# # good
|
16
|
+
# config.cop_enabled?('Department/CopName')
|
17
|
+
#
|
18
|
+
# @example
|
19
|
+
# # when keeping a cop's config in a local and then checking the `Enabled` key
|
20
|
+
#
|
21
|
+
# # bad
|
22
|
+
# cop_config = config.for_cop('Department/CopName')
|
23
|
+
# cop_config['Enabled'] && cop_config['Foo']
|
24
|
+
#
|
25
|
+
# # good
|
26
|
+
# config.for_enabled_cop('Department/CopName')['Foo']
|
27
|
+
#
|
28
|
+
class CopEnabled < Base
|
29
|
+
extend AutoCorrector
|
30
|
+
|
31
|
+
MSG = 'Use `%<replacement>s` instead of `%<source>s`.'
|
32
|
+
MSG_HASH = 'Consider replacing uses of `%<hash_name>s` with `config.for_enabled_cop`.'
|
33
|
+
|
34
|
+
RESTRICT_ON_SEND = [:[]].freeze
|
35
|
+
|
36
|
+
# @!method for_cop_enabled?(node)
|
37
|
+
def_node_matcher :for_cop_enabled?, <<~PATTERN
|
38
|
+
(send
|
39
|
+
(send
|
40
|
+
${(send nil? :config) (ivar :@config)} :for_cop
|
41
|
+
$(str _)) :[]
|
42
|
+
(str "Enabled"))
|
43
|
+
PATTERN
|
44
|
+
|
45
|
+
# @!method config_enabled_lookup?(node)
|
46
|
+
def_node_matcher :config_enabled_lookup?, <<~PATTERN
|
47
|
+
(send
|
48
|
+
{(lvar $_) (ivar $_) (send nil? $_)} :[]
|
49
|
+
(str "Enabled"))
|
50
|
+
PATTERN
|
51
|
+
|
52
|
+
def on_send(node)
|
53
|
+
if (config_var, cop_name = for_cop_enabled?(node))
|
54
|
+
handle_for_cop(node, config_var, cop_name)
|
55
|
+
elsif (config_var = config_enabled_lookup?(node))
|
56
|
+
return unless config_var.end_with?('_config')
|
57
|
+
|
58
|
+
handle_hash(node, config_var)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
private
|
63
|
+
|
64
|
+
def handle_for_cop(node, config_var, cop_name)
|
65
|
+
source = node.source
|
66
|
+
quote = cop_name.loc.begin.source
|
67
|
+
cop_name = cop_name.value
|
68
|
+
|
69
|
+
replacement = "#{config_var.source}.cop_enabled?(#{quote}#{cop_name}#{quote})"
|
70
|
+
message = format(MSG, source: source, replacement: replacement)
|
71
|
+
|
72
|
+
add_offense(node, message: message) do |corrector|
|
73
|
+
corrector.replace(node, replacement)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def handle_hash(node, config_var)
|
78
|
+
message = format(MSG_HASH, hash_name: config_var)
|
79
|
+
|
80
|
+
add_offense(node, message: message)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -50,10 +50,12 @@ module RuboCop
|
|
50
50
|
}.freeze
|
51
51
|
|
52
52
|
EXPECT_NO_CORRECTIONS_DESCRIPTION_MAPPING = {
|
53
|
-
/\A(auto[- ]?)?
|
53
|
+
/\A(auto[- ]?)?corrects?/ => 'does not correct',
|
54
|
+
/\band (auto[- ]?)?corrects/ => 'but does not correct'
|
54
55
|
}.freeze
|
55
56
|
|
56
57
|
EXPECT_CORRECTION_DESCRIPTION_MAPPING = {
|
58
|
+
/\bbut (does not|doesn't) (auto[- ]?)?correct/ => 'and autocorrects',
|
57
59
|
/\b(does not|doesn't) (auto[- ]?)?correct/ => 'autocorrects'
|
58
60
|
}.freeze
|
59
61
|
|
@@ -67,7 +69,7 @@ module RuboCop
|
|
67
69
|
# @!method offense_example(node)
|
68
70
|
def_node_matcher :offense_example, <<~PATTERN
|
69
71
|
(block
|
70
|
-
(send _ {:it :specify} $...)
|
72
|
+
(send _ {:it :specify :xit :fit} $...)
|
71
73
|
_args
|
72
74
|
`(send nil? %RESTRICT_ON_SEND ...)
|
73
75
|
)
|
@@ -90,8 +92,10 @@ module RuboCop
|
|
90
92
|
description_text = string_contents(current_description)
|
91
93
|
return unless (new_description = correct_description(description_text, description_map))
|
92
94
|
|
95
|
+
quote = current_description.dstr_type? ? '"' : "'"
|
96
|
+
|
93
97
|
add_offense(current_description, message: message) do |corrector|
|
94
|
-
corrector.replace(current_description, "
|
98
|
+
corrector.replace(current_description, "#{quote}#{new_description}#{quote}")
|
95
99
|
end
|
96
100
|
end
|
97
101
|
|
@@ -106,7 +110,7 @@ module RuboCop
|
|
106
110
|
end
|
107
111
|
|
108
112
|
def string_contents(node)
|
109
|
-
node.
|
113
|
+
node.type?(:str, :dstr) ? node.value : node.source
|
110
114
|
end
|
111
115
|
end
|
112
116
|
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module InternalAffairs
|
6
|
+
# When a node location may not exist, `Node#loc?` or `Node#loc_is?`
|
7
|
+
# can be used instead of calling `Node#respond_to?` before using
|
8
|
+
# the value.
|
9
|
+
#
|
10
|
+
# @example
|
11
|
+
# # bad
|
12
|
+
# node.loc.respond_to?(:begin) && node.loc.begin
|
13
|
+
#
|
14
|
+
# # good
|
15
|
+
# node.loc?(:begin)
|
16
|
+
#
|
17
|
+
# # bad
|
18
|
+
# node.loc.respond_to?(:begin) && node.loc.begin.is?('(')
|
19
|
+
#
|
20
|
+
# # good
|
21
|
+
# node.loc_is?(:begin, '(')
|
22
|
+
#
|
23
|
+
# # bad
|
24
|
+
# node.loc.respond_to?(:begin) && node.loc.begin.source == '('
|
25
|
+
#
|
26
|
+
# # good
|
27
|
+
# node.loc_is?(:begin, '(')
|
28
|
+
#
|
29
|
+
class LocationExists < Base
|
30
|
+
extend AutoCorrector
|
31
|
+
|
32
|
+
MSG = 'Use `%<replacement>s` instead of `%<source>s`.'
|
33
|
+
|
34
|
+
# @!method replaceable_with_loc_is(node)
|
35
|
+
def_node_matcher :replaceable_with_loc_is, <<~PATTERN
|
36
|
+
(and
|
37
|
+
(call
|
38
|
+
(call $_receiver :loc) :respond_to?
|
39
|
+
$(sym _location))
|
40
|
+
{
|
41
|
+
(call
|
42
|
+
(call
|
43
|
+
(call _receiver :loc) _location) :is?
|
44
|
+
$(str _))
|
45
|
+
(call
|
46
|
+
(call
|
47
|
+
(call
|
48
|
+
(call _receiver :loc) _location) :source) :==
|
49
|
+
$(str _))
|
50
|
+
})
|
51
|
+
PATTERN
|
52
|
+
|
53
|
+
# @!method replaceable_with_loc(node)
|
54
|
+
def_node_matcher :replaceable_with_loc, <<~PATTERN
|
55
|
+
(and
|
56
|
+
(call
|
57
|
+
(call $_receiver :loc) :respond_to?
|
58
|
+
$(sym _location))
|
59
|
+
(call
|
60
|
+
(call _receiver :loc) _location))
|
61
|
+
PATTERN
|
62
|
+
|
63
|
+
def on_and(node)
|
64
|
+
replace_with_loc(node) || replace_with_loc_is(node)
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
def replace_with_loc(node)
|
70
|
+
replaceable_with_loc(node) do |receiver, location|
|
71
|
+
if node.parent&.assignment?
|
72
|
+
register_offense(node, replace_assignment(receiver, location))
|
73
|
+
else
|
74
|
+
register_offense(node, replacement(receiver, "loc?(#{location.source})"))
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def replace_with_loc_is(node)
|
80
|
+
replaceable_with_loc_is(node) do |receiver, location, value|
|
81
|
+
replacement = replacement(receiver, "loc_is?(#{location.source}, #{value.source})")
|
82
|
+
register_offense(node, replacement)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def register_offense(node, replacement)
|
87
|
+
message = format(MSG, replacement: replacement, source: node.source)
|
88
|
+
|
89
|
+
add_offense(node, message: message) do |corrector|
|
90
|
+
corrector.replace(node, replacement)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def replacement(receiver, rest)
|
95
|
+
"#{replace_receiver(receiver)}#{rest}"
|
96
|
+
end
|
97
|
+
|
98
|
+
def replace_assignment(receiver, location)
|
99
|
+
prefix = replace_receiver(receiver)
|
100
|
+
|
101
|
+
"#{prefix}loc#{dot(receiver)}#{location.value} if #{prefix}loc?(#{location.source})"
|
102
|
+
end
|
103
|
+
|
104
|
+
def replace_receiver(receiver)
|
105
|
+
return '' unless receiver
|
106
|
+
|
107
|
+
"#{receiver.source}#{dot(receiver)}"
|
108
|
+
end
|
109
|
+
|
110
|
+
def dot(node)
|
111
|
+
node.parent.loc.dot.source
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
@@ -22,7 +22,7 @@ module RuboCop
|
|
22
22
|
|
23
23
|
def on_send(node)
|
24
24
|
return unless (parent = node.parent)
|
25
|
-
return unless parent.
|
25
|
+
return unless parent.call_type? && parent.method?(:expression)
|
26
26
|
return unless parent.receiver.receiver
|
27
27
|
|
28
28
|
offense = node.loc.selector.join(parent.source_range.end)
|
@@ -31,6 +31,7 @@ module RuboCop
|
|
31
31
|
corrector.replace(offense, 'source_range')
|
32
32
|
end
|
33
33
|
end
|
34
|
+
alias on_csend on_send
|
34
35
|
end
|
35
36
|
end
|
36
37
|
end
|