rubocop 1.68.0 → 1.69.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/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/generator.rb +6 -0
- data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +3 -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 +10 -12
- data/lib/rubocop/cop/lint/circular_argument_reference.rb +6 -0
- data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +2 -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_as_condition.rb +1 -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/non_deterministic_require_order.rb +3 -3
- 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/refinement_import_methods.rb +1 -1
- 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/unescaped_bracket_in_regexp.rb +3 -0
- data/lib/rubocop/cop/lint/unreachable_code.rb +51 -2
- 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_else_without_rescue.rb +4 -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 +2 -3
- 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/accessor_method_name.rb +6 -6
- 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/security/compound_hash.rb +1 -0
- data/lib/rubocop/cop/security/yaml_load.rb +3 -2
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +54 -25
- 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 +10 -2
- 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 +89 -0
- data/lib/rubocop/cop/style/fetch_env_var.rb +1 -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/hash_except.rb +19 -7
- 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 +3 -2
- 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/object_then.rb +1 -0
- 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_argument.rb +3 -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 +2 -2
- 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 +8 -15
- 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 +13 -12
- 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 +23 -14
| @@ -38,7 +38,7 @@ module RuboCop | |
| 38 38 | 
             
                  # * `Layout/MultilineHashKeyLineBreaks`
         | 
| 39 39 | 
             
                  # * `Layout/MultilineMethodArgumentLineBreaks`
         | 
| 40 40 | 
             
                  # * `Layout/MultilineMethodParameterLineBreaks`
         | 
| 41 | 
            -
                  # * `Layout | 
| 41 | 
            +
                  # * `Layout/ParameterAlignment`
         | 
| 42 42 | 
             
                  # * `Style/BlockDelimiters`
         | 
| 43 43 | 
             
                  #
         | 
| 44 44 | 
             
                  # Together, these cops will pretty print hashes, arrays,
         | 
| @@ -60,7 +60,7 @@ module RuboCop | |
| 60 60 | 
             
                  #     bar: "0000000000",
         | 
| 61 61 | 
             
                  #     baz: "0000000000",
         | 
| 62 62 | 
             
                  #   }
         | 
| 63 | 
            -
                  class LineLength < Base
         | 
| 63 | 
            +
                  class LineLength < Base # rubocop:disable Metrics/ClassLength
         | 
| 64 64 | 
             
                    include CheckLineBreakable
         | 
| 65 65 | 
             
                    include AllowedPattern
         | 
| 66 66 | 
             
                    include RangeHelp
         | 
| @@ -74,9 +74,16 @@ module RuboCop | |
| 74 74 | 
             
                    def on_block(node)
         | 
| 75 75 | 
             
                      check_for_breakable_block(node)
         | 
| 76 76 | 
             
                    end
         | 
| 77 | 
            -
             | 
| 78 77 | 
             
                    alias on_numblock on_block
         | 
| 79 78 |  | 
| 79 | 
            +
                    def on_str(node)
         | 
| 80 | 
            +
                      check_for_breakable_str(node)
         | 
| 81 | 
            +
                    end
         | 
| 82 | 
            +
             | 
| 83 | 
            +
                    def on_dstr(node)
         | 
| 84 | 
            +
                      check_for_breakable_dstr(node)
         | 
| 85 | 
            +
                    end
         | 
| 86 | 
            +
             | 
| 80 87 | 
             
                    def on_potential_breakable_node(node)
         | 
| 81 88 | 
             
                      check_for_breakable_node(node)
         | 
| 82 89 | 
             
                    end
         | 
| @@ -132,6 +139,42 @@ module RuboCop | |
| 132 139 | 
             
                      breakable_range_by_line_index[line_index] = range_between(pos, pos + 1)
         | 
| 133 140 | 
             
                    end
         | 
| 134 141 |  | 
| 142 | 
            +
                    def check_for_breakable_str(node)
         | 
| 143 | 
            +
                      line_index = node.loc.line - 1
         | 
| 144 | 
            +
                      return if breakable_range_by_line_index[line_index]
         | 
| 145 | 
            +
             | 
| 146 | 
            +
                      return unless breakable_string?(node)
         | 
| 147 | 
            +
                      return unless (delimiter = string_delimiter(node))
         | 
| 148 | 
            +
                      return unless (pos = breakable_string_position(node))
         | 
| 149 | 
            +
             | 
| 150 | 
            +
                      breakable_range_by_line_index[line_index] = range_between(pos, pos + 1)
         | 
| 151 | 
            +
                      breakable_string_delimiters[line_index] = delimiter
         | 
| 152 | 
            +
                    end
         | 
| 153 | 
            +
             | 
| 154 | 
            +
                    def check_for_breakable_dstr(node) # rubocop:disable Metrics/AbcSize
         | 
