rubocop 1.68.0 → 1.69.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/README.md +1 -1
 - data/config/default.yml +41 -6
 - data/lib/rubocop/cop/base.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/for_to_each_corrector.rb +1 -1
 - 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/internal_affairs/location_line_equality_comparison.rb +2 -4
 - data/lib/rubocop/cop/internal_affairs/numblock_handler.rb +1 -1
 - data/lib/rubocop/cop/internal_affairs/operator_keyword.rb +46 -0
 - data/lib/rubocop/cop/internal_affairs/style_detected_api_use.rb +0 -2
 - data/lib/rubocop/cop/internal_affairs.rb +1 -0
 - data/lib/rubocop/cop/layout/argument_alignment.rb +1 -2
 - 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 +1 -2
 - data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +1 -1
 - data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +2 -3
 - data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +3 -4
 - data/lib/rubocop/cop/layout/empty_lines_around_method_body.rb +3 -1
 - data/lib/rubocop/cop/layout/indentation_width.rb +7 -7
 - data/lib/rubocop/cop/layout/leading_comment_space.rb +15 -0
 - data/lib/rubocop/cop/layout/line_length.rb +118 -4
 - data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +1 -1
 - 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 +3 -35
 - data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +3 -2
 - data/lib/rubocop/cop/layout/space_around_keyword.rb +1 -1
 - data/lib/rubocop/cop/layout/space_around_operators.rb +16 -17
 - data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +6 -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/lint/binary_operator_with_identical_operands.rb +11 -12
 - data/lib/rubocop/cop/lint/circular_argument_reference.rb +2 -0
 - data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +1 -1
 - data/lib/rubocop/cop/lint/empty_ensure.rb +1 -1
 - 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 +14 -6
 - data/lib/rubocop/cop/lint/float_out_of_range.rb +1 -3
 - data/lib/rubocop/cop/lint/hash_new_with_keyword_arguments_as_default.rb +55 -0
 - 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_assignment_in_condition.rb +1 -1
 - data/lib/rubocop/cop/lint/mixed_case_range.rb +2 -5
 - data/lib/rubocop/cop/lint/nested_method_definition.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 +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 +106 -0
 - data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +1 -2
 - data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +1 -1
 - data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +1 -1
 - 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/regexp_as_condition.rb +0 -1
 - data/lib/rubocop/cop/lint/rescue_type.rb +3 -7
 - data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +2 -0
 - 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/unused_method_argument.rb +18 -2
 - data/lib/rubocop/cop/lint/useless_defined.rb +55 -0
 - data/lib/rubocop/cop/lint/useless_rescue.rb +1 -1
 - data/lib/rubocop/cop/lint/useless_setter_call.rb +14 -25
 - data/lib/rubocop/cop/lint/void.rb +3 -2
 - data/lib/rubocop/cop/metrics/class_length.rb +7 -7
 - data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +1 -1
 - data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +1 -2
 - data/lib/rubocop/cop/mixin/check_assignment.rb +4 -12
 - data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +49 -0
 - data/lib/rubocop/cop/mixin/dig_help.rb +27 -0
 - data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +5 -9
 - data/lib/rubocop/cop/mixin/range_help.rb +0 -1
 - data/lib/rubocop/cop/mixin/target_ruby_version.rb +17 -1
 - 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/rescued_exceptions_variable_name.rb +3 -11
 - data/lib/rubocop/cop/naming/variable_name.rb +3 -4
 - data/lib/rubocop/cop/naming/variable_number.rb +2 -3
 - data/lib/rubocop/cop/style/access_modifier_declarations.rb +53 -24
 - data/lib/rubocop/cop/style/ambiguous_endless_method_definition.rb +1 -1
 - data/lib/rubocop/cop/style/array_intersect.rb +5 -4
 - data/lib/rubocop/cop/style/bitwise_predicate.rb +1 -1
 - data/lib/rubocop/cop/style/block_delimiters.rb +1 -1
 - data/lib/rubocop/cop/style/case_like_if.rb +8 -11
 - data/lib/rubocop/cop/style/commented_keyword.rb +11 -1
 - data/lib/rubocop/cop/style/conditional_assignment.rb +19 -21
 - data/lib/rubocop/cop/style/constant_visibility.rb +3 -12
 - data/lib/rubocop/cop/style/dig_chain.rb +90 -0
 - data/lib/rubocop/cop/style/file_null.rb +73 -0
 - data/lib/rubocop/cop/style/file_touch.rb +75 -0
 - data/lib/rubocop/cop/style/for.rb +0 -1
 - data/lib/rubocop/cop/style/global_vars.rb +1 -3
 - data/lib/rubocop/cop/style/guard_clause.rb +1 -1
 - data/lib/rubocop/cop/style/hash_conversion.rb +1 -2
 - data/lib/rubocop/cop/style/if_inside_else.rb +0 -1
 - data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +1 -2
 - data/lib/rubocop/cop/style/if_with_semicolon.rb +14 -5
 - data/lib/rubocop/cop/style/inverse_methods.rb +0 -1
 - data/lib/rubocop/cop/style/keyword_arguments_merging.rb +2 -2
 - data/lib/rubocop/cop/style/lambda_call.rb +0 -1
 - data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +1 -1
 - data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +7 -11
 - data/lib/rubocop/cop/style/missing_respond_to_missing.rb +33 -3
 - data/lib/rubocop/cop/style/multiline_memoization.rb +1 -1
 - data/lib/rubocop/cop/style/mutable_constant.rb +4 -5
 - data/lib/rubocop/cop/style/negated_if_else_condition.rb +6 -4
 - 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/one_line_conditional.rb +25 -4
 - 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 +8 -13
 - data/lib/rubocop/cop/style/raise_args.rb +1 -1
 - data/lib/rubocop/cop/style/redundant_assignment.rb +1 -1
 - data/lib/rubocop/cop/style/redundant_condition.rb +36 -21
 - data/lib/rubocop/cop/style/redundant_line_continuation.rb +7 -6
 - data/lib/rubocop/cop/style/redundant_parentheses.rb +1 -1
 - data/lib/rubocop/cop/style/redundant_regexp_argument.rb +1 -0
 - data/lib/rubocop/cop/style/redundant_return.rb +2 -2
 - data/lib/rubocop/cop/style/redundant_self.rb +7 -14
 - data/lib/rubocop/cop/style/redundant_self_assignment.rb +7 -5
 - data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +4 -4
 - data/lib/rubocop/cop/style/redundant_sort.rb +1 -1
 - data/lib/rubocop/cop/style/rescue_modifier.rb +2 -3
 - data/lib/rubocop/cop/style/safe_navigation.rb +1 -1
 - 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/signal_exception.rb +2 -3
 - data/lib/rubocop/cop/style/single_argument_dig.rb +9 -5
 - data/lib/rubocop/cop/style/single_line_do_end_block.rb +13 -3
 - data/lib/rubocop/cop/style/sole_nested_conditional.rb +2 -3
 - data/lib/rubocop/cop/style/special_global_vars.rb +1 -1
 - data/lib/rubocop/cop/style/string_concatenation.rb +0 -1
 - data/lib/rubocop/cop/style/swap_values.rb +4 -15
 - data/lib/rubocop/cop/style/trailing_underscore_variable.rb +4 -4
 - data/lib/rubocop/cop/style/variable_interpolation.rb +1 -2
 - data/lib/rubocop/cop/variable_force.rb +4 -10
 - data/lib/rubocop/cops_documentation_generator.rb +9 -1
 - data/lib/rubocop/version.rb +1 -1
 - data/lib/rubocop.rb +8 -0
 - metadata +17 -8
 
