rubocop 1.67.0 → 1.73.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/LICENSE.txt +1 -1
- data/README.md +4 -4
- data/config/default.yml +168 -19
- data/config/internal_affairs.yml +16 -0
- data/lib/rubocop/cached_data.rb +12 -4
- data/lib/rubocop/cli/command/execute_runner.rb +4 -4
- data/lib/rubocop/cli/command/show_cops.rb +24 -2
- data/lib/rubocop/cli/command/suggest_extensions.rb +7 -1
- data/lib/rubocop/cli/command/version.rb +2 -2
- data/lib/rubocop/comment_config.rb +2 -2
- data/lib/rubocop/config.rb +17 -4
- data/lib/rubocop/config_loader.rb +48 -8
- data/lib/rubocop/config_loader_resolver.rb +35 -10
- data/lib/rubocop/config_validator.rb +19 -9
- data/lib/rubocop/cop/autocorrect_logic.rb +36 -19
- data/lib/rubocop/cop/base.rb +7 -1
- 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/gem_filename.rb +0 -1
- data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +0 -1
- data/lib/rubocop/cop/correctors/alignment_corrector.rb +1 -12
- data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +1 -1
- data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +10 -0
- data/lib/rubocop/cop/gemspec/deprecated_attribute_assignment.rb +1 -2
- data/lib/rubocop/cop/gemspec/required_ruby_version.rb +0 -2
- 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 +4 -2
- 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 +3 -4
- 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 +229 -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/numblock_handler.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/on_send_without_on_csend.rb +90 -0
- data/lib/rubocop/cop/internal_affairs/operator_keyword.rb +48 -0
- data/lib/rubocop/cop/internal_affairs/plugin.rb +33 -0
- 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/style_detected_api_use.rb +0 -2
- data/lib/rubocop/cop/internal_affairs/undefined_config.rb +7 -1
- 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 -9
- data/lib/rubocop/cop/layout/array_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/begin_end_alignment.rb +0 -1
- data/lib/rubocop/cop/layout/block_alignment.rb +3 -2
- data/lib/rubocop/cop/layout/class_structure.rb +9 -9
- 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 +29 -4
- data/lib/rubocop/cop/layout/empty_lines_around_begin_body.rb +5 -6
- data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +4 -5
- data/lib/rubocop/cop/layout/empty_lines_around_method_body.rb +23 -1
- 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 +3 -8
- 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 +6 -4
- data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +2 -1
- data/lib/rubocop/cop/layout/indentation_width.rb +7 -7
- data/lib/rubocop/cop/layout/leading_comment_space.rb +44 -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 +119 -4
- 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 +2 -1
- data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +4 -4
- data/lib/rubocop/cop/layout/multiline_method_definition_brace_layout.rb +1 -1
- data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +2 -3
- data/lib/rubocop/cop/layout/parameter_alignment.rb +3 -4
- data/lib/rubocop/cop/layout/redundant_line_break.rb +10 -41
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +4 -3
- 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 +1 -1
- data/lib/rubocop/cop/layout/space_around_keyword.rb +2 -1
- data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +1 -1
- data/lib/rubocop/cop/layout/space_around_operators.rb +19 -20
- data/lib/rubocop/cop/layout/space_before_brackets.rb +5 -5
- 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 +6 -0
- data/lib/rubocop/cop/layout/space_inside_block_braces.rb +4 -0
- data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +4 -0
- data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +0 -1
- 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 +119 -0
- data/lib/rubocop/cop/lint/assignment_in_condition.rb +1 -3
- data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +10 -12
- data/lib/rubocop/cop/lint/circular_argument_reference.rb +6 -0
- 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 +1 -1
- data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +2 -1
- data/lib/rubocop/cop/lint/duplicate_branch.rb +39 -4
- data/lib/rubocop/cop/lint/duplicate_match_pattern.rb +1 -1
- data/lib/rubocop/cop/lint/duplicate_methods.rb +0 -14
- 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_ensure.rb +1 -1
- data/lib/rubocop/cop/lint/empty_expression.rb +0 -2
- data/lib/rubocop/cop/lint/empty_file.rb +0 -2
- data/lib/rubocop/cop/lint/ensure_return.rb +1 -1
- data/lib/rubocop/cop/lint/float_comparison.rb +20 -14
- data/lib/rubocop/cop/lint/float_out_of_range.rb +2 -4
- data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +2 -2
- data/lib/rubocop/cop/lint/hash_new_with_keyword_arguments_as_default.rb +55 -0
- data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +1 -1
- data/lib/rubocop/cop/lint/interpolation_check.rb +9 -0
- data/lib/rubocop/cop/lint/it_without_arguments_in_block.rb +3 -0
- data/lib/rubocop/cop/lint/literal_as_condition.rb +105 -7
- data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +1 -1
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +24 -6
- data/lib/rubocop/cop/lint/missing_super.rb +2 -2
- data/lib/rubocop/cop/lint/mixed_case_range.rb +4 -7
- 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/no_return_in_begin_end_blocks.rb +2 -2
- data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +12 -3
- data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +3 -3
- data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +1 -1
- data/lib/rubocop/cop/lint/number_conversion.rb +0 -1
- data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +1 -2
- data/lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +93 -0
- data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +1 -2
- data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +3 -2
- data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +1 -5
- data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +1 -1
- 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_safe_navigation.rb +12 -7
- data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +8 -7
- data/lib/rubocop/cop/lint/redundant_string_coercion.rb +2 -2
- data/lib/rubocop/cop/lint/redundant_type_conversion.rb +252 -0
- data/lib/rubocop/cop/lint/refinement_import_methods.rb +1 -1
- data/lib/rubocop/cop/lint/regexp_as_condition.rb +0 -1
- data/lib/rubocop/cop/lint/rescue_exception.rb +1 -1
- data/lib/rubocop/cop/lint/rescue_type.rb +3 -7
- data/lib/rubocop/cop/lint/safe_navigation_chain.rb +17 -1
- data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +5 -1
- data/lib/rubocop/cop/lint/self_assignment.rb +8 -10
- data/lib/rubocop/cop/lint/shadowed_exception.rb +1 -1
- data/lib/rubocop/cop/lint/shared_mutable_default.rb +65 -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/unescaped_bracket_in_regexp.rb +88 -0
- data/lib/rubocop/cop/lint/unexpected_block_arity.rb +1 -1
- data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +1 -1
- data/lib/rubocop/cop/lint/unreachable_code.rb +51 -2
- data/lib/rubocop/cop/lint/unreachable_loop.rb +1 -1
- data/lib/rubocop/cop/lint/unused_method_argument.rb +18 -2
- data/lib/rubocop/cop/lint/useless_access_modifier.rb +4 -4
- data/lib/rubocop/cop/lint/useless_assignment.rb +1 -1
- data/lib/rubocop/cop/lint/useless_constant_scoping.rb +80 -0
- data/lib/rubocop/cop/lint/useless_defined.rb +55 -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_rescue.rb +1 -1
- data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +2 -2
- data/lib/rubocop/cop/lint/useless_setter_call.rb +14 -25
- data/lib/rubocop/cop/lint/void.rb +14 -11
- 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 +5 -2
- data/lib/rubocop/cop/metrics/method_length.rb +8 -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/abc_size_calculator.rb +1 -1
- data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +2 -3
- 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_assignment.rb +4 -12
- data/lib/rubocop/cop/mixin/check_line_breakable.rb +20 -10
- data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +49 -0
- data/lib/rubocop/cop/mixin/comments_help.rb +8 -3
- data/lib/rubocop/cop/mixin/dig_help.rb +27 -0
- data/lib/rubocop/cop/mixin/endless_method_rewriter.rb +24 -0
- data/lib/rubocop/cop/mixin/frozen_string_literal.rb +4 -2
- 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 +1 -1
- data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +5 -9
- 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 +3 -4
- 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 +17 -1
- data/lib/rubocop/cop/mixin/trailing_comma.rb +15 -3
- data/lib/rubocop/cop/naming/accessor_method_name.rb +6 -6
- data/lib/rubocop/cop/naming/block_forwarding.rb +20 -16
- data/lib/rubocop/cop/naming/constant_name.rb +6 -7
- data/lib/rubocop/cop/naming/file_name.rb +0 -2
- data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +11 -12
- data/lib/rubocop/cop/naming/predicate_name.rb +44 -0
- data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +6 -14
- data/lib/rubocop/cop/naming/variable_name.rb +63 -6
- data/lib/rubocop/cop/naming/variable_number.rb +2 -3
- data/lib/rubocop/cop/offense.rb +2 -3
- 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 +86 -28
- data/lib/rubocop/cop/style/accessor_grouping.rb +19 -5
- data/lib/rubocop/cop/style/ambiguous_endless_method_definition.rb +79 -0
- data/lib/rubocop/cop/style/and_or.rb +1 -1
- data/lib/rubocop/cop/style/arguments_forwarding.rb +39 -23
- data/lib/rubocop/cop/style/array_first_last.rb +18 -2
- data/lib/rubocop/cop/style/array_intersect.rb +5 -4
- data/lib/rubocop/cop/style/bitwise_predicate.rb +100 -0
- data/lib/rubocop/cop/style/block_delimiters.rb +41 -24
- data/lib/rubocop/cop/style/case_like_if.rb +8 -11
- data/lib/rubocop/cop/style/class_and_module_children.rb +6 -3
- data/lib/rubocop/cop/style/collection_methods.rb +1 -1
- data/lib/rubocop/cop/style/combinable_defined.rb +115 -0
- data/lib/rubocop/cop/style/combinable_loops.rb +2 -2
- data/lib/rubocop/cop/style/commented_keyword.rb +11 -1
- data/lib/rubocop/cop/style/concat_array_literals.rb +1 -1
- data/lib/rubocop/cop/style/conditional_assignment.rb +25 -25
- data/lib/rubocop/cop/style/constant_visibility.rb +3 -12
- data/lib/rubocop/cop/style/dig_chain.rb +89 -0
- data/lib/rubocop/cop/style/documentation.rb +1 -1
- data/lib/rubocop/cop/style/double_negation.rb +3 -3
- 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 +1 -1
- data/lib/rubocop/cop/style/empty_method.rb +1 -1
- data/lib/rubocop/cop/style/endless_method.rb +150 -18
- data/lib/rubocop/cop/style/eval_with_location.rb +1 -1
- data/lib/rubocop/cop/style/exact_regexp_match.rb +2 -3
- data/lib/rubocop/cop/style/explicit_block_argument.rb +15 -2
- data/lib/rubocop/cop/style/exponential_notation.rb +1 -1
- data/lib/rubocop/cop/style/fetch_env_var.rb +2 -1
- data/lib/rubocop/cop/style/file_null.rb +89 -0
- data/lib/rubocop/cop/style/file_touch.rb +75 -0
- data/lib/rubocop/cop/style/float_division.rb +8 -4
- data/lib/rubocop/cop/style/for.rb +0 -1
- data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +1 -1
- data/lib/rubocop/cop/style/global_vars.rb +1 -3
- data/lib/rubocop/cop/style/guard_clause.rb +15 -2
- data/lib/rubocop/cop/style/hash_conversion.rb +1 -2
- data/lib/rubocop/cop/style/hash_each_methods.rb +3 -6
- data/lib/rubocop/cop/style/hash_except.rb +35 -147
- data/lib/rubocop/cop/style/hash_slice.rb +80 -0
- data/lib/rubocop/cop/style/hash_syntax.rb +6 -3
- data/lib/rubocop/cop/style/identical_conditional_branches.rb +22 -3
- data/lib/rubocop/cop/style/if_inside_else.rb +0 -1
- data/lib/rubocop/cop/style/if_unless_modifier.rb +3 -3
- data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +2 -3
- data/lib/rubocop/cop/style/if_with_semicolon.rb +20 -9
- data/lib/rubocop/cop/style/infinite_loop.rb +1 -1
- data/lib/rubocop/cop/style/inverse_methods.rb +6 -7
- data/lib/rubocop/cop/style/it_assignment.rb +36 -0
- data/lib/rubocop/cop/style/keyword_arguments_merging.rb +67 -0
- data/lib/rubocop/cop/style/keyword_parameters_order.rb +1 -1
- data/lib/rubocop/cop/style/lambda_call.rb +3 -2
- data/lib/rubocop/cop/style/line_end_concatenation.rb +10 -4
- data/lib/rubocop/cop/style/map_into_array.rb +7 -2
- data/lib/rubocop/cop/style/map_to_hash.rb +1 -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 +20 -13
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +2 -0
- data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +8 -11
- data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +2 -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/missing_respond_to_missing.rb +33 -3
- data/lib/rubocop/cop/style/multiline_block_chain.rb +1 -1
- data/lib/rubocop/cop/style/multiline_memoization.rb +1 -1
- data/lib/rubocop/cop/style/multiple_comparison.rb +52 -51
- data/lib/rubocop/cop/style/mutable_constant.rb +7 -8
- data/lib/rubocop/cop/style/negated_if_else_condition.rb +7 -5
- data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +1 -1
- data/lib/rubocop/cop/style/nested_ternary_operator.rb +5 -4
- data/lib/rubocop/cop/style/not.rb +1 -1
- data/lib/rubocop/cop/style/object_then.rb +14 -15
- data/lib/rubocop/cop/style/one_line_conditional.rb +25 -4
- data/lib/rubocop/cop/style/open_struct_use.rb +5 -5
- data/lib/rubocop/cop/style/operator_method_call.rb +5 -6
- data/lib/rubocop/cop/style/or_assignment.rb +3 -6
- data/lib/rubocop/cop/style/parallel_assignment.rb +9 -18
- 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/proc.rb +1 -2
- data/lib/rubocop/cop/style/quoted_symbols.rb +1 -1
- data/lib/rubocop/cop/style/raise_args.rb +7 -5
- 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_assignment.rb +1 -1
- data/lib/rubocop/cop/style/redundant_begin.rb +1 -1
- data/lib/rubocop/cop/style/redundant_condition.rb +72 -23
- data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +2 -1
- 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 +250 -0
- data/lib/rubocop/cop/style/redundant_freeze.rb +2 -2
- data/lib/rubocop/cop/style/redundant_initialize.rb +12 -3
- data/lib/rubocop/cop/style/redundant_line_continuation.rb +54 -15
- data/lib/rubocop/cop/style/redundant_parentheses.rb +36 -24
- data/lib/rubocop/cop/style/redundant_regexp_argument.rb +4 -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_return.rb +2 -2
- data/lib/rubocop/cop/style/redundant_self.rb +8 -15
- data/lib/rubocop/cop/style/redundant_self_assignment.rb +20 -32
- data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +4 -4
- data/lib/rubocop/cop/style/redundant_sort.rb +3 -3
- data/lib/rubocop/cop/style/redundant_string_escape.rb +2 -2
- data/lib/rubocop/cop/style/rescue_modifier.rb +2 -3
- data/lib/rubocop/cop/style/return_nil.rb +1 -1
- data/lib/rubocop/cop/style/safe_navigation.rb +14 -2
- data/lib/rubocop/cop/style/safe_navigation_chain_length.rb +52 -0
- data/lib/rubocop/cop/style/select_by_regexp.rb +1 -1
- data/lib/rubocop/cop/style/self_assignment.rb +11 -17
- 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/signal_exception.rb +2 -3
- data/lib/rubocop/cop/style/single_argument_dig.rb +9 -5
- data/lib/rubocop/cop/style/single_line_block_params.rb +1 -1
- data/lib/rubocop/cop/style/single_line_do_end_block.rb +12 -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 +4 -5
- data/lib/rubocop/cop/style/special_global_vars.rb +1 -1
- 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/super_arguments.rb +65 -17
- data/lib/rubocop/cop/style/swap_values.rb +4 -15
- data/lib/rubocop/cop/style/ternary_parentheses.rb +25 -4
- data/lib/rubocop/cop/style/top_level_method_definition.rb +1 -1
- data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +4 -1
- 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/trailing_underscore_variable.rb +4 -4
- data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
- data/lib/rubocop/cop/style/variable_interpolation.rb +1 -2
- 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/util.rb +12 -5
- data/lib/rubocop/cop/utils/format_string.rb +7 -5
- data/lib/rubocop/cop/variable_force/assignment.rb +18 -3
- data/lib/rubocop/cop/variable_force/branch.rb +1 -1
- data/lib/rubocop/cop/variable_force/variable.rb +18 -2
- data/lib/rubocop/cop/variable_force/variable_table.rb +5 -5
- data/lib/rubocop/cop/variable_force.rb +4 -10
- data/lib/rubocop/cops_documentation_generator.rb +44 -23
- data/lib/rubocop/directive_comment.rb +44 -10
- data/lib/rubocop/formatter/disabled_config_formatter.rb +1 -1
- data/lib/rubocop/formatter/formatter_set.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 +17 -49
- data/lib/rubocop/lsp/server.rb +0 -2
- data/lib/rubocop/lsp/stdin_runner.rb +83 -0
- data/lib/rubocop/magic_comment.rb +3 -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 +9 -0
- data/lib/rubocop/rspec/expect_offense.rb +6 -2
- data/lib/rubocop/rspec/shared_contexts.rb +19 -1
- data/lib/rubocop/rspec/support.rb +2 -2
- data/lib/rubocop/runner.rb +21 -14
- data/lib/rubocop/server/cache.rb +35 -2
- data/lib/rubocop/server/cli.rb +2 -2
- data/lib/rubocop/target_finder.rb +1 -0
- data/lib/rubocop/target_ruby.rb +16 -1
- data/lib/rubocop/version.rb +41 -7
- data/lib/rubocop.rb +27 -1
- data/lib/ruby_lsp/rubocop/addon.rb +75 -0
- data/lib/ruby_lsp/rubocop/runtime_adapter.rb +47 -0
- metadata +73 -20
- data/lib/rubocop/cop/utils/regexp_ranges.rb +0 -113
- data/lib/rubocop/rspec/host_environment_simulation_helper.rb +0 -28
@@ -12,9 +12,11 @@ module RuboCop
|
|
12
12
|
#
|
13
13
|
# # bad
|
14
14
|
# array = [ a, b, c, d ]
|
15
|
+
# array = [ a, [ b, c ]]
|
15
16
|
#
|
16
17
|
# # good
|
17
18
|
# array = [a, b, c, d]
|
19
|
+
# array = [a, [b, c]]
|
18
20
|
#
|
19
21
|
# @example EnforcedStyle: space
|
20
22
|
# # The `space` style enforces that array literals have
|
@@ -22,9 +24,11 @@ module RuboCop
|
|
22
24
|
#
|
23
25
|
# # bad
|
24
26
|
# array = [a, b, c, d]
|
27
|
+
# array = [ a, [ b, c ]]
|
25
28
|
#
|
26
29
|
# # good
|
27
30
|
# array = [ a, b, c, d ]
|
31
|
+
# array = [ a, [ b, c ] ]
|
28
32
|
#
|
29
33
|
# @example EnforcedStyle: compact
|
30
34
|
# # The `compact` style normally requires a space inside
|
@@ -32,6 +36,7 @@ module RuboCop
|
|
32
36
|
# # or right brackets are collapsed together in nested arrays.
|
33
37
|
#
|
34
38
|
# # bad
|
39
|
+
# array = [a, b, c, d]
|
35
40
|
# array = [ a, [ b, c ] ]
|
36
41
|
# array = [
|
37
42
|
# [ a ],
|
@@ -39,6 +44,7 @@ module RuboCop
|
|
39
44
|
# ]
|
40
45
|
#
|
41
46
|
# # good
|
47
|
+
# array = [ a, b, c, d ]
|
42
48
|
# array = [ a, [ b, c ]]
|
43
49
|
# array = [[ a ],
|
44
50
|
# [ b, c ]]
|
@@ -12,9 +12,11 @@ module RuboCop
|
|
12
12
|
#
|
13
13
|
# # bad
|
14
14
|
# h = {a: 1, b: 2}
|
15
|
+
# foo = {{ a: 1 } => { b: { c: 2 }}}
|
15
16
|
#
|
16
17
|
# # good
|
17
18
|
# h = { a: 1, b: 2 }
|
19
|
+
# foo = { { a: 1 } => { b: { c: 2 } } }
|
18
20
|
#
|
19
21
|
# @example EnforcedStyle: no_space
|
20
22
|
# # The `no_space` style enforces that hash literals have
|
@@ -22,9 +24,11 @@ module RuboCop
|
|
22
24
|
#
|
23
25
|
# # bad
|
24
26
|
# h = { a: 1, b: 2 }
|
27
|
+
# foo = {{ a: 1 } => { b: { c: 2 }}}
|
25
28
|
#
|
26
29
|
# # good
|
27
30
|
# h = {a: 1, b: 2}
|
31
|
+
# foo = {{a: 1} => {b: {c: 2}}}
|
28
32
|
#
|
29
33
|
# @example EnforcedStyle: compact
|
30
34
|
# # The `compact` style normally requires a space inside
|
@@ -48,7 +48,7 @@ module RuboCop
|
|
48
48
|
|
49
49
|
def on_new_investigation
|
50
50
|
processed_source.lines.each_with_index do |line, index|
|
51
|
-
next unless line.
|
51
|
+
next unless line.match?(/[[:blank:]]\z/)
|
52
52
|
|
53
53
|
process_line(line, index + 1)
|
54
54
|
end
|
@@ -84,7 +84,7 @@ module RuboCop
|
|
84
84
|
end
|
85
85
|
|
86
86
|
def whitespace_is_indentation?(range, level)
|
87
|
-
range.source[/[
|
87
|
+
range.source[/[[:blank:]]+/].length <= level
|
88
88
|
end
|
89
89
|
|
90
90
|
def whitespace_only?(range)
|
@@ -123,7 +123,9 @@ module RuboCop
|
|
123
123
|
end
|
124
124
|
|
125
125
|
def offense_range(lineno, line)
|
126
|
-
source_range(
|
126
|
+
source_range(
|
127
|
+
processed_source.buffer, lineno, (line.sub(/[[:blank:]]+\z/, '').length)...(line.length)
|
128
|
+
)
|
127
129
|
end
|
128
130
|
end
|
129
131
|
end
|
@@ -77,7 +77,7 @@ module RuboCop
|
|
77
77
|
private
|
78
78
|
|
79
79
|
def ambiguous_block_association?(send_node)
|
80
|
-
send_node.last_argument.
|
80
|
+
send_node.last_argument.any_block_type? && !send_node.last_argument.send_node.arguments?
|
81
81
|
end
|
82
82
|
|
83
83
|
def allowed_method_pattern?(node)
|
@@ -0,0 +1,119 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Lint
|
6
|
+
# Checks for an array literal interpolated inside a regexp.
|
7
|
+
#
|
8
|
+
# When interpolating an array literal, it is converted to a string. This means
|
9
|
+
# that when inside a regexp, it acts as a character class but with additional
|
10
|
+
# quotes, spaces and commas that are likely not intended. For example,
|
11
|
+
# `/#{%w[a b c]}/` parses as `/["a", "b", "c"]/` (or `/["a, bc]/` without
|
12
|
+
# repeated characters).
|
13
|
+
#
|
14
|
+
# The cop can autocorrect to a character class (if all items in the array are a
|
15
|
+
# single character) or alternation (if the array contains longer items).
|
16
|
+
#
|
17
|
+
# NOTE: This only considers interpolated arrays that contain only strings, symbols,
|
18
|
+
# integers, and floats. Any other type is not easily convertible to a character class
|
19
|
+
# or regexp alternation.
|
20
|
+
#
|
21
|
+
# @safety
|
22
|
+
# Autocorrection is unsafe because it will change the regexp pattern, by
|
23
|
+
# removing the additional quotes, spaces and commas from the character class.
|
24
|
+
#
|
25
|
+
# @example
|
26
|
+
# # bad
|
27
|
+
# /#{%w[a b c]}/
|
28
|
+
#
|
29
|
+
# # good
|
30
|
+
# /[abc]/
|
31
|
+
#
|
32
|
+
# # bad
|
33
|
+
# /#{%w[foo bar baz]}/
|
34
|
+
#
|
35
|
+
# # good
|
36
|
+
# /(?:foo|bar|baz)/
|
37
|
+
#
|
38
|
+
# # bad - construct a regexp rather than interpolate an array of identifiers
|
39
|
+
# /#{[foo, bar]}/
|
40
|
+
#
|
41
|
+
class ArrayLiteralInRegexp < Base
|
42
|
+
include Interpolation
|
43
|
+
extend AutoCorrector
|
44
|
+
|
45
|
+
LITERAL_TYPES = %i[str sym int float true false nil].freeze
|
46
|
+
private_constant :LITERAL_TYPES
|
47
|
+
|
48
|
+
MSG_CHARACTER_CLASS = 'Use a character class instead of interpolating an array in a regexp.'
|
49
|
+
MSG_ALTERNATION = 'Use alternation instead of interpolating an array in a regexp.'
|
50
|
+
MSG_UNKNOWN = 'Use alternation or a character class instead of interpolating an array ' \
|
51
|
+
'in a regexp.'
|
52
|
+
|
53
|
+
def on_interpolation(begin_node)
|
54
|
+
final_node = begin_node.children.last
|
55
|
+
|
56
|
+
return unless begin_node.parent.regexp_type?
|
57
|
+
return unless final_node.array_type?
|
58
|
+
|
59
|
+
if array_of_literal_values?(final_node)
|
60
|
+
register_array_of_literal_values(begin_node, final_node)
|
61
|
+
else
|
62
|
+
register_array_of_nonliteral_values(begin_node)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
def array_of_literal_values?(node)
|
69
|
+
node.each_value.all? { |value| value.type?(*LITERAL_TYPES) }
|
70
|
+
end
|
71
|
+
|
72
|
+
def register_array_of_literal_values(begin_node, node)
|
73
|
+
array_values = array_values(node)
|
74
|
+
|
75
|
+
if character_class?(array_values)
|
76
|
+
message = MSG_CHARACTER_CLASS
|
77
|
+
replacement = character_class_for(array_values)
|
78
|
+
else
|
79
|
+
message = MSG_ALTERNATION
|
80
|
+
replacement = alternation_for(array_values)
|
81
|
+
end
|
82
|
+
|
83
|
+
add_offense(begin_node, message: message) do |corrector|
|
84
|
+
corrector.replace(begin_node, replacement)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def register_array_of_nonliteral_values(node)
|
89
|
+
# Add offense but do not correct if the array contains any nonliteral values.
|
90
|
+
add_offense(node, message: MSG_UNKNOWN)
|
91
|
+
end
|
92
|
+
|
93
|
+
def array_values(node)
|
94
|
+
node.each_value.map do |value|
|
95
|
+
value.respond_to?(:value) ? value.value : value.source
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def character_class?(values)
|
100
|
+
values.all? { |v| v.to_s.length == 1 }
|
101
|
+
end
|
102
|
+
|
103
|
+
def character_class_for(values)
|
104
|
+
"[#{escape_values(values).join}]"
|
105
|
+
end
|
106
|
+
|
107
|
+
def alternation_for(values)
|
108
|
+
"(?:#{escape_values(values).join('|')})"
|
109
|
+
end
|
110
|
+
|
111
|
+
def escape_values(values)
|
112
|
+
# This may add extraneous escape characters, but they can be cleaned up
|
113
|
+
# by `Style/RedundantRegexpEscape`.
|
114
|
+
values.map { |value| Regexp.escape(value.to_s) }
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
@@ -53,8 +53,6 @@ module RuboCop
|
|
53
53
|
ASGN_TYPES = [:begin, *AST::Node::EQUALS_ASSIGNMENTS, :send, :csend].freeze
|
54
54
|
|
55
55
|
def on_if(node)
|
56
|
-
return if node.condition.block_type?
|
57
|
-
|
58
56
|
traverse_node(node.condition) do |asgn_node|
|
59
57
|
next :skip_children if skip_children?(asgn_node)
|
60
58
|
next if allowed_construct?(asgn_node)
|
@@ -95,7 +93,7 @@ module RuboCop
|
|
95
93
|
|
96
94
|
def traverse_node(node, &block)
|
97
95
|
# if the node is a block, any assignments are irrelevant
|
98
|
-
return if node.
|
96
|
+
return if node.any_block_type?
|
99
97
|
|
100
98
|
result = yield node if ASGN_TYPES.include?(node.type)
|
101
99
|
|
@@ -5,17 +5,16 @@ module RuboCop
|
|
5
5
|
module Lint
|
6
6
|
# Checks for places where binary operator has identical operands.
|
7
7
|
#
|
8
|
-
# It covers
|
9
|
-
# comparison operators: `==`, `===`, `=~`, `>`, `>=`, `<`, ``<=``;
|
8
|
+
# It covers comparison operators: `==`, `===`, `=~`, `>`, `>=`, `<`, ``<=``;
|
10
9
|
# bitwise operators: `|`, `^`, `&`;
|
11
10
|
# boolean operators: `&&`, `||`
|
12
11
|
# and "spaceship" operator - ``<=>``.
|
13
12
|
#
|
14
13
|
# Simple arithmetic operations are allowed by this cop: `+`, `*`, `**`, `<<` and `>>`.
|
15
14
|
# Although these can be rewritten in a different way, it should not be necessary to
|
16
|
-
# do so.
|
17
|
-
#
|
18
|
-
#
|
15
|
+
# do so. Operations such as `-` or `/` where the result will always be the same
|
16
|
+
# (`x - x` will always be 0; `x / x` will always be 1) are offenses, but these
|
17
|
+
# are covered by `Lint/NumericOperationWithConstantResult` instead.
|
19
18
|
#
|
20
19
|
# @safety
|
21
20
|
# This cop is unsafe as it does not consider side effects when calling methods
|
@@ -30,7 +29,6 @@ module RuboCop
|
|
30
29
|
#
|
31
30
|
# @example
|
32
31
|
# # bad
|
33
|
-
# x / x
|
34
32
|
# x.top >= x.top
|
35
33
|
#
|
36
34
|
# if a.x != 0 && a.x != 0
|
@@ -47,19 +45,19 @@ module RuboCop
|
|
47
45
|
#
|
48
46
|
class BinaryOperatorWithIdenticalOperands < Base
|
49
47
|
MSG = 'Binary operator `%<op>s` has identical operands.'
|
50
|
-
|
48
|
+
RESTRICT_ON_SEND = %i[== != === <=> =~ && || > >= < <= | ^].freeze
|
51
49
|
|
52
50
|
def on_send(node)
|
53
51
|
return unless node.binary_operation?
|
52
|
+
return unless node.receiver == node.first_argument
|
54
53
|
|
55
|
-
|
56
|
-
return if ALLOWED_MATH_OPERATORS.include?(node.method_name)
|
57
|
-
|
58
|
-
add_offense(node, message: format(MSG, op: operation)) if lhs == rhs
|
54
|
+
add_offense(node, message: format(MSG, op: node.method_name))
|
59
55
|
end
|
60
56
|
|
61
57
|
def on_and(node)
|
62
|
-
|
58
|
+
return unless node.lhs == node.rhs
|
59
|
+
|
60
|
+
add_offense(node, message: format(MSG, op: node.operator))
|
63
61
|
end
|
64
62
|
alias on_or on_and
|
65
63
|
end
|
@@ -8,6 +8,8 @@ module RuboCop
|
|
8
8
|
#
|
9
9
|
# This cop mirrors a warning produced by MRI since 2.2.
|
10
10
|
#
|
11
|
+
# NOTE: This syntax is no longer valid on Ruby 2.7 or higher.
|
12
|
+
#
|
11
13
|
# @example
|
12
14
|
#
|
13
15
|
# # bad
|
@@ -35,8 +37,12 @@ module RuboCop
|
|
35
37
|
# dry_ingredients.combine
|
36
38
|
# end
|
37
39
|
class CircularArgumentReference < Base
|
40
|
+
extend TargetRubyVersion
|
41
|
+
|
38
42
|
MSG = 'Circular argument reference - `%<arg_name>s`.'
|
39
43
|
|
44
|
+
maximum_target_ruby_version 2.6
|
45
|
+
|
40
46
|
def on_kwoptarg(node)
|
41
47
|
check_for_circular_argument_references(*node)
|
42
48
|
end
|
@@ -68,12 +68,12 @@ module RuboCop
|
|
68
68
|
|
69
69
|
# @!method constant_assigned_in_block?(node)
|
70
70
|
def_node_matcher :constant_assigned_in_block?, <<~PATTERN
|
71
|
-
({^
|
71
|
+
({^any_block [^begin ^^any_block]} nil? ...)
|
72
72
|
PATTERN
|
73
73
|
|
74
74
|
# @!method module_defined_in_block?(node)
|
75
75
|
def_node_matcher :module_defined_in_block?, <<~PATTERN
|
76
|
-
({^
|
76
|
+
({^any_block [^begin ^^any_block]} ...)
|
77
77
|
PATTERN
|
78
78
|
|
79
79
|
def on_casgn(node)
|
@@ -92,7 +92,7 @@ module RuboCop
|
|
92
92
|
private
|
93
93
|
|
94
94
|
def method_name(node)
|
95
|
-
node.ancestors.find(&:
|
95
|
+
node.ancestors.find(&:any_block_type?).method_name
|
96
96
|
end
|
97
97
|
end
|
98
98
|
end
|
@@ -0,0 +1,148 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Lint
|
6
|
+
# Checks for constant reassignments.
|
7
|
+
#
|
8
|
+
# Emulates Ruby's runtime warning "already initialized constant X"
|
9
|
+
# when a constant is reassigned in the same file and namespace using the
|
10
|
+
# `NAME = value` syntax.
|
11
|
+
#
|
12
|
+
# The cop cannot catch all offenses, like, for example, when a constant
|
13
|
+
# is reassigned in another file, or when using metaprogramming (`Module#const_set`).
|
14
|
+
#
|
15
|
+
# The cop only takes into account constants assigned in a "simple" way: directly
|
16
|
+
# inside class/module definition, or within another constant. Other type of assignments
|
17
|
+
# (e.g., inside a conditional) are disregarded.
|
18
|
+
#
|
19
|
+
# The cop also tracks constant removal using `Module#remove_const` with symbol
|
20
|
+
# or string argument.
|
21
|
+
#
|
22
|
+
# @example
|
23
|
+
# # bad
|
24
|
+
# X = :foo
|
25
|
+
# X = :bar
|
26
|
+
#
|
27
|
+
# # bad
|
28
|
+
# class A
|
29
|
+
# X = :foo
|
30
|
+
# X = :bar
|
31
|
+
# end
|
32
|
+
#
|
33
|
+
# # bad
|
34
|
+
# module A
|
35
|
+
# X = :foo
|
36
|
+
# X = :bar
|
37
|
+
# end
|
38
|
+
#
|
39
|
+
# # good - keep only one assignment
|
40
|
+
# X = :bar
|
41
|
+
#
|
42
|
+
# class A
|
43
|
+
# X = :bar
|
44
|
+
# end
|
45
|
+
#
|
46
|
+
# module A
|
47
|
+
# X = :bar
|
48
|
+
# end
|
49
|
+
#
|
50
|
+
# # good - use OR assignment
|
51
|
+
# X = :foo
|
52
|
+
# X ||= :bar
|
53
|
+
#
|
54
|
+
# # good - use conditional assignment
|
55
|
+
# X = :foo
|
56
|
+
# X = :bar unless defined?(X)
|
57
|
+
#
|
58
|
+
# # good - remove the assigned constant first
|
59
|
+
# class A
|
60
|
+
# X = :foo
|
61
|
+
# remove_const :X
|
62
|
+
# X = :bar
|
63
|
+
# end
|
64
|
+
#
|
65
|
+
class ConstantReassignment < Base
|
66
|
+
MSG = 'Constant `%<constant>s` is already assigned in this namespace.'
|
67
|
+
|
68
|
+
RESTRICT_ON_SEND = %i[remove_const].freeze
|
69
|
+
|
70
|
+
# @!method remove_constant(node)
|
71
|
+
def_node_matcher :remove_constant, <<~PATTERN
|
72
|
+
(send _ :remove_const
|
73
|
+
({sym str} $_))
|
74
|
+
PATTERN
|
75
|
+
|
76
|
+
def on_casgn(node)
|
77
|
+
return unless fixed_constant_path?(node)
|
78
|
+
return unless simple_assignment?(node)
|
79
|
+
return if constant_names.add?(fully_qualified_constant_name(node))
|
80
|
+
|
81
|
+
add_offense(node, message: format(MSG, constant: node.name))
|
82
|
+
end
|
83
|
+
|
84
|
+
def on_send(node)
|
85
|
+
constant = remove_constant(node)
|
86
|
+
|
87
|
+
return unless constant
|
88
|
+
|
89
|
+
namespaces = ancestor_namespaces(node)
|
90
|
+
|
91
|
+
return if namespaces.none?
|
92
|
+
|
93
|
+
constant_names.delete(fully_qualified_name_for(namespaces, constant))
|
94
|
+
end
|
95
|
+
|
96
|
+
private
|
97
|
+
|
98
|
+
def fixed_constant_path?(node)
|
99
|
+
node.each_path.all? { |path| path.type?(:cbase, :const, :self) }
|
100
|
+
end
|
101
|
+
|
102
|
+
def simple_assignment?(node)
|
103
|
+
node.ancestors.all? do |ancestor|
|
104
|
+
return true if ancestor.type?(:module, :class)
|
105
|
+
|
106
|
+
ancestor.begin_type? || ancestor.literal? || ancestor.casgn_type? ||
|
107
|
+
freeze_method?(ancestor)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def freeze_method?(node)
|
112
|
+
node.send_type? && node.method?(:freeze)
|
113
|
+
end
|
114
|
+
|
115
|
+
def fully_qualified_constant_name(node)
|
116
|
+
if node.absolute?
|
117
|
+
namespace = node.namespace.const_type? ? node.namespace.source : nil
|
118
|
+
|
119
|
+
"#{namespace}::#{node.name}"
|
120
|
+
else
|
121
|
+
constant_namespaces = ancestor_namespaces(node) + constant_namespaces(node)
|
122
|
+
|
123
|
+
fully_qualified_name_for(constant_namespaces, node.name)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
def fully_qualified_name_for(namespaces, constant)
|
128
|
+
['', *namespaces, constant].join('::')
|
129
|
+
end
|
130
|
+
|
131
|
+
def constant_namespaces(node)
|
132
|
+
node.each_path.select(&:const_type?).map(&:short_name)
|
133
|
+
end
|
134
|
+
|
135
|
+
def ancestor_namespaces(node)
|
136
|
+
node
|
137
|
+
.each_ancestor(:class, :module)
|
138
|
+
.map { |ancestor| ancestor.identifier.short_name }
|
139
|
+
.reverse
|
140
|
+
end
|
141
|
+
|
142
|
+
def constant_names
|
143
|
+
@constant_names ||= Set.new
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# rubocop:disable Lint/RedundantCopDisableDirective
|
4
|
+
# rubocop:disable Style/DoubleCopDisableDirective
|
5
|
+
module RuboCop
|
6
|
+
module Cop
|
7
|
+
module Lint
|
8
|
+
# Checks that `# rubocop:enable ...` and `# rubocop:disable ...` statements
|
9
|
+
# are strictly formatted.
|
10
|
+
#
|
11
|
+
# A comment can be added to the directive by prefixing it with `--`.
|
12
|
+
#
|
13
|
+
# @example
|
14
|
+
# # bad
|
15
|
+
# # rubocop:disable Layout/LineLength Style/Encoding
|
16
|
+
# # ^ missing comma
|
17
|
+
#
|
18
|
+
# # bad
|
19
|
+
# # rubocop:disable
|
20
|
+
#
|
21
|
+
# # bad
|
22
|
+
# # rubocop:disable Layout/LineLength # rubocop:disable Style/Encoding
|
23
|
+
#
|
24
|
+
# # bad
|
25
|
+
# # rubocop:wrongmode Layout/LineLength
|
26
|
+
#
|
27
|
+
# # good
|
28
|
+
# # rubocop:disable Layout/LineLength
|
29
|
+
#
|
30
|
+
# # good
|
31
|
+
# # rubocop:disable Layout/LineLength, Style/Encoding
|
32
|
+
#
|
33
|
+
# # good
|
34
|
+
# # rubocop:disable all
|
35
|
+
#
|
36
|
+
# # good
|
37
|
+
# # rubocop:disable Layout/LineLength -- This is a good comment.
|
38
|
+
#
|
39
|
+
class CopDirectiveSyntax < Base
|
40
|
+
COMMON_MSG = 'Malformed directive comment detected.'
|
41
|
+
|
42
|
+
MISSING_MODE_NAME_MSG = 'The mode name is missing.'
|
43
|
+
INVALID_MODE_NAME_MSG = 'The mode name must be one of `enable`, `disable`, or `todo`.'
|
44
|
+
MISSING_COP_NAME_MSG = 'The cop name is missing.'
|
45
|
+
MALFORMED_COP_NAMES_MSG = 'Cop names must be separated by commas. ' \
|
46
|
+
'Comment in the directive must start with `--`.'
|
47
|
+
|
48
|
+
def on_new_investigation
|
49
|
+
processed_source.comments.each do |comment|
|
50
|
+
directive_comment = DirectiveComment.new(comment)
|
51
|
+
next unless directive_comment.start_with_marker?
|
52
|
+
next unless directive_comment.malformed?
|
53
|
+
|
54
|
+
message = offense_message(directive_comment)
|
55
|
+
add_offense(comment, message: message)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
# rubocop:disable Metrics/MethodLength
|
62
|
+
def offense_message(directive_comment)
|
63
|
+
comment = directive_comment.comment
|
64
|
+
after_marker = comment.text.sub(DirectiveComment::DIRECTIVE_MARKER_REGEXP, '')
|
65
|
+
mode = after_marker.split(' ', 2).first
|
66
|
+
additional_msg = if mode.nil?
|
67
|
+
MISSING_MODE_NAME_MSG
|
68
|
+
elsif !DirectiveComment::AVAILABLE_MODES.include?(mode)
|
69
|
+
INVALID_MODE_NAME_MSG
|
70
|
+
elsif directive_comment.missing_cop_name?
|
71
|
+
MISSING_COP_NAME_MSG
|
72
|
+
else
|
73
|
+
MALFORMED_COP_NAMES_MSG
|
74
|
+
end
|
75
|
+
|
76
|
+
"#{COMMON_MSG} #{additional_msg}"
|
77
|
+
end
|
78
|
+
# rubocop:enable Metrics/MethodLength
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
# rubocop:enable Lint/RedundantCopDisableDirective
|
84
|
+
# rubocop:enable Style/DoubleCopDisableDirective
|
@@ -116,7 +116,7 @@ module RuboCop
|
|
116
116
|
|
117
117
|
def assumed_usage_context?(node)
|
118
118
|
# Basically, debugger methods are not used as a method argument without arguments.
|
119
|
-
return false unless node.arguments.empty? && node.each_ancestor(:
|
119
|
+
return false unless node.arguments.empty? && node.each_ancestor(:call).any?
|
120
120
|
return true if assumed_argument?(node)
|
121
121
|
|
122
122
|
node.each_ancestor.none? do |ancestor|
|
@@ -33,6 +33,7 @@ module RuboCop
|
|
33
33
|
|
34
34
|
MSG = 'Use `%<constant>s.%<method>s(%<replacement_args>s)` instead of `%<original>s`.'
|
35
35
|
|
36
|
+
RESTRICT_ON_SEND = %i[new digest].freeze
|
36
37
|
NO_ARG_ALGORITHM = %w[BF DES IDEA RC4].freeze
|
37
38
|
|
38
39
|
# @!method algorithm_const(node)
|
@@ -51,7 +52,7 @@ module RuboCop
|
|
51
52
|
PATTERN
|
52
53
|
|
53
54
|
def on_send(node)
|
54
|
-
return if node.arguments.any? { |arg| arg.variable? || arg.
|
55
|
+
return if node.arguments.any? { |arg| arg.variable? || arg.call_type? || arg.const_type? }
|
55
56
|
return if digest_const?(node.receiver)
|
56
57
|
return unless algorithm_const(node)
|
57
58
|
|