| 155 | 
            +
                      line_index = node.loc.line - 1
         | 
| 156 | 
            +
                      return if breakable_range_by_line_index[line_index]
         | 
| 157 | 
            +
             | 
| 158 | 
            +
                      return unless breakable_dstr?(node)
         | 
| 159 | 
            +
                      return unless (delimiter = string_delimiter(node))
         | 
| 160 | 
            +
             | 
| 161 | 
            +
                      node.each_child_node(:begin).detect do |begin_node|
         | 
| 162 | 
            +
                        next unless (pos = breakable_dstr_begin_position(begin_node))
         | 
| 163 | 
            +
             | 
| 164 | 
            +
                        breakable_range_by_line_index[line_index] = range_between(pos, pos + 1)
         | 
| 165 | 
            +
                        breakable_string_delimiters[line_index] = delimiter
         | 
| 166 | 
            +
                      end
         | 
| 167 | 
            +
                    end
         | 
| 168 | 
            +
             | 
| 169 | 
            +
                    def breakable_string?(node)
         | 
| 170 | 
            +
                      allow_string_split? &&
         | 
| 171 | 
            +
                        node.single_line? &&
         | 
| 172 | 
            +
                        !node.heredoc? &&
         | 
| 173 | 
            +
                        # TODO: strings inside hashes, kwargs and arrays are currently ignored,
         | 
| 174 | 
            +
                        # but could be considered in the future
         | 
| 175 | 
            +
                        !node.parent&.type?(:pair, :kwoptarg, :array)
         | 
| 176 | 
            +
                    end
         | 
| 177 | 
            +
             | 
| 135 178 | 
             
                    def breakable_block_range(block_node)
         | 
| 136 179 | 
             
                      if block_node.arguments? && !block_node.lambda?
         | 
| 137 180 | 
             
                        block_node.arguments.loc.end
         | 
| @@ -153,10 +196,47 @@ module RuboCop | |
| 153 196 | 
             
                      next_range
         | 
| 154 197 | 
             
                    end
         | 
| 155 198 |  | 
| 199 | 
            +
                    def breakable_string_position(node)
         | 
| 200 | 
            +
                      source_range = node.source_range
         | 
| 201 | 
            +
                      return if source_range.last_column < max
         | 
| 202 | 
            +
                      return unless (pos = breakable_string_range(node))
         | 
| 203 | 
            +
             | 
| 204 | 
            +
                      pos.end_pos unless pos.end_pos == source_range.begin_pos
         | 
| 205 | 
            +
                    end
         | 
| 206 | 
            +
             | 
| 207 | 
            +
                    # Locate where to break a string that is too long, ensuring that escape characters
         | 
| 208 | 
            +
                    # are not bisected.
         | 
| 209 | 
            +
                    # If the string contains spaces, use them to determine a place for a clean break;
         | 
| 210 | 
            +
                    # otherwise, the string will be broken at the line length limit.
         | 
| 211 | 
            +
                    def breakable_string_range(node) # rubocop:disable Metrics/AbcSize
         | 
| 212 | 
            +
                      source_range = node.source_range
         | 
| 213 | 
            +
                      relevant_substr = largest_possible_string(node)
         | 
| 214 | 
            +
             | 
| 215 | 
            +
                      if (space_pos = relevant_substr.rindex(/\s/))
         | 
| 216 | 
            +
                        source_range.resize(space_pos + 1)
         | 
| 217 | 
            +
                      elsif (escape_pos = relevant_substr.rindex(/\\(u[\da-f]{0,4}|x[\da-f]{0,2})?\z/))
         | 
| 218 | 
            +
                        source_range.resize(escape_pos)
         | 
| 219 | 
            +
                      else
         | 
| 220 | 
            +
                        adjustment = max - source_range.last_column - 3
         | 
| 221 | 
            +
                        return if adjustment.abs > source_range.size
         | 
| 222 | 
            +
             | 
| 223 | 
            +
                        source_range.adjust(end_pos: max - source_range.last_column - 3)
         | 
| 224 | 
            +
                      end
         | 
| 225 | 
            +
                    end
         | 
| 226 | 
            +
             | 
| 227 | 
            +
                    def breakable_dstr_begin_position(node)
         | 
| 228 | 
            +
                      source_range = node.source_range
         | 
| 229 | 
            +
                      source_range.begin_pos if source_range.begin_pos < max && source_range.end_pos >= max
         | 
| 230 | 
            +
                    end
         | 
| 231 | 
            +
             | 
| 156 232 | 
             
                    def breakable_range_by_line_index
         | 
| 157 233 | 
             
                      @breakable_range_by_line_index ||= {}
         | 
| 158 234 | 
             
                    end
         | 