| 
         @@ -12,7 +12,7 @@ module RuboCop 
     | 
|
| 
       12 
12 
     | 
    
         
             
                  # first parameter of the definition, then the closing brace should be
         
     | 
| 
       13 
13 
     | 
    
         
             
                  # on the same line as the last parameter of the definition.
         
     | 
| 
       14 
14 
     | 
    
         
             
                  #
         
     | 
| 
       15 
     | 
    
         
            -
                  # If  
     | 
| 
      
 15 
     | 
    
         
            +
                  # If a method definition's opening brace is on the line above the first
         
     | 
| 
       16 
16 
     | 
    
         
             
                  # parameter of the definition, then the closing brace should be on the
         
     | 
| 
       17 
17 
     | 
    
         
             
                  # line below the last parameter of the definition.
         
     | 
| 
       18 
18 
     | 
    
         
             
                  #
         
     | 
| 
         @@ -76,9 +76,8 @@ module RuboCop 
     | 
|
| 
       76 
76 
     | 
    
         
             
                    end
         
     | 
| 
       77 
77 
     | 
    
         | 
| 
       78 
78 
     | 
    
         
             
                    def check_and_or(node)
         
     | 
| 
       79 
     | 
    
         
            -
                      lhs, rhs  
     | 
| 
       80 
     | 
    
         
            -
                      range  
     | 
| 
       81 
     | 
    
         
            -
                      check(range, node, lhs, rhs.source_range)
         
     | 
| 
      
 79 
     | 
    
         
            +
                      range = offending_range(node, node.lhs, node.rhs.source_range, style)
         
     | 
| 
      
 80 
     | 
    
         
            +
                      check(range, node, node.lhs, node.rhs.source_range)
         
     | 
| 
       82 
81 
     | 
    
         
             
                    end
         
     | 
| 
       83 
82 
     | 
    
         | 
| 
       84 
83 
     | 
    
         
             
                    def offending_range(node, lhs, rhs, given_style)
         
     | 
| 
         @@ -3,11 +3,10 @@ 
     | 
|
| 
       3 
3 
     | 
    
         
             
            module RuboCop
         
     | 
| 
       4 
4 
     | 
    
         
             
              module Cop
         
     | 
| 
       5 
5 
     | 
    
         
             
                module Layout
         
     | 
| 
       6 
     | 
    
         
            -
                  #  
     | 
| 
       7 
     | 
    
         
            -
                  # definition are aligned.
         
     | 
| 
      
 6 
     | 
    
         
            +
                  # Check that the parameters on a multi-line method call or definition are aligned.
         
     | 
| 
       8 
7 
     | 
    
         
             
                  #
         
     | 
| 
       9 
     | 
    
         
            -
                  # To set the alignment of the first argument, use the 
     | 
| 
       10 
     | 
    
         
            -
                  # FirstParameterIndentation.
         
     | 
| 
      
 8 
     | 
    
         
            +
                  # To set the alignment of the first argument, use the
         
     | 
| 
      
 9 
     | 
    
         
            +
                  # `Layout/FirstParameterIndentation` cop.
         
     | 
| 
       11 
10 
     | 
    
         
             
                  #
         
     | 
| 
       12 
11 
     | 
    
         
             
                  # @example EnforcedStyle: with_first_parameter (default)
         
     | 
| 
       13 
12 
     | 
    
         
             
                  #   # good
         
     | 
| 
         @@ -44,6 +44,7 @@ module RuboCop 
     | 
|
| 
       44 
44 
     | 
    
         
             
                  #
         
     | 
| 
       45 
45 
     | 
    
         
             
                  class RedundantLineBreak < Base
         
     | 
| 
       46 
46 
     | 
    
         
             
                    include CheckAssignment
         
     | 
| 
      
 47 
     | 
    
         
            +
                    include CheckSingleLineSuitability
         
     | 
| 
       47 
48 
     | 
    
         
             
                    extend AutoCorrector
         
     | 
| 
       48 
49 
     | 
    
         | 
| 
       49 
50 
     | 
    
         
             
                    MSG = 'Redundant line break detected.'
         
     | 
| 
         @@ -84,8 +85,8 @@ module RuboCop 
     | 
|
| 
       84 
85 
     | 
    
         
             
                    end
         
     | 
| 
       85 
86 
     | 
    
         | 
| 
       86 
87 
     | 
    
         
             
                    def offense?(node)
         
     | 
| 
       87 
     | 
    
         
            -
                      return false  
     | 
| 
       88 
     | 
    
         
            -
                      return require_backslash?(node) if node. 
     | 