| 159 235 |  | 
| 236 | 
            +
                    def breakable_string_delimiters
         | 
| 237 | 
            +
                      @breakable_string_delimiters ||= {}
         | 
| 238 | 
            +
                    end
         | 
| 239 | 
            +
             | 
| 160 240 | 
             
                    def heredocs
         | 
| 161 241 | 
             
                      @heredocs ||= extract_heredocs(processed_source.ast)
         | 
| 162 242 | 
             
                    end
         | 
| @@ -197,7 +277,14 @@ module RuboCop | |
| 197 277 |  | 
| 198 278 | 
             
                      add_offense(loc, message: message) do |corrector|
         | 
| 199 279 | 
             
                        self.max = line_length(line)
         | 
| 200 | 
            -
             | 
| 280 | 
            +
             | 
| 281 | 
            +
                        insertion = if (delimiter = breakable_string_delimiters[line_index])
         | 
| 282 | 
            +
                                      [delimiter, " \\\n", delimiter].join
         | 
| 283 | 
            +
                                    else
         | 
| 284 | 
            +
                                      "\n"
         | 
| 285 | 
            +
                                    end
         | 
| 286 | 
            +
             | 
| 287 | 
            +
                        corrector.insert_before(breakable_range, insertion) unless breakable_range.nil?
         | 
| 201 288 | 
             
                      end
         | 
| 202 289 | 
             
                    end
         | 
| 203 290 |  | 
| @@ -224,6 +311,10 @@ module RuboCop | |
| 224 311 | 
             
                      cop_config['AllowHeredoc']
         | 
| 225 312 | 
             
                    end
         | 
| 226 313 |  | 
| 314 | 
            +
                    def allow_string_split?
         | 
| 315 | 
            +
                      cop_config['SplitStrings']
         | 
| 316 | 
            +
                    end
         | 
| 317 | 
            +
             | 
| 227 318 | 
             
                    def extract_heredocs(ast)
         | 
| 228 319 | 
             
                      return [] unless ast
         | 
| 229 320 |  | 
| @@ -270,6 +361,29 @@ module RuboCop | |
| 270 361 |  | 
| 271 362 | 
             
                      register_offense(excess_range(uri_range, line, line_index), line, line_index)
         | 
| 272 363 | 
             
                    end
         | 
| 364 | 
            +
             | 
| 365 | 
            +
                    def breakable_dstr?(node)
         | 
| 366 | 
            +
                      # If the `dstr` only contains one child, it cannot be broken
         | 
| 367 | 
            +
                      breakable_string?(node) && !node.child_nodes.one?
         | 
| 368 | 
            +
                    end
         | 
| 369 | 
            +
             | 
| 370 | 
            +
                    def string_delimiter(node)
         | 
| 371 | 
            +
                      delimiter = node.loc.begin
         | 
| 372 | 
            +
                      delimiter ||= node.parent.loc.begin if node.parent&.dstr_type?
         | 
| 373 | 
            +
                      delimiter = delimiter&.source
         | 
| 374 | 
            +
             | 
| 375 | 
            +
                      delimiter if %w[' "].include?(delimiter)
         | 
| 376 | 
            +
                    end
         | 
| 377 | 
            +
             | 
| 378 | 
            +
                    # Find the largest possible substring of a string node to retain before a break
         | 
| 379 | 
            +
                    def largest_possible_string(node)
         | 
| 380 | 
            +
                      # The maximum allowed length of a string value is:
         | 
| 381 | 
            +
                      # `Max` - end delimiter (quote) - continuation characters (space and slash)
         | 
| 382 | 
            +
                      max_length = max - 3
         | 
| 383 | 
            +
                      # If the string doesn't start at the beginning of the line, the max length is offset
         | 
| 384 | 
            +
                      max_length -= column_offset_between(node.loc, node.parent.loc) if node.parent
         | 
| 385 | 
            +
                      node.source[0...(max_length)]
         | 
| 386 | 
            +
                    end
         | 
| 273 387 | 
             
                  end
         | 
| 274 388 | 
             
                end
         | 
| 275 389 | 
             
              end
         | 
| @@ -12,7 +12,7 @@ module RuboCop | |
| 12 12 | 
             
                  # argument of the call, then the closing brace should be on the same
         | 
| 13 13 | 
             
                  # line as the last argument of the call.
         | 
| 14 14 | 
             
                  #
         | 
| 15 | 
            -
                  # If  | 
| 15 | 
            +
                  # If a method call's opening brace is on the line above the first
         | 
| 16 16 | 
             
                  # argument of the call, then the closing brace should be on the line
         | 
| 17 17 | 
             
                  # below the last argument of the call.
         | 
| 18 18 | 
             
                  #
         | 
| @@ -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,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
         | 
| @@ -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 |  | 
| @@ -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
         |