| 
      
 88 
     | 
    
         
            +
                      return false unless node.multiline? && suitable_as_single_line?(node)
         
     | 
| 
      
 89 
     | 
    
         
            +
                      return require_backslash?(node) if node.operator_keyword?
         
     | 
| 
       89 
90 
     | 
    
         | 
| 
       90 
91 
     | 
    
         
             
                      !index_access_call_chained?(node) && !configured_to_not_be_inspected?(node)
         
     | 
| 
       91 
92 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -117,44 +118,11 @@ module RuboCop 
     | 
|
| 
       117 
118 
     | 
    
         
             
                      @config.for_cop('Layout/SingleLineBlockChain')['Enabled']
         
     | 
| 
       118 
119 
     | 
    
         
             
                    end
         
     | 
| 
       119 
120 
     | 
    
         | 
| 
       120 
     | 
    
         
            -
                    def suitable_as_single_line?(node)
         
     | 
| 
       121 
     | 
    
         
            -
                      !comment_within?(node) &&
         
     | 
| 
       122 
     | 
    
         
            -
                        node.each_descendant(:if, :case, :kwbegin, :def, :defs).none? &&
         
     | 
| 
       123 
     | 
    
         
            -
                        node.each_descendant(:dstr, :str).none? { |n| n.heredoc? || n.value.include?("\n") } &&
         
     | 
| 
       124 
     | 
    
         
            -
                        node.each_descendant(:begin, :sym).none? { |b| !b.single_line? }
         
     | 
| 
       125 
     | 
    
         
            -
                    end
         
     | 
| 
       126 
     | 
    
         
            -
             
     | 
| 
       127 
121 
     | 
    
         
             
                    def convertible_block?(node)
         
     | 
| 
       128 
122 
     | 
    
         
             
                      parent = node.parent
         
     | 
| 
       129 
123 
     | 
    
         
             
                      parent&.block_type? && node == parent.send_node &&
         
     | 
| 
       130 
124 
     | 
    
         
             
                        (node.parenthesized? || !node.arguments?)
         
     | 
| 
       131 
125 
     | 
    
         
             
                    end
         
     | 
| 
       132 
     | 
    
         
            -
             
     | 
| 
       133 
     | 
    
         
            -
                    def comment_within?(node)
         
     | 
| 
       134 
     | 
    
         
            -
                      comment_line_numbers = processed_source.comments.map { |comment| comment.loc.line }
         
     | 
| 
       135 
     | 
    
         
            -
             
     | 
| 
       136 
     | 
    
         
            -
                      comment_line_numbers.any? do |comment_line_number|
         
     | 
| 
       137 
     | 
    
         
            -
                        comment_line_number >= node.first_line && comment_line_number <= node.last_line
         
     | 
| 
       138 
     | 
    
         
            -
                      end
         
     | 
| 
       139 
     | 
    
         
            -
                    end
         
     | 
| 
       140 
     | 
    
         
            -
             
     | 
| 
       141 
     | 
    
         
            -
                    def too_long?(node)
         
     | 
| 
       142 
     | 
    
         
            -
                      lines = processed_source.lines[(node.first_line - 1)...node.last_line]
         
     | 
| 
       143 
     | 
    
         
            -
                      to_single_line(lines.join("\n")).length > max_line_length
         
     | 
| 
       144 
     | 
    
         
            -
                    end
         
     | 
| 
       145 
     | 
    
         
            -
             
     | 
| 
       146 
     | 
    
         
            -
                    def to_single_line(source)
         
     | 
| 
       147 
     | 
    
         
            -
                      source
         
     | 
| 
       148 
     | 
    
         
            -
                        .gsub(/" *\\\n\s*'/, %q(" + ')) # Double quote, backslash, and then single quote
         
     | 
| 
       149 
     | 
    
         
            -
                        .gsub(/' *\\\n\s*"/, %q(' + ")) # Single quote, backslash, and then double quote
         
     | 
| 
       150 
     | 
    
         
            -
                        .gsub(/(["']) *\\\n\s*\1/, '')  # Double or single quote, backslash, then same quote
         
     | 
| 
       151 
     | 
    
         
            -
                        .gsub(/\n\s*(?=(&)?\.\w)/, '')  # Extra space within method chaining which includes `&.`
         
     | 
| 
       152 
     | 
    
         
            -
                        .gsub(/\s*\\?\n\s*/, ' ')       # Any other line break, with or without backslash
         
     | 
| 
       153 
     | 
    
         
            -
                    end
         
     | 
| 
       154 
     | 
    
         
            -
             
     | 
| 
       155 
     | 
    
         
            -
                    def max_line_length
         
     | 
| 
       156 
     | 
    
         
            -
                      config.for_cop('Layout/LineLength')['Max']
         
     | 
| 
       157 
     | 
    
         
            -
                    end
         
     | 
| 
       158 
126 
     | 
    
         
             
                  end
         
     | 
| 
       159 
127 
     | 
    
         
             
                end
         
     | 
| 
       160 
128 
     | 
    
         
             
              end
         
     | 
| 
         @@ -92,6 +92,7 @@ module RuboCop 
     | 
|
| 
       92 
92 
     | 
    
         
             
                      )
         
     | 
| 
       93 
93 
     | 
    
         
             
                    end
         
     | 
| 
       94 
94 
     | 
    
         | 
| 
      
 95 
     | 
    
         
            +
                    # rubocop:disable Metrics/AbcSize
         
     | 
| 
       95 
96 
     | 
    
         
             
                    def alignment_source(node, starting_loc)
         
     | 
| 
       96 
97 
     | 
    
         
             
                      ending_loc =
         
     | 
| 
       97 
98 
     | 
    
         
             
                        case node.type
         
     | 
| 
         @@ -101,8 +102,7 @@ module RuboCop 
     | 
|
| 
       101 
102 
     | 
    
         
             
                             :lvasgn, :ivasgn, :cvasgn, :gvasgn, :casgn
         
     | 
| 
       102 
103 
     | 
    
         
             
                          node.loc.name
         
     | 
| 
       103 
104 
     | 
    
         
             
                        when :masgn
         
     | 
| 
       104 
     | 
    
         
            -
                           
     | 
| 
       105 
     | 
    
         
            -
                          mlhs_node.source_range
         
     | 
| 
      
 105 
     | 
    
         
            +
                          node.lhs.source_range
         
     | 
| 
       106 
106 
     | 
    
         
             
                        else
         
     | 
| 
       107 
107 
     | 
    
         
             
                          # It is a wrapper with receiver of object attribute or access modifier.
         
     | 
| 
       108 
108 
     | 
    
         
             
                          node.receiver&.source_range || node.child_nodes.first.loc.name
         
     | 
| 
         @@ -110,6 +110,7 @@ module RuboCop 
     | 
|
| 
       110 
110 
     | 
    
         | 
| 
       111 
111 
     | 
    
         
             
                      range_between(starting_loc.begin_pos, ending_loc.end_pos).source
         
     | 
| 
       112 
112 
     | 
    
         
             
                    end
         
     | 
| 
      
 113 
     | 
    
         
            +
                    # rubocop:enable Metrics/AbcSize
         
     | 
| 
       113 
114 
     | 
    
         | 
| 
       114 
115 
     | 
    
         
             
                    # We will use ancestor or wrapper with access modifier.
         
     | 
| 
       115 
116 
     | 
    
         | 
| 
         @@ -256,7 +256,7 @@ module RuboCop 
     | 
|
| 
       256 
256 
     | 
    
         
             
                      # regular dotted method calls bind more tightly than operators
         
     | 
| 
       257 
257 
     | 
    
         
             
                      # so we need to climb up the AST past them
         
     | 
| 
       258 
258 
     | 
    
         
             
                      node.each_ancestor do |ancestor|
         
     | 
| 
       259 
     | 
    
         
            -
                        return true if ancestor. 
     | 
| 
      
 259 
     | 
    
         
            +
                        return true if ancestor.operator_keyword? || ancestor.range_type?
         
     | 
| 
       260 
260 
     | 
    
         
             
                        return false unless ancestor.send_type?
         
     | 
| 
       261 
261 
     | 
    
         
             
                        return true if ancestor.operator_method?
         
     | 
| 
       262 
262 
     | 
    
         
             
                      end
         
     | 
| 
         @@ -99,51 +99,50 @@ module RuboCop 
     | 
|
| 
       99 
99 
     | 
    
         
             
                    def on_resbody(node)
         
     | 
| 
       100 
100 
     | 
    
         
             
                      return unless node.loc.assoc
         
     | 
| 
       101 
101 
     | 
    
         | 
| 
       102 
     | 
    
         
            -
                       
     | 
| 
       103 
     | 
    
         
            -
             
     | 
| 
       104 
     | 
    
         
            -
                      check_operator(:resbody, node.loc.assoc, variable)
         
     | 
| 
      
 102 
     | 
    
         
            +
                      check_operator(:resbody, node.loc.assoc, node.exception_variable)
         
     | 
| 
       105 
103 
     | 
    
         
             
                    end
         
     | 
| 
       106 
104 
     | 
    
         | 
| 
       107 
105 
     | 
    
         
             
                    def on_send(node)
         
     | 
| 
       108 
106 
     | 
    
         
             
                      return if rational_literal?(node)
         
     | 
| 
       109 
107 
     | 
    
         | 
| 
       110 
108 
     | 
    
         
             
                      if node.setter_method?
         
     | 
| 
       111 
     | 
    
         
            -
                         
     | 
| 
      
 109 
     | 
    
         
            +
                        on_setter_method(node)
         
     | 
| 
       112 
110 
     | 
    
         
             
                      elsif regular_operator?(node)
         
     | 
| 
       113 
111 
     | 
    
         
             
                        check_operator(:send, node.loc.selector, node.first_argument)
         
     | 
| 
       114 
112 
     | 
    
         
             
                      end
         
     | 
| 
       115 
113 
     | 
    
         
             
                    end
         
     | 
| 
       116 
114 
     | 
    
         | 
| 
       117 
115 
     | 
    
         
             
                    def on_assignment(node)
         
     | 
| 
       118 
     | 
    
         
            -
                       
     | 
| 
      
 116 
     | 
    
         
            +
                      rhs = node.rhs
         
     | 
| 
       119 
117 
     | 
    
         | 
| 
       120 
118 
     | 
    
         
             
                      return unless rhs
         
     | 
| 
       121 
119 
     | 
    
         | 
| 
       122 
     | 
    
         
            -
                       
     | 
| 
      
 120 
     | 
    
         
            +
                      type = node.op_asgn_type? ? :special_asgn : :assignment
         
     | 
| 
      
 121 
     | 
    
         
            +
                      check_operator(type, node.loc.operator, rhs)
         
     | 
| 
       123 
122 
     | 
    
         
             
                    end
         
     | 
| 
       124 
123 
     | 
    
         | 
| 
       125 
     | 
    
         
            -
                    def  
     | 
| 
       126 
     | 
    
         
            -
                       
     | 
| 
      
 124 
     | 
    
         
            +
                    def on_class(node)
         
     | 
| 
      
 125 
     | 
    
         
            +
                      rhs = node.parent_class
         
     | 
| 
       127 
126 
     | 
    
         | 
| 
       128 
     | 
    
         
            -
                      return unless  
     | 
| 
      
 127 
     | 
    
         
            +
                      return unless rhs
         
     | 
| 
       129 
128 
     | 
    
         | 
| 
       130 
     | 
    
         
            -
                      check_operator(: 
     | 
| 
      
 129 
     | 
    
         
            +
                      check_operator(:class, node.loc.operator, rhs)
         
     | 
| 
       131 
130 
     | 
    
         
             
                    end
         
     | 
| 
       132 
131 
     | 
    
         | 
| 
       133 
132 
     | 
    
         
             
                    def on_binary(node)
         
     | 
| 
       134 
     | 
    
         
            -
                       
     | 
| 
      
 133 
     | 
    
         
            +
                      rhs = node.rhs
         
     | 
| 
       135 
134 
     | 
    
         | 
| 
       136 
135 
     | 
    
         
             
                      return unless rhs
         
     | 
| 
       137 
136 
     | 
    
         | 
| 
       138 
137 
     | 
    
         
             
                      check_operator(:binary, node.loc.operator, rhs)
         
     | 
| 
       139 
138 
     | 
    
         
             
                    end
         
     | 
| 
       140 
139 
     | 
    
         | 
| 
       141 
     | 
    
         
            -
                    def  
     | 
| 
       142 
     | 
    
         
            -
                       
     | 
| 
      
 140 
     | 
    
         
            +
                    def on_setter_method(node)
         
     | 
| 
      
 141 
     | 
    
         
            +
                      rhs = node.first_argument
         
     | 
| 
       143 
142 
     | 
    
         | 
| 
       144 
     | 
    
         
            -
                      return unless  
     | 
| 
      
 143 
     | 
    
         
            +
                      return unless rhs
         
     | 
| 
       145 
144 
     | 
    
         | 
| 
       146 
     | 
    
         
            -
                      check_operator(:special_asgn, node.loc.operator,  
     | 
| 
      
 145 
     | 
    
         
            +
                      check_operator(:special_asgn, node.loc.operator, node.first_argument)
         
     | 
| 
       147 
146 
     | 
    
         
             
                    end
         
     | 
| 
       148 
147 
     | 
    
         | 
| 
       149 
148 
     | 
    
         
             
                    def on_match_pattern(node)
         
     | 
| 
         @@ -155,14 +154,14 @@ module RuboCop 
     | 
|
| 
       155 
154 
     | 
    
         
             
                    alias on_or       on_binary
         
     | 
| 
       156 
155 
     | 
    
         
             
                    alias on_and      on_binary
         
     | 
| 
       157 
156 
     | 
    
         
             
                    alias on_lvasgn   on_assignment
         
     | 
| 
      
 157 
     | 
    
         
            +
                    alias on_casgn    on_assignment
         
     | 
| 
       158 
158 
     | 
    
         
             
                    alias on_masgn    on_assignment
         
     | 
| 
       159 
159 
     | 
    
         
             
                    alias on_ivasgn   on_assignment
         
     | 
| 
       160 
160 
     | 
    
         
             
                    alias on_cvasgn   on_assignment
         
     | 
| 
       161 
161 
     | 
    
         
             
                    alias on_gvasgn   on_assignment
         
     | 
| 
       162 
     | 
    
         
            -
                    alias on_class    on_binary
         
     | 
| 
       163 
162 
     | 
    
         
             
                    alias on_or_asgn  on_assignment
         
     | 
| 
       164 
163 
     | 
    
         
             
                    alias on_and_asgn on_assignment
         
     | 
| 
       165 
     | 
    
         
            -
                    alias on_op_asgn   
     | 
| 
      
 164 
     | 
    
         
            +
                    alias on_op_asgn  on_assignment
         
     | 
| 
       166 
165 
     | 
    
         | 
| 
       167 
166 
     | 
    
         
             
                    private
         
     | 
| 
       168 
167 
     | 
    
         | 
| 
         @@ -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
         
     | 
| 
         @@ -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,20 @@ module RuboCop 
     | 
|
| 
       47 
45 
     | 
    
         
             
                  #
         
     | 
| 
       48 
46 
     | 
    
         
             
                  class BinaryOperatorWithIdenticalOperands < Base
         
     | 
| 
       49 
47 
     | 
    
         
             
                    MSG = 'Binary operator `%<op>s` has identical operands.'
         
     | 
| 
       50 
     | 
    
         
            -
                     
     | 
| 
      
 48 
     | 
    
         
            +
                    MATH_OPERATORS = %i[- + * / ** << >>].to_set.freeze
         
     | 
| 
       51 
49 
     | 
    
         | 
| 
       52 
50 
     | 
    
         
             
                    def on_send(node)
         
     | 
| 
       53 
51 
     | 
    
         
             
                      return unless node.binary_operation?
         
     | 
| 
      
 52 
     | 
    
         
            +
                      return if MATH_OPERATORS.include?(node.method_name)
         
     | 
| 
      
 53 
     | 
    
         
            +
                      return unless node.receiver == node.first_argument
         
     | 
| 
       54 
54 
     | 
    
         | 
| 
       55 
     | 
    
         
            -
                       
     | 
| 
       56 
     | 
    
         
            -
                      return if ALLOWED_MATH_OPERATORS.include?(node.method_name)
         
     | 
| 
       57 
     | 
    
         
            -
             
     | 
| 
       58 
     | 
    
         
            -
                      add_offense(node, message: format(MSG, op: operation)) if lhs == rhs
         
     | 
| 
      
 55 
     | 
    
         
            +
                      add_offense(node, message: format(MSG, op: node.method_name))
         
     | 
| 
       59 
56 
     | 
    
         
             
                    end
         
     | 
| 
       60 
57 
     | 
    
         | 
| 
       61 
58 
     | 
    
         
             
                    def on_and(node)
         
     | 
| 
       62 
     | 
    
         
            -
                       
     | 
| 
      
 59 
     | 
    
         
            +
                      return unless node.lhs == node.rhs
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
      
 61 
     | 
    
         
            +
                      add_offense(node, message: format(MSG, op: node.operator))
         
     | 
| 
       63 
62 
     | 
    
         
             
                    end
         
     | 
| 
       64 
63 
     | 
    
         
             
                    alias on_or on_and
         
     | 
| 
       65 
64 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -51,7 +51,7 @@ module RuboCop 
     | 
|
| 
       51 
51 
     | 
    
         
             
                    PATTERN
         
     | 
| 
       52 
52 
     | 
    
         | 
| 
       53 
53 
     | 
    
         
             
                    def on_send(node)
         
     | 
| 
       54 
     | 
    
         
            -
                      return if node.arguments.any? { |arg| arg.variable? || arg. 
     | 
| 
      
 54 
     | 
    
         
            +
                      return if node.arguments.any? { |arg| arg.variable? || arg.call_type? || arg.const_type? }
         
     | 
| 
       55 
55 
     | 
    
         
             
                      return if digest_const?(node.receiver)
         
     | 
| 
       56 
56 
     | 
    
         
             
                      return unless algorithm_const(node)
         
     | 
| 
       57 
57 
     | 
    
         | 
| 
         @@ -43,7 +43,7 @@ module RuboCop 
     | 
|
| 
       43 
43 
     | 
    
         
             
                    MSG = 'Do not return from an `ensure` block.'
         
     | 
| 
       44 
44 
     | 
    
         | 
| 
       45 
45 
     | 
    
         
             
                    def on_ensure(node)
         
     | 
| 
       46 
     | 
    
         
            -
                      node. 
     | 
| 
      
 46 
     | 
    
         
            +
                      node.branch&.each_node(:return) { |return_node| add_offense(return_node) }
         
     | 
| 
       47 
47 
     | 
    
         
             
                    end
         
     | 
| 
       48 
48 
     | 
    
         
             
                  end
         
     | 
| 
       49 
49 
     | 
    
         
             
                end
         
     | 
| 
         @@ -29,6 +29,9 @@ module RuboCop 
     | 
|
| 
       29 
29 
     | 
    
         
             
                  #   tolerance = 0.0001
         
     | 
| 
       30 
30 
     | 
    
         
             
                  #   (x - 0.1).abs < tolerance
         
     | 
| 
       31 
31 
     | 
    
         
             
                  #
         
     | 
| 
      
 32 
     | 
    
         
            +
                  #   # good - comparing against nil
         
     | 
| 
      
 33 
     | 
    
         
            +
                  #   Float(x, exception: false) == nil
         
     | 
| 
      
 34 
     | 
    
         
            +
                  #
         
     | 
| 
       32 
35 
     | 
    
         
             
                  #   # Or some other epsilon based type of comparison:
         
     | 
| 
       33 
36 
     | 
    
         
             
                  #   # https://www.embeddeduse.com/2019/08/26/qt-compare-two-floats/
         
     | 
| 
       34 
37 
     | 
    
         
             
                  #
         
     | 
| 
         @@ -42,8 +45,12 @@ module RuboCop 
     | 
|
| 
       42 
45 
     | 
    
         
             
                    RESTRICT_ON_SEND = EQUALITY_METHODS
         
     | 
| 
       43 
46 
     | 
    
         | 
| 
       44 
47 
     | 
    
         
             
                    def on_send(node)
         
     | 
| 
       45 
     | 
    
         
            -
                       
     | 
| 
       46 
     | 
    
         
            -
             
     | 
| 
      
 48 
     | 
    
         
            +
                      return unless node.arguments.one?
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
                      lhs = node.receiver
         
     | 
| 
      
 51 
     | 
    
         
            +
                      rhs = node.first_argument
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
                      return if literal_safe?(lhs) || literal_safe?(rhs)
         
     | 
| 
       47 
54 
     | 
    
         | 
| 
       48 
55 
     | 
    
         
             
                      add_offense(node) if float?(lhs) || float?(rhs)
         
     | 
| 
       49 
56 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -65,15 +72,16 @@ module RuboCop 
     | 
|
| 
       65 
72 
     | 
    
         
             
                      end
         
     | 
| 
       66 
73 
     | 
    
         
             
                    end
         
     | 
| 
       67 
74 
     | 
    
         | 
| 
       68 
     | 
    
         
            -
                    def  
     | 
| 
       69 
     | 
    
         
            -
                       
     | 
| 
      
 75 
     | 
    
         
            +
                    def literal_safe?(node)
         
     | 
| 
      
 76 
     | 
    
         
            +
                      return false unless node
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
      
 78 
     | 
    
         
            +
                      (node.numeric_type? && node.value.zero?) || node.nil_type?
         
     | 
| 
       70 
79 
     | 
    
         
             
                    end
         
     | 
| 
       71 
80 
     | 
    
         | 
| 
       72 
81 
     | 
    
         
             
                    # rubocop:disable Metrics/PerceivedComplexity
         
     | 
| 
       73 
82 
     | 
    
         
             
                    def check_send(node)
         
     | 
| 
       74 
83 
     | 
    
         
             
                      if node.arithmetic_operation?
         
     | 
| 
       75 
     | 
    
         
            -
                         
     | 
| 
       76 
     | 
    
         
            -
                        float?(lhs) || float?(rhs)
         
     | 
| 
      
 84 
     | 
    
         
            +
                        float?(node.receiver) || float?(node.first_argument)
         
     | 
| 
       77 
85 
     | 
    
         
             
                      elsif FLOAT_RETURNING_METHODS.include?(node.method_name)
         
     | 
| 
       78 
86 
     | 
    
         
             
                        true
         
     | 
| 
       79 
87 
     | 
    
         
             
                      elsif node.receiver&.float_type?
         
     | 
| 
         @@ -18,9 +18,7 @@ module RuboCop 
     | 
|
| 
       18 
18 
     | 
    
         
             
                    MSG = 'Float out of range.'
         
     | 
| 
       19 
19 
     | 
    
         | 
| 
       20 
20 
     | 
    
         
             
                    def on_float(node)
         
     | 
| 
       21 
     | 
    
         
            -
                      value 
     | 
| 
       22 
     | 
    
         
            -
             
     | 
| 
       23 
     | 
    
         
            -
                      return unless value.infinite? || (value.zero? && /[1-9]/.match?(node.source))
         
     | 
| 
      
 21 
     | 
    
         
            +
                      return unless node.value.infinite? || (node.value.zero? && /[1-9]/.match?(node.source))
         
     | 
| 
       24 
22 
     | 
    
         | 
| 
       25 
23 
     | 
    
         
             
                      add_offense(node)
         
     | 
| 
       26 
24 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -0,0 +1,55 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module RuboCop
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Cop
         
     | 
| 
      
 5 
     | 
    
         
            +
                module Lint
         
     | 
| 
      
 6 
     | 
    
         
            +
                  # Checks for the deprecated use of keyword arguments as a default in `Hash.new`.
         
     | 
| 
      
 7 
     | 
    
         
            +
                  #
         
     | 
| 
      
 8 
     | 
    
         
            +
                  # This usage raises a warning in Ruby 3.3 and results in an error in Ruby 3.4.
         
     | 
| 
      
 9 
     | 
    
         
            +
                  # In Ruby 3.4, keyword arguments will instead be used to change the behavior of a hash.
         
     | 
| 
      
 10 
     | 
    
         
            +
                  # For example, the capacity option can be passed to create a hash with a certain size
         
     | 
| 
      
 11 
     | 
    
         
            +
                  # if you know it in advance, for better performance.
         
     | 
| 
      
 12 
     | 
    
         
            +
                  #
         
     | 
| 
      
 13 
     | 
    
         
            +
                  # NOTE: The following corner case may result in a false negative when upgrading from Ruby 3.3
         
     | 
| 
      
 14 
     | 
    
         
            +
                  # or earlier, but it is intentionally not detected to respect the expected usage in Ruby 3.4.
         
     | 
| 
      
 15 
     | 
    
         
            +
                  #
         
     | 
| 
      
 16 
     | 
    
         
            +
                  # [source,ruby]
         
     | 
| 
      
 17 
     | 
    
         
            +
                  # ----
         
     | 
| 
      
 18 
     | 
    
         
            +
                  # Hash.new(capacity: 42)
         
     | 
| 
      
 19 
     | 
    
         
            +
                  # ----
         
     | 
| 
      
 20 
     | 
    
         
            +
                  #
         
     | 
| 
      
 21 
     | 
    
         
            +
                  # @example
         
     | 
| 
      
 22 
     | 
    
         
            +
                  #
         
     | 
| 
      
 23 
     | 
    
         
            +
                  #   # bad
         
     | 
| 
      
 24 
     | 
    
         
            +
                  #   Hash.new(key: :value)
         
     | 
| 
      
 25 
     | 
    
         
            +
                  #
         
     | 
| 
      
 26 
     | 
    
         
            +
                  #   # good
         
     | 
| 
      
 27 
     | 
    
         
            +
                  #   Hash.new({key: :value})
         
     | 
| 
      
 28 
     | 
    
         
            +
                  #
         
     | 
| 
      
 29 
     | 
    
         
            +
                  class HashNewWithKeywordArgumentsAsDefault < Base
         
     | 
| 
      
 30 
     | 
    
         
            +
                    extend AutoCorrector
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                    MSG = 'Use a hash literal instead of keyword arguments.'
         
     | 
| 
      
 33 
     | 
    
         
            +
                    RESTRICT_ON_SEND = %i[new].freeze
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                    # @!method hash_new(node)
         
     | 
| 
      
 36 
     | 
    
         
            +
                    def_node_matcher :hash_new, <<~PATTERN
         
     | 
| 
      
 37 
     | 
    
         
            +
                      (send (const {nil? (cbase)} :Hash) :new $[hash !braces?])
         
     | 
| 
      
 38 
     | 
    
         
            +
                    PATTERN
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                    def on_send(node)
         
     | 
| 
      
 41 
     | 
    
         
            +
                      return unless (first_argument = hash_new(node))
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
                      if first_argument.pairs.one?
         
     | 
| 
      
 44 
     | 
    
         
            +
                        key = first_argument.pairs.first.key
         
     | 
| 
      
 45 
     | 
    
         
            +
                        return if key.respond_to?(:value) && key.value == :capacity
         
     | 
| 
      
 46 
     | 
    
         
            +
                      end
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
                      add_offense(first_argument) do |corrector|
         
     | 
| 
      
 49 
     | 
    
         
            +
                        corrector.wrap(first_argument, '{', '}')
         
     | 
| 
      
 50 
     | 
    
         
            +
                      end
         
     | 
| 
      
 51 
     | 
    
         
            +
                    end
         
     | 
| 
      
 52 
     | 
    
         
            +
                  end
         
     | 
| 
      
 53 
     | 
    
         
            +
                end
         
     | 
| 
      
 54 
     | 
    
         
            +
              end
         
     | 
| 
      
 55 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -24,14 +24,17 @@ module RuboCop 
     | 
|
| 
       24 
24 
     | 
    
         
             
                    MSG = 'Interpolation in single quoted string detected. ' \
         
     | 
| 
       25 
25 
     | 
    
         
             
                          'Use double quoted strings if you need interpolation.'
         
     | 
| 
       26 
26 
     | 
    
         | 
| 
      
 27 
     | 
    
         
            +
                    # rubocop:disable Metrics/CyclomaticComplexity
         
     | 
| 
       27 
28 
     | 
    
         
             
                    def on_str(node)
         
     | 
| 
       28 
29 
     | 
    
         
             
                      return if node.parent&.regexp_type?
         
     | 
| 
       29 
30 
     | 
    
         
             
                      return unless /(?<!\\)#\{.*\}/.match?(node.source)
         
     | 
| 
       30 
31 
     | 
    
         
             
                      return if heredoc?(node)
         
     | 
| 
       31 
32 
     | 
    
         
             
                      return unless node.loc.begin && node.loc.end
         
     | 
| 
      
 33 
     | 
    
         
            +
                      return unless valid_syntax?(node)
         
     | 
| 
       32 
34 
     | 
    
         | 
| 
       33 
35 
     | 
    
         
             
                      add_offense(node) { |corrector| autocorrect(corrector, node) }
         
     | 
| 
       34 
36 
     | 
    
         
             
                    end
         
     | 
| 
      
 37 
     | 
    
         
            +
                    # rubocop:enable Metrics/CyclomaticComplexity
         
     | 
| 
       35 
38 
     | 
    
         | 
| 
       36 
39 
     | 
    
         
             
                    private
         
     | 
| 
       37 
40 
     | 
    
         | 
| 
         @@ -49,6 +52,12 @@ module RuboCop 
     | 
|
| 
       49 
52 
     | 
    
         
             
                    def heredoc?(node)
         
     | 
| 
       50 
53 
     | 
    
         
             
                      node.loc.is_a?(Parser::Source::Map::Heredoc) || (node.parent && heredoc?(node.parent))
         
     | 
| 
       51 
54 
     | 
    
         
             
                    end
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
                    def valid_syntax?(node)
         
     | 
| 
      
 57 
     | 
    
         
            +
                      double_quoted_string = node.source.gsub(/\A'|'\z/, '"')
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
                      parse(double_quoted_string).valid_syntax?
         
     | 
| 
      
 60 
     | 
    
         
            +
                    end
         
     | 
| 
       52 
61 
     | 
    
         
             
                  end
         
     | 
| 
       53 
62 
     | 
    
         
             
                end
         
     | 
| 
       54 
63 
     | 
    
         
             
              end
         
     | 
| 
         @@ -26,6 +26,9 @@ module RuboCop 
     | 
|
| 
       26 
26 
     | 
    
         
             
                  #
         
     | 
| 
       27 
27 
     | 
    
         
             
                  class ItWithoutArgumentsInBlock < Base
         
     | 
| 
       28 
28 
     | 
    
         
             
                    include NodePattern::Macros
         
     | 
| 
      
 29 
     | 
    
         
            +
                    extend TargetRubyVersion
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                    maximum_target_ruby_version 3.3
         
     | 
| 
       29 
32 
     | 
    
         | 
| 
       30 
33 
     | 
    
         
             
                    MSG = '`it` calls without arguments will refer to the first block param in Ruby 3.4; ' \
         
     | 
| 
       31 
34 
     | 
    
         
             
                          'use `it()` or `self.it`.'
         
     | 
| 
         @@ -40,7 +40,7 @@ module RuboCop 
     | 
|
| 
       40 
40 
     | 
    
         
             
                      traverse_node(node.condition) do |asgn_node|
         
     | 
| 
       41 
41 
     | 
    
         
             
                        next unless asgn_node.loc.operator
         
     | 
| 
       42 
42 
     | 
    
         | 
| 
       43 
     | 
    
         
            -
                        rhs = asgn_node. 
     | 
| 
      
 43 
     | 
    
         
            +
                        rhs = asgn_node.rhs
         
     | 
| 
       44 
44 
     | 
    
         
             
                        next if !all_literals?(rhs) || parallel_assignment_with_splat_operator?(rhs)
         
     | 
| 
       45 
45 
     | 
    
         | 
| 
       46 
46 
     | 
    
         
             
                        range = offense_range(asgn_node, rhs)
         
     | 
| 
         @@ -36,12 +36,9 @@ module RuboCop 
     | 
|
| 
       36 
36 
     | 
    
         | 
| 
       37 
37 
     | 
    
         
             
                    def on_irange(node)
         
     | 
| 
       38 
38 
     | 
    
         
             
                      return unless node.children.compact.all?(&:str_type?)
         
     | 
| 
      
 39 
     | 
    
         
            +
                      return if node.begin.nil? || node.end.nil?
         
     | 
| 
       39 
40 
     | 
    
         | 
| 
       40 
     | 
    
         
            -
                       
     | 
| 
       41 
     | 
    
         
            -
             
     | 
| 
       42 
     | 
    
         
            -
                      return if range_start.nil? || range_end.nil?
         
     | 
| 
       43 
     | 
    
         
            -
             
     | 
| 
       44 
     | 
    
         
            -
                      add_offense(node) if unsafe_range?(range_start.value, range_end.value)
         
     | 
| 
      
 41 
     | 
    
         
            +
                      add_offense(node) if unsafe_range?(node.begin.value, node.end.value)
         
     | 
| 
       45 
42 
     | 
    
         
             
                    end
         
     | 
| 
       46 
43 
     | 
    
         
             
                    alias on_erange on_irange
         
     | 
| 
       47 
44 
     | 
    
         | 
| 
         @@ -95,7 +95,7 @@ module RuboCop 
     | 
|
| 
       95 
95 
     | 
    
         
             
                    MSG = 'Method definitions must not be nested. Use `lambda` instead.'
         
     | 
| 
       96 
96 
     | 
    
         | 
| 
       97 
97 
     | 
    
         
             
                    def on_def(node)
         
     | 
| 
       98 
     | 
    
         
            -
                      subject, = *node
         
     | 
| 
      
 98 
     | 
    
         
            +
                      subject, = *node # rubocop:disable InternalAffairs/NodeDestructuring
         
     | 
| 
       99 
99 
     | 
    
         
             
                      return if node.defs_type? && subject.variable?
         
     | 
| 
       100 
100 
     | 
    
         | 
| 
       101 
101 
     | 
    
         
             
                      def_ancestor = node.each_ancestor(:def, :defs).first
         
     | 
| 
         @@ -95,7 +95,7 @@ module RuboCop 
     | 
|
| 
       95 
95 
     | 
    
         
             
                    end
         
     | 
| 
       96 
96 
     | 
    
         | 
| 
       97 
97 
     | 
    
         
             
                    def allowable_use_with_if?(if_node)
         
     | 
| 
       98 
     | 
    
         
            -
                      if_node.condition. 
     | 
| 
      
 98 
     | 
    
         
            +
                      if_node.condition.operator_keyword? || if_node.else_branch
         
     | 
| 
       99 
99 
     | 
    
         
             
                    end
         
     | 
| 
       100 
100 
     | 
    
         | 
| 
       101 
101 
     | 
    
         
             
                    def register_offense(node, exist_node)
         
     | 
| 
         @@ -33,8 +33,7 @@ module RuboCop 
     | 
|
| 
       33 
33 
     | 
    
         
             
                    NUMBERED_PARAMETER_RANGE = (1..9).freeze
         
     | 
| 
       34 
34 
     | 
    
         | 
| 
       35 
35 
     | 
    
         
             
                    def on_lvasgn(node)
         
     | 
| 
       36 
     | 
    
         
            -
                       
     | 
| 
       37 
     | 
    
         
            -
                      return unless /\A_(\d+)\z/ =~ lhs
         
     | 
| 
      
 36 
     | 
    
         
            +
                      return unless /\A_(\d+)\z/ =~ node.name
         
     | 
| 
       38 
37 
     | 
    
         | 
| 
       39 
38 
     | 
    
         
             
                      number = Regexp.last_match(1).to_i
         
     | 
| 
       40 
39 
     | 
    
         
             
                      template = NUMBERED_PARAMETER_RANGE.include?(number) ? NUM_PARAM_MSG : LVAR_MSG
         
     |