rubocop 1.72.2 → 1.74.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 +3 -3
- data/config/default.yml +56 -15
- data/config/internal_affairs.yml +20 -0
- data/lib/rubocop/config_loader.rb +0 -1
- data/lib/rubocop/config_loader_resolver.rb +4 -3
- data/lib/rubocop/config_obsoletion/extracted_cop.rb +4 -3
- data/lib/rubocop/config_obsoletion.rb +1 -1
- data/lib/rubocop/config_validator.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/example_description.rb +3 -1
- data/lib/rubocop/cop/internal_affairs/node_type_group.rb +91 -0
- data/lib/rubocop/cop/internal_affairs.rb +1 -0
- data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +4 -4
- data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +26 -1
- data/lib/rubocop/cop/layout/line_length.rb +3 -3
- data/lib/rubocop/cop/lint/duplicate_methods.rb +0 -14
- data/lib/rubocop/cop/lint/empty_conditional_body.rb +14 -64
- data/lib/rubocop/cop/lint/erb_new_arguments.rb +0 -6
- data/lib/rubocop/cop/lint/float_comparison.rb +1 -6
- data/lib/rubocop/cop/lint/literal_as_condition.rb +103 -9
- data/lib/rubocop/cop/lint/mixed_case_range.rb +2 -2
- data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +2 -2
- data/lib/rubocop/cop/lint/redundant_require_statement.rb +0 -21
- data/lib/rubocop/cop/lint/redundant_type_conversion.rb +32 -5
- data/lib/rubocop/cop/lint/return_in_void_context.rb +4 -11
- data/lib/rubocop/cop/lint/shared_mutable_default.rb +12 -1
- data/lib/rubocop/cop/lint/useless_constant_scoping.rb +2 -11
- data/lib/rubocop/cop/lint/void.rb +6 -0
- data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +1 -1
- data/lib/rubocop/cop/mixin/hash_subset.rb +19 -4
- data/lib/rubocop/cop/mixin/range_help.rb +12 -0
- data/lib/rubocop/cop/mixin/target_ruby_version.rb +1 -1
- data/lib/rubocop/cop/mixin/trailing_comma.rb +12 -0
- data/lib/rubocop/cop/naming/variable_name.rb +64 -6
- data/lib/rubocop/cop/style/accessor_grouping.rb +19 -5
- data/lib/rubocop/cop/style/class_and_module_children.rb +29 -7
- data/lib/rubocop/cop/style/commented_keyword.rb +10 -3
- data/lib/rubocop/cop/style/comparable_between.rb +75 -0
- data/lib/rubocop/cop/style/double_negation.rb +1 -1
- data/lib/rubocop/cop/style/endless_method.rb +163 -18
- data/lib/rubocop/cop/style/expand_path_arguments.rb +2 -7
- data/lib/rubocop/cop/style/exponential_notation.rb +2 -2
- data/lib/rubocop/cop/style/format_string_token.rb +38 -11
- data/lib/rubocop/cop/style/if_unless_modifier.rb +2 -2
- data/lib/rubocop/cop/style/inverse_methods.rb +8 -5
- data/lib/rubocop/cop/style/keyword_parameters_order.rb +13 -7
- data/lib/rubocop/cop/style/line_end_concatenation.rb +10 -4
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +3 -3
- data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +1 -1
- data/lib/rubocop/cop/style/multiline_block_chain.rb +1 -1
- data/lib/rubocop/cop/style/multiline_method_signature.rb +1 -9
- data/lib/rubocop/cop/style/redundant_condition.rb +45 -0
- data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +14 -4
- data/lib/rubocop/cop/style/redundant_format.rb +23 -11
- data/lib/rubocop/cop/style/redundant_freeze.rb +1 -1
- data/lib/rubocop/cop/style/redundant_self_assignment.rb +1 -1
- data/lib/rubocop/cop/style/rescue_modifier.rb +3 -0
- data/lib/rubocop/cop/style/single_line_methods.rb +3 -3
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +0 -6
- data/lib/rubocop/cop/style/string_concatenation.rb +1 -1
- data/lib/rubocop/cop/style/trailing_comma_in_array_literal.rb +47 -6
- data/lib/rubocop/cop/style/trailing_comma_in_hash_literal.rb +48 -6
- data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
- data/lib/rubocop/cop/utils/format_string.rb +5 -2
- data/lib/rubocop/cops_documentation_generator.rb +12 -1
- data/lib/rubocop/directive_comment.rb +1 -1
- data/lib/rubocop/ext/regexp_node.rb +0 -1
- data/lib/rubocop/plugin/load_error.rb +1 -1
- data/lib/rubocop/plugin.rb +9 -2
- data/lib/rubocop/rspec/shared_contexts.rb +15 -0
- data/lib/rubocop/rspec/support.rb +1 -0
- data/lib/rubocop/version.rb +1 -1
- data/lib/rubocop.rb +1 -1
- metadata +6 -5
- data/lib/rubocop/cop/utils/regexp_ranges.rb +0 -113
| @@ -47,7 +47,7 @@ module RuboCop | |
| 47 47 | 
             
                  class RedundantFormat < Base
         | 
| 48 48 | 
             
                    extend AutoCorrector
         | 
| 49 49 |  | 
| 50 | 
            -
                    MSG = ' | 
| 50 | 
            +
                    MSG = 'Use `%<prefer>s` directly instead of `%<method_name>s`.'
         | 
| 51 51 |  | 
| 52 52 | 
             
                    RESTRICT_ON_SEND = %i[format sprintf].to_set.freeze
         | 
| 53 53 | 
             
                    ACCEPTABLE_LITERAL_TYPES = %i[str dstr sym dsym numeric boolean nil].freeze
         | 
| @@ -72,10 +72,20 @@ module RuboCop | |
| 72 72 | 
             
                      (pair (sym %1) $_)
         | 
| 73 73 | 
             
                    PATTERN
         | 
| 74 74 |  | 
| 75 | 
            +
                    # @!method splatted_arguments?(node)
         | 
| 76 | 
            +
                    def_node_matcher :splatted_arguments?, <<~PATTERN
         | 
| 77 | 
            +
                      (send _ %RESTRICT_ON_SEND <{
         | 
| 78 | 
            +
                        splat
         | 
| 79 | 
            +
                        (hash <kwsplat ...>)
         | 
| 80 | 
            +
                      } ...>)
         | 
| 81 | 
            +
                    PATTERN
         | 
| 82 | 
            +
             | 
| 75 83 | 
             
                    def on_send(node)
         | 
| 76 84 | 
             
                      format_without_additional_args?(node) do |value|
         | 
| 77 | 
            -
                         | 
| 78 | 
            -
             | 
| 85 | 
            +
                        replacement = value.source
         | 
| 86 | 
            +
             | 
| 87 | 
            +
                        add_offense(node, message: message(node, replacement)) do |corrector|
         | 
| 88 | 
            +
                          corrector.replace(node, replacement)
         | 
| 79 89 | 
             
                        end
         | 
| 80 90 | 
             
                        return
         | 
| 81 91 | 
             
                      end
         | 
| @@ -85,8 +95,8 @@ module RuboCop | |
| 85 95 |  | 
| 86 96 | 
             
                    private
         | 
| 87 97 |  | 
| 88 | 
            -
                    def message(node)
         | 
| 89 | 
            -
                      format(MSG, method_name: node.method_name)
         | 
| 98 | 
            +
                    def message(node, prefer)
         | 
| 99 | 
            +
                      format(MSG, prefer: prefer, method_name: node.method_name)
         | 
| 90 100 | 
             
                    end
         | 
| 91 101 |  | 
| 92 102 | 
             
                    def detect_unnecessary_fields(node)
         | 
| @@ -96,7 +106,7 @@ module RuboCop | |
| 96 106 | 
             
                      arguments = node.arguments[1..]
         | 
| 97 107 |  | 
| 98 108 | 
             
                      return unless string && arguments.any?
         | 
| 99 | 
            -
                      return if  | 
| 109 | 
            +
                      return if splatted_arguments?(node)
         | 
| 100 110 |  | 
| 101 111 | 
             
                      register_all_fields_literal(node, string, arguments)
         | 
| 102 112 | 
             
                    end
         | 
| @@ -104,9 +114,11 @@ module RuboCop | |
| 104 114 | 
             
                    def register_all_fields_literal(node, string, arguments)
         | 
| 105 115 | 
             
                      return unless all_fields_literal?(string, arguments.dup)
         | 
| 106 116 |  | 
| 107 | 
            -
                       | 
| 108 | 
            -
             | 
| 109 | 
            -
             | 
| 117 | 
            +
                      formatted_string = format(string, *argument_values(arguments))
         | 
| 118 | 
            +
                      replacement = quote(formatted_string, node)
         | 
| 119 | 
            +
             | 
| 120 | 
            +
                      add_offense(node, message: message(node, replacement)) do |corrector|
         | 
| 121 | 
            +
                        corrector.replace(node, replacement)
         | 
| 110 122 | 
             
                      end
         | 
| 111 123 | 
             
                    end
         | 
| 112 124 |  | 
| @@ -119,7 +131,7 @@ module RuboCop | |
| 119 131 | 
             
                        next if sequence.percent?
         | 
| 120 132 |  | 
| 121 133 | 
             
                        hash = arguments.detect(&:hash_type?)
         | 
| 122 | 
            -
                        argument = find_argument(sequence, arguments, hash)
         | 
| 134 | 
            +
                        next unless (argument = find_argument(sequence, arguments, hash))
         | 
| 123 135 | 
             
                        next unless matching_argument?(sequence, argument)
         | 
| 124 136 |  | 
| 125 137 | 
             
                        count += 1
         | 
| @@ -160,7 +172,7 @@ module RuboCop | |
| 160 172 | 
             
                    end
         | 
| 161 173 |  | 
| 162 174 | 
             
                    def numeric?(argument)
         | 
| 163 | 
            -
                      argument | 
| 175 | 
            +
                      argument.type?(:numeric, :str) ||
         | 
| 164 176 | 
             
                        rational_number?(argument) ||
         | 
| 165 177 | 
             
                        complex_number?(argument)
         | 
| 166 178 | 
             
                    end
         | 
| @@ -60,7 +60,7 @@ module RuboCop | |
| 60 60 | 
             
                        (begin (send !{(str _) array} {:+ :- :* :** :/ :%} {float int}))
         | 
| 61 61 | 
             
                        (begin (send _ {:== :=== :!= :<= :>= :< :>} _))
         | 
| 62 62 | 
             
                        (send _ {:count :length :size} ...)
         | 
| 63 | 
            -
                        ( | 
| 63 | 
            +
                        (any_block (send _ {:count :length :size} ...) ...)
         | 
| 64 64 | 
             
                      }
         | 
| 65 65 | 
             
                    PATTERN
         | 
| 66 66 | 
             
                  end
         | 
| @@ -58,7 +58,7 @@ module RuboCop | |
| 58 58 | 
             
                    # rubocop:disable Metrics/AbcSize
         | 
| 59 59 | 
             
                    def on_lvasgn(node)
         | 
| 60 60 | 
             
                      return unless (rhs = node.rhs)
         | 
| 61 | 
            -
                      return unless rhs. | 
| 61 | 
            +
                      return unless rhs.type?(:any_block, :call) && method_returning_self?(rhs.method_name)
         | 
| 62 62 | 
             
                      return unless (receiver = rhs.receiver)
         | 
| 63 63 |  | 
| 64 64 | 
             
                      receiver_type = ASSIGNMENT_TYPE_TO_RECEIVER_TYPE[node.type]
         | 
| @@ -67,11 +67,13 @@ module RuboCop | |
| 67 67 | 
             
                      node.parent && parentheses?(node.parent)
         | 
| 68 68 | 
             
                    end
         | 
| 69 69 |  | 
| 70 | 
            +
                    # rubocop:disable Metrics/AbcSize
         | 
| 70 71 | 
             
                    def correct_rescue_block(corrector, node, parenthesized)
         | 
| 71 72 | 
             
                      operation = node.body
         | 
| 72 73 |  | 
| 73 74 | 
             
                      node_indentation, node_offset = indentation_and_offset(node, parenthesized)
         | 
| 74 75 |  | 
| 76 | 
            +
                      corrector.wrap(operation, '[', ']') if operation.array_type? && !operation.bracketed?
         | 
| 75 77 | 
             
                      corrector.remove(range_between(operation.source_range.end_pos, node.source_range.end_pos))
         | 
| 76 78 | 
             
                      corrector.insert_before(operation, "begin\n#{node_indentation}")
         | 
| 77 79 | 
             
                      corrector.insert_after(heredoc_end(operation) || operation, <<~RESCUE_CLAUSE.chop)
         | 
| @@ -81,6 +83,7 @@ module RuboCop | |
| 81 83 | 
             
                        #{node_offset}end
         | 
| 82 84 | 
             
                      RESCUE_CLAUSE
         | 
| 83 85 | 
             
                    end
         | 
| 86 | 
            +
                    # rubocop:enable Metrics/AbcSize
         | 
| 84 87 |  | 
| 85 88 | 
             
                    def indentation_and_offset(node, parenthesized)
         | 
| 86 89 | 
             
                      node_indentation = indentation(node)
         | 
| @@ -8,9 +8,9 @@ module RuboCop | |
| 8 8 | 
             
                  #
         | 
| 9 9 | 
             
                  # Endless methods added in Ruby 3.0 are also accepted by this cop.
         | 
| 10 10 | 
             
                  #
         | 
| 11 | 
            -
                  # If `Style/EndlessMethod` is enabled with `EnforcedStyle: allow_single_line` | 
| 12 | 
            -
                  # ` | 
| 13 | 
            -
                  # methods if there is only one statement in the body.
         | 
| 11 | 
            +
                  # If `Style/EndlessMethod` is enabled with `EnforcedStyle: allow_single_line`, `allow_always`,
         | 
| 12 | 
            +
                  # `require_single_line`, or `require_always`, single-line methods will be autocorrected
         | 
| 13 | 
            +
                  # to endless methods if there is only one statement in the body.
         | 
| 14 14 | 
             
                  #
         | 
| 15 15 | 
             
                  # @example
         | 
| 16 16 | 
             
                  #   # bad
         | 
| @@ -230,12 +230,6 @@ module RuboCop | |
| 230 230 | 
             
                        !condition.comparison_method?
         | 
| 231 231 | 
             
                    end
         | 
| 232 232 |  | 
| 233 | 
            -
                    def arguments_range(node)
         | 
| 234 | 
            -
                      range_between(
         | 
| 235 | 
            -
                        node.first_argument.source_range.begin_pos, node.last_argument.source_range.end_pos
         | 
| 236 | 
            -
                      )
         | 
| 237 | 
            -
                    end
         | 
| 238 | 
            -
             | 
| 239 233 | 
             
                    def wrap_condition?(node)
         | 
| 240 234 | 
             
                      node.operator_keyword? || (node.call_type? && node.arguments.any? && !node.parenthesized?)
         | 
| 241 235 | 
             
                    end
         | 
| @@ -6,12 +6,13 @@ module RuboCop | |
| 6 6 | 
             
                  # Checks for trailing comma in array literals.
         | 
| 7 7 | 
             
                  # The configuration options are:
         | 
| 8 8 | 
             
                  #
         | 
| 9 | 
            -
                  # * `consistent_comma`: Requires a comma after the
         | 
| 10 | 
            -
                  #  | 
| 11 | 
            -
                  # * `comma`: Requires a comma after last item in an array,
         | 
| 12 | 
            -
                  #  | 
| 13 | 
            -
                  # * ` | 
| 14 | 
            -
                  #  | 
| 9 | 
            +
                  # * `consistent_comma`: Requires a comma after the last item of all non-empty, multiline array
         | 
| 10 | 
            +
                  # literals.
         | 
| 11 | 
            +
                  # * `comma`: Requires a comma after the last item in an array, but only when each item is on
         | 
| 12 | 
            +
                  # its own line.
         | 
| 13 | 
            +
                  # * `diff_comma`: Requires a comma after the last item in an array, but only when that item is
         | 
| 14 | 
            +
                  # followed by an immediate newline.
         | 
| 15 | 
            +
                  # * `no_comma`: Does not require a comma after the last item in an array
         | 
| 15 16 | 
             
                  #
         | 
| 16 17 | 
             
                  # @example EnforcedStyleForMultiline: consistent_comma
         | 
| 17 18 | 
             
                  #   # bad
         | 
| @@ -37,6 +38,14 @@ module RuboCop | |
| 37 38 | 
             
                  #     2,
         | 
| 38 39 | 
             
                  #   ]
         | 
| 39 40 | 
             
                  #
         | 
| 41 | 
            +
                  #   # bad
         | 
| 42 | 
            +
                  #   a = [1, 2,
         | 
| 43 | 
            +
                  #        3, 4]
         | 
| 44 | 
            +
                  #
         | 
| 45 | 
            +
                  #   # good
         | 
| 46 | 
            +
                  #   a = [1, 2,
         | 
| 47 | 
            +
                  #        3, 4,]
         | 
| 48 | 
            +
                  #
         | 
| 40 49 | 
             
                  # @example EnforcedStyleForMultiline: comma
         | 
| 41 50 | 
             
                  #   # bad
         | 
| 42 51 | 
             
                  #   a = [1, 2,]
         | 
| @@ -72,6 +81,38 @@ module RuboCop | |
| 72 81 | 
             
                  #     2,
         | 
| 73 82 | 
             
                  #   ]
         | 
| 74 83 | 
             
                  #
         | 
| 84 | 
            +
                  # @example EnforcedStyleForMultiline: diff_comma
         | 
| 85 | 
            +
                  #   # bad
         | 
| 86 | 
            +
                  #   a = [1, 2,]
         | 
| 87 | 
            +
                  #
         | 
| 88 | 
            +
                  #   # good
         | 
| 89 | 
            +
                  #   a = [1, 2]
         | 
| 90 | 
            +
                  #
         | 
| 91 | 
            +
                  #   # good
         | 
| 92 | 
            +
                  #   a = [
         | 
| 93 | 
            +
                  #     1, 2,
         | 
| 94 | 
            +
                  #     3,
         | 
| 95 | 
            +
                  #   ]
         | 
| 96 | 
            +
                  #
         | 
| 97 | 
            +
                  #   # good
         | 
| 98 | 
            +
                  #   a = [
         | 
| 99 | 
            +
                  #     1, 2, 3,
         | 
| 100 | 
            +
                  #   ]
         | 
| 101 | 
            +
                  #
         | 
| 102 | 
            +
                  #   # good
         | 
| 103 | 
            +
                  #   a = [
         | 
| 104 | 
            +
                  #     1,
         | 
| 105 | 
            +
                  #     2,
         | 
| 106 | 
            +
                  #   ]
         | 
| 107 | 
            +
                  #
         | 
| 108 | 
            +
                  #   # bad
         | 
| 109 | 
            +
                  #   a = [1, 2,
         | 
| 110 | 
            +
                  #        3, 4,]
         | 
| 111 | 
            +
                  #
         | 
| 112 | 
            +
                  #   # good
         | 
| 113 | 
            +
                  #   a = [1, 2,
         | 
| 114 | 
            +
                  #        3, 4]
         | 
| 115 | 
            +
                  #
         | 
| 75 116 | 
             
                  # @example EnforcedStyleForMultiline: no_comma (default)
         | 
| 76 117 | 
             
                  #   # bad
         | 
| 77 118 | 
             
                  #   a = [1, 2,]
         | 
| @@ -6,12 +6,13 @@ module RuboCop | |
| 6 6 | 
             
                  # Checks for trailing comma in hash literals.
         | 
| 7 7 | 
             
                  # The configuration options are:
         | 
| 8 8 | 
             
                  #
         | 
| 9 | 
            -
                  # * `consistent_comma`: Requires a comma after the
         | 
| 10 | 
            -
                  #  | 
| 11 | 
            -
                  # * `comma`: Requires a comma after the last item in a hash,
         | 
| 12 | 
            -
                  #  | 
| 13 | 
            -
                  # * ` | 
| 14 | 
            -
                  #  | 
| 9 | 
            +
                  # * `consistent_comma`: Requires a comma after the last item of all non-empty, multiline hash
         | 
| 10 | 
            +
                  # literals.
         | 
| 11 | 
            +
                  # * `comma`: Requires a comma after the last item in a hash, but only when each item is on its
         | 
| 12 | 
            +
                  # own line.
         | 
| 13 | 
            +
                  # * `diff_comma`: Requires a comma after the last item in a hash, but only when that item is
         | 
| 14 | 
            +
                  # followed by an immediate newline.
         | 
| 15 | 
            +
                  # * `no_comma`: Does not require a comma after the last item in a hash
         | 
| 15 16 | 
             
                  #
         | 
| 16 17 | 
             
                  # @example EnforcedStyleForMultiline: consistent_comma
         | 
| 17 18 | 
             
                  #
         | 
| @@ -38,6 +39,14 @@ module RuboCop | |
| 38 39 | 
             
                  #     bar: 2,
         | 
| 39 40 | 
             
                  #   }
         | 
| 40 41 | 
             
                  #
         | 
| 42 | 
            +
                  #   # bad
         | 
| 43 | 
            +
                  #   a = { foo: 1, bar: 2,
         | 
| 44 | 
            +
                  #         baz: 3, qux: 4 }
         | 
| 45 | 
            +
                  #
         | 
| 46 | 
            +
                  #   # good
         | 
| 47 | 
            +
                  #   a = { foo: 1, bar: 2,
         | 
| 48 | 
            +
                  #         baz: 3, qux: 4, }
         | 
| 49 | 
            +
                  #
         | 
| 41 50 | 
             
                  # @example EnforcedStyleForMultiline: comma
         | 
| 42 51 | 
             
                  #
         | 
| 43 52 | 
             
                  #   # bad
         | 
| @@ -74,6 +83,39 @@ module RuboCop | |
| 74 83 | 
             
                  #     bar: 2,
         | 
| 75 84 | 
             
                  #   }
         | 
| 76 85 | 
             
                  #
         | 
| 86 | 
            +
                  # @example EnforcedStyleForMultiline: diff_comma
         | 
| 87 | 
            +
                  #
         | 
| 88 | 
            +
                  #   # bad
         | 
| 89 | 
            +
                  #   a = { foo: 1, bar: 2, }
         | 
| 90 | 
            +
                  #
         | 
| 91 | 
            +
                  #   # good
         | 
| 92 | 
            +
                  #   a = { foo: 1, bar: 2 }
         | 
| 93 | 
            +
                  #
         | 
| 94 | 
            +
                  #   # good
         | 
| 95 | 
            +
                  #   a = {
         | 
| 96 | 
            +
                  #     foo: 1, bar: 2,
         | 
| 97 | 
            +
                  #     qux: 3,
         | 
| 98 | 
            +
                  #   }
         | 
| 99 | 
            +
                  #
         | 
| 100 | 
            +
                  #   # good
         | 
| 101 | 
            +
                  #   a = {
         | 
| 102 | 
            +
                  #     foo: 1, bar: 2, qux: 3,
         | 
| 103 | 
            +
                  #   }
         | 
| 104 | 
            +
                  #
         | 
| 105 | 
            +
                  #   # good
         | 
| 106 | 
            +
                  #   a = {
         | 
| 107 | 
            +
                  #     foo: 1,
         | 
| 108 | 
            +
                  #     bar: 2,
         | 
| 109 | 
            +
                  #   }
         | 
| 110 | 
            +
                  #
         | 
| 111 | 
            +
                  #   # bad
         | 
| 112 | 
            +
                  #   a = { foo: 1, bar: 2,
         | 
| 113 | 
            +
                  #         baz: 3, qux: 4, }
         | 
| 114 | 
            +
                  #
         | 
| 115 | 
            +
                  #   # good
         | 
| 116 | 
            +
                  #   a = { foo: 1, bar: 2,
         | 
| 117 | 
            +
                  #         baz: 3, qux: 4 }
         | 
| 118 | 
            +
                  #
         | 
| 77 119 | 
             
                  # @example EnforcedStyleForMultiline: no_comma (default)
         | 
| 78 120 | 
             
                  #
         | 
| 79 121 | 
             
                  #   # bad
         | 
| @@ -113,7 +113,7 @@ module RuboCop | |
| 113 113 | 
             
                    private
         | 
| 114 114 |  | 
| 115 115 | 
             
                    def in_module_or_instance_eval?(node)
         | 
| 116 | 
            -
                      node.each_ancestor(: | 
| 116 | 
            +
                      node.each_ancestor(:any_block, :class, :sclass, :module).each do |pnode|
         | 
| 117 117 | 
             
                        case pnode.type
         | 
| 118 118 | 
             
                        when :class, :sclass
         | 
| 119 119 | 
             
                          return false
         | 
| @@ -5,8 +5,11 @@ module RuboCop | |
| 5 5 | 
             
                module Utils
         | 
| 6 6 | 
             
                  # Parses {Kernel#sprintf} format strings.
         | 
| 7 7 | 
             
                  class FormatString
         | 
| 8 | 
            +
                    # Escaping the `#` in `INTERPOLATION` and `TEMPLATE_NAME` is necessary to
         | 
| 9 | 
            +
                    # avoid a bug in Ruby 3.2.0
         | 
| 10 | 
            +
                    # See: https://bugs.ruby-lang.org/issues/19379
         | 
| 8 11 | 
             
                    DIGIT_DOLLAR  = /(?<arg_number>\d+)\$/.freeze
         | 
| 9 | 
            -
                    INTERPOLATION =  | 
| 12 | 
            +
                    INTERPOLATION = /\#\{.*?\}/.freeze
         | 
| 10 13 | 
             
                    FLAG          = /[ #0+-]|#{DIGIT_DOLLAR}/.freeze
         | 
| 11 14 | 
             
                    NUMBER_ARG    = /\*#{DIGIT_DOLLAR}?/.freeze
         | 
| 12 15 | 
             
                    NUMBER        = /\d+|#{NUMBER_ARG}|#{INTERPOLATION}/.freeze
         | 
| @@ -14,7 +17,7 @@ module RuboCop | |
| 14 17 | 
             
                    PRECISION     = /\.(?<precision>#{NUMBER}?)/.freeze
         | 
| 15 18 | 
             
                    TYPE          = /(?<type>[bBdiouxXeEfgGaAcps])/.freeze
         | 
| 16 19 | 
             
                    NAME          = /<(?<name>\w+)>/.freeze
         | 
| 17 | 
            -
                    TEMPLATE_NAME = /( | 
| 20 | 
            +
                    TEMPLATE_NAME = /(?<!\#)\{(?<name>\w+)\}/.freeze
         | 
| 18 21 |  | 
| 19 22 | 
             
                    SEQUENCE = /
         | 
| 20 23 | 
             
                        % (?<type>%)
         | 
| @@ -28,6 +28,12 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength | |
| 28 28 | 
             
              #
         | 
| 29 29 | 
             
              #   CopsDocumentationGenerator.new(departments: ['Lint']).call
         | 
| 30 30 | 
             
              #
         | 
| 31 | 
            +
              # For plugin extensions, specify `:plugin_name` keyword as follows:
         | 
| 32 | 
            +
              #
         | 
| 33 | 
            +
              #   CopsDocumentationGenerator.new(
         | 
| 34 | 
            +
              #     departments: ['Performance'], plugin_name: 'rubocop-performance'
         | 
| 35 | 
            +
              #   ).call
         | 
| 36 | 
            +
              #
         | 
| 31 37 | 
             
              # You can append additional information:
         | 
| 32 38 | 
             
              #
         | 
| 33 39 | 
             
              #   callback = ->(data) { required_rails_version(data.cop) }
         | 
| @@ -36,11 +42,16 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength | |
| 36 42 | 
             
              # This will insert the string returned from the lambda _after_ the section from RuboCop itself.
         | 
| 37 43 | 
             
              # See `CopsDocumentationGenerator::STRUCTURE` for available sections.
         | 
| 38 44 | 
             
              #
         | 
| 39 | 
            -
              def initialize(departments: [], extra_info: {}, base_dir: Dir.pwd)
         | 
| 45 | 
            +
              def initialize(departments: [], extra_info: {}, base_dir: Dir.pwd, plugin_name: nil)
         | 
| 40 46 | 
             
                @departments = departments.map(&:to_sym).sort!
         | 
| 41 47 | 
             
                @extra_info = extra_info
         | 
| 42 48 | 
             
                @cops = RuboCop::Cop::Registry.global
         | 
| 43 49 | 
             
                @config = RuboCop::ConfigLoader.default_configuration
         | 
| 50 | 
            +
                # NOTE: For example, this prevents excessive plugin loading before another task executes,
         | 
| 51 | 
            +
                # in cases where plugins are already loaded by `internal_investigation`.
         | 
| 52 | 
            +
                if plugin_name && @config.loaded_plugins.none? { |plugin| plugin.about.name == plugin_name }
         | 
| 53 | 
            +
                  RuboCop::Plugin.integrate_plugins(RuboCop::Config.new, [plugin_name])
         | 
| 54 | 
            +
                end
         | 
| 44 55 | 
             
                @base_dir = base_dir
         | 
| 45 56 | 
             
                @docs_path = "#{base_dir}/docs/modules/ROOT"
         | 
| 46 57 | 
             
                FileUtils.mkdir_p("#{@docs_path}/pages")
         | 
| @@ -12,7 +12,7 @@ module RuboCop | |
| 12 12 | 
             
                # @api private
         | 
| 13 13 | 
             
                LINT_SYNTAX_COP = "#{LINT_DEPARTMENT}/Syntax"
         | 
| 14 14 | 
             
                # @api private
         | 
| 15 | 
            -
                COP_NAME_PATTERN = '([A- | 
| 15 | 
            +
                COP_NAME_PATTERN = '([A-Za-z]\w+/)*(?:[A-Za-z]\w+)'
         | 
| 16 16 | 
             
                # @api private
         | 
| 17 17 | 
             
                COP_NAMES_PATTERN = "(?:#{COP_NAME_PATTERN} , )*#{COP_NAME_PATTERN}"
         | 
| 18 18 | 
             
                # @api private
         | 
| @@ -15,7 +15,7 @@ module RuboCop | |
| 15 15 | 
             
                    <<~MESSAGE
         | 
| 16 16 | 
             
                      Failed to load plugin `#{@plugin_name}` because the corresponding plugin class could not be determined for instantiation.
         | 
| 17 17 | 
             
                      Try upgrading it first (e.g., `bundle update #{@plugin_name}`).
         | 
| 18 | 
            -
                      If `#{@plugin_name}` is not yet a plugin, use `require: #{@plugin_name}` instead of `plugins:  | 
| 18 | 
            +
                      If `#{@plugin_name}` is not yet a plugin, use `require: #{@plugin_name}` instead of `plugins: #{@plugin_name}` in your configuration.
         | 
| 19 19 |  | 
| 20 20 | 
             
                      For further assistance, check with the developer regarding the following points:
         | 
| 21 21 | 
             
                      https://docs.rubocop.org/rubocop/plugin_migration_guide.html
         | 
    
        data/lib/rubocop/plugin.rb
    CHANGED
    
    | @@ -22,9 +22,16 @@ module RuboCop | |
| 22 22 | 
             
                  def plugin_capable?(feature_name)
         | 
| 23 23 | 
             
                    return true if BUILTIN_INTERNAL_PLUGINS.key?(feature_name)
         | 
| 24 24 | 
             
                    return true if feature_name == OBSOLETE_INTERNAL_AFFAIRS_PLUGIN_NAME
         | 
| 25 | 
            -
                    return false unless (gem = Gem.loaded_specs[feature_name])
         | 
| 26 25 |  | 
| 27 | 
            -
                     | 
| 26 | 
            +
                    begin
         | 
| 27 | 
            +
                      # When not using Bundler. Makes the spec available but does not require it.
         | 
| 28 | 
            +
                      gem feature_name
         | 
| 29 | 
            +
                    rescue Gem::LoadError
         | 
| 30 | 
            +
                      # The user requested a gem that they do not have installed
         | 
| 31 | 
            +
                    end
         | 
| 32 | 
            +
                    return false unless (spec = Gem.loaded_specs[feature_name])
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                    !!spec.metadata['default_lint_roller_plugin']
         | 
| 28 35 | 
             
                  end
         | 
| 29 36 |  | 
| 30 37 | 
             
                  def integrate_plugins(rubocop_config, plugins)
         | 
| @@ -80,6 +80,21 @@ RSpec.shared_context 'maintain registry' do | |
| 80 80 | 
             
              end
         | 
| 81 81 | 
             
            end
         | 
| 82 82 |  | 
| 83 | 
            +
            RSpec.shared_context 'maintain default configuration' do
         | 
| 84 | 
            +
              around(:each) do |example|
         | 
| 85 | 
            +
                # Make a copy of the current configuration that will not change when source hash changes
         | 
| 86 | 
            +
                default_configuration = RuboCop::ConfigLoader.default_configuration
         | 
| 87 | 
            +
                config = RuboCop::Config.create(
         | 
| 88 | 
            +
                  default_configuration.to_h.clone,
         | 
| 89 | 
            +
                  default_configuration.loaded_path
         | 
| 90 | 
            +
                )
         | 
| 91 | 
            +
             | 
| 92 | 
            +
                example.run
         | 
| 93 | 
            +
             | 
| 94 | 
            +
                RuboCop::ConfigLoader.instance_variable_set(:@default_configuration, config)
         | 
| 95 | 
            +
              end
         | 
| 96 | 
            +
            end
         | 
| 97 | 
            +
             | 
| 83 98 | 
             
            # This context assumes nothing and defines `cop`, among others.
         | 
| 84 99 | 
             
            RSpec.shared_context 'config' do # rubocop:disable Metrics/BlockLength
         | 
| 85 100 | 
             
              ### Meant to be overridden at will
         | 
| @@ -15,6 +15,7 @@ RSpec.configure do |config| | |
| 15 15 | 
             
              config.include_context 'isolated bundler', :isolated_bundler
         | 
| 16 16 | 
             
              config.include_context 'lsp', :lsp
         | 
| 17 17 | 
             
              config.include_context 'maintain registry', :restore_registry
         | 
| 18 | 
            +
              config.include_context 'maintain default configuration', :restore_configuration
         | 
| 18 19 | 
             
              config.include_context 'ruby 2.0', :ruby20
         | 
| 19 20 | 
             
              config.include_context 'ruby 2.1', :ruby21
         | 
| 20 21 | 
             
              config.include_context 'ruby 2.2', :ruby22
         | 
    
        data/lib/rubocop/version.rb
    CHANGED
    
    
    
        data/lib/rubocop.rb
    CHANGED
    
    | @@ -148,7 +148,6 @@ require_relative 'rubocop/cop/mixin/comments_help' # relies on visibility_help | |
| 148 148 | 
             
            require_relative 'rubocop/cop/mixin/def_node' # relies on visibility_help
         | 
| 149 149 |  | 
| 150 150 | 
             
            require_relative 'rubocop/cop/utils/format_string'
         | 
| 151 | 
            -
            require_relative 'rubocop/cop/utils/regexp_ranges'
         | 
| 152 151 |  | 
| 153 152 | 
             
            require_relative 'rubocop/cop/migration/department_name'
         | 
| 154 153 |  | 
| @@ -510,6 +509,7 @@ require_relative 'rubocop/cop/style/combinable_loops' | |
| 510 509 | 
             
            require_relative 'rubocop/cop/style/command_literal'
         | 
| 511 510 | 
             
            require_relative 'rubocop/cop/style/comment_annotation'
         | 
| 512 511 | 
             
            require_relative 'rubocop/cop/style/commented_keyword'
         | 
| 512 | 
            +
            require_relative 'rubocop/cop/style/comparable_between'
         | 
| 513 513 | 
             
            require_relative 'rubocop/cop/style/comparable_clamp'
         | 
| 514 514 | 
             
            require_relative 'rubocop/cop/style/concat_array_literals'
         | 
| 515 515 | 
             
            require_relative 'rubocop/cop/style/conditional_assignment'
         | 
    
        metadata
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: rubocop
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 1. | 
| 4 | 
            +
              version: 1.74.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Bozhidar Batsov
         | 
| @@ -9,7 +9,7 @@ authors: | |
| 9 9 | 
             
            - Yuji Nakayama
         | 
| 10 10 | 
             
            bindir: exe
         | 
| 11 11 | 
             
            cert_chain: []
         | 
| 12 | 
            -
            date: 2025- | 
| 12 | 
            +
            date: 2025-03-13 00:00:00.000000000 Z
         | 
| 13 13 | 
             
            dependencies:
         | 
| 14 14 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 15 15 | 
             
              name: json
         | 
| @@ -297,6 +297,7 @@ files: | |
| 297 297 | 
             
            - lib/rubocop/cop/internal_affairs/node_pattern_groups.rb
         | 
| 298 298 | 
             
            - lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_processor.rb
         | 
| 299 299 | 
             
            - lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_walker.rb
         | 
| 300 | 
            +
            - lib/rubocop/cop/internal_affairs/node_type_group.rb
         | 
| 300 301 | 
             
            - lib/rubocop/cop/internal_affairs/node_type_multiple_predicates.rb
         | 
| 301 302 | 
             
            - lib/rubocop/cop/internal_affairs/node_type_predicate.rb
         | 
| 302 303 | 
             
            - lib/rubocop/cop/internal_affairs/numblock_handler.rb
         | 
| @@ -728,6 +729,7 @@ files: | |
| 728 729 | 
             
            - lib/rubocop/cop/style/command_literal.rb
         | 
| 729 730 | 
             
            - lib/rubocop/cop/style/comment_annotation.rb
         | 
| 730 731 | 
             
            - lib/rubocop/cop/style/commented_keyword.rb
         | 
| 732 | 
            +
            - lib/rubocop/cop/style/comparable_between.rb
         | 
| 731 733 | 
             
            - lib/rubocop/cop/style/comparable_clamp.rb
         | 
| 732 734 | 
             
            - lib/rubocop/cop/style/concat_array_literals.rb
         | 
| 733 735 | 
             
            - lib/rubocop/cop/style/conditional_assignment.rb
         | 
| @@ -971,7 +973,6 @@ files: | |
| 971 973 | 
             
            - lib/rubocop/cop/team.rb
         | 
| 972 974 | 
             
            - lib/rubocop/cop/util.rb
         | 
| 973 975 | 
             
            - lib/rubocop/cop/utils/format_string.rb
         | 
| 974 | 
            -
            - lib/rubocop/cop/utils/regexp_ranges.rb
         | 
| 975 976 | 
             
            - lib/rubocop/cop/variable_force.rb
         | 
| 976 977 | 
             
            - lib/rubocop/cop/variable_force/assignment.rb
         | 
| 977 978 | 
             
            - lib/rubocop/cop/variable_force/branch.rb
         | 
| @@ -1075,9 +1076,9 @@ licenses: | |
| 1075 1076 | 
             
            - MIT
         | 
| 1076 1077 | 
             
            metadata:
         | 
| 1077 1078 | 
             
              homepage_uri: https://rubocop.org/
         | 
| 1078 | 
            -
              changelog_uri: https://github.com/rubocop/rubocop/releases/tag/v1. | 
| 1079 | 
            +
              changelog_uri: https://github.com/rubocop/rubocop/releases/tag/v1.74.0
         | 
| 1079 1080 | 
             
              source_code_uri: https://github.com/rubocop/rubocop/
         | 
| 1080 | 
            -
              documentation_uri: https://docs.rubocop.org/rubocop/1. | 
| 1081 | 
            +
              documentation_uri: https://docs.rubocop.org/rubocop/1.74/
         | 
| 1081 1082 | 
             
              bug_tracker_uri: https://github.com/rubocop/rubocop/issues
         | 
| 1082 1083 | 
             
              rubygems_mfa_required: 'true'
         | 
| 1083 1084 | 
             
            rdoc_options: []
         | 
| @@ -1,113 +0,0 @@ | |
| 1 | 
            -
            # frozen_string_literal: true
         | 
| 2 | 
            -
             | 
| 3 | 
            -
            module RuboCop
         | 
| 4 | 
            -
              module Cop
         | 
| 5 | 
            -
                module Utils
         | 
| 6 | 
            -
                  # Helper to abstract complexity of building range pairs
         | 
| 7 | 
            -
                  # with octal escape reconstruction (needed for regexp_parser < 2.7).
         | 
| 8 | 
            -
                  class RegexpRanges
         | 
| 9 | 
            -
                    attr_reader :root
         | 
| 10 | 
            -
             | 
| 11 | 
            -
                    def initialize(root)
         | 
| 12 | 
            -
                      @root = root
         | 
| 13 | 
            -
                      @compound_token = []
         | 
| 14 | 
            -
                      @pairs = []
         | 
| 15 | 
            -
                      @populated = false
         | 
| 16 | 
            -
                    end
         | 
| 17 | 
            -
             | 
| 18 | 
            -
                    def compound_token
         | 
| 19 | 
            -
                      populate_all unless @populated
         | 
| 20 | 
            -
             | 
| 21 | 
            -
                      @compound_token
         | 
| 22 | 
            -
                    end
         | 
| 23 | 
            -
             | 
| 24 | 
            -
                    def pairs
         | 
| 25 | 
            -
                      populate_all unless @populated
         | 
| 26 | 
            -
             | 
| 27 | 
            -
                      @pairs
         | 
| 28 | 
            -
                    end
         | 
| 29 | 
            -
             | 
| 30 | 
            -
                    private
         | 
| 31 | 
            -
             | 
| 32 | 
            -
                    def populate_all
         | 
| 33 | 
            -
                      populate(@root)
         | 
| 34 | 
            -
             | 
| 35 | 
            -
                      # If either bound is a compound the first one is an escape
         | 
| 36 | 
            -
                      # and that's all we need to work with.
         | 
| 37 | 
            -
                      # If there are any cops that wanted to operate on the compound
         | 
| 38 | 
            -
                      # expression we could wrap it with a facade class.
         | 
| 39 | 
            -
                      @pairs.map! { |pair| pair.map(&:first) }
         | 
| 40 | 
            -
             | 
| 41 | 
            -
                      @populated = true
         | 
| 42 | 
            -
                    end
         | 
| 43 | 
            -
             | 
| 44 | 
            -
                    def populate(expr)
         | 
| 45 | 
            -
                      expressions = expr.expressions.to_a
         | 
| 46 | 
            -
             | 
| 47 | 
            -
                      until expressions.empty?
         | 
| 48 | 
            -
                        current = expressions.shift
         | 
| 49 | 
            -
             | 
| 50 | 
            -
                        if escaped_octal?(current)
         | 
| 51 | 
            -
                          @compound_token << current
         | 
| 52 | 
            -
                          @compound_token.concat(pop_octal_digits(expressions))
         | 
| 53 | 
            -
                          # If we have all the digits we can discard.
         | 
| 54 | 
            -
                        end
         | 
| 55 | 
            -
             | 
| 56 | 
            -
                        next unless current.type == :set
         | 
| 57 | 
            -
             | 
| 58 | 
            -
                        process_set(expressions, current)
         | 
| 59 | 
            -
                        @compound_token.clear
         | 
| 60 | 
            -
                      end
         | 
| 61 | 
            -
                    end
         | 
| 62 | 
            -
             | 
| 63 | 
            -
                    def process_set(expressions, current)
         | 
| 64 | 
            -
                      case current.token
         | 
| 65 | 
            -
                      when :range
         | 
| 66 | 
            -
                        @pairs << compose_range(expressions, current)
         | 
| 67 | 
            -
                      when :character
         | 
| 68 | 
            -
                        # Child expressions may include the range we are looking for.
         | 
| 69 | 
            -
                        populate(current)
         | 
| 70 | 
            -
                      when :intersection
         | 
| 71 | 
            -
                        # Each child expression could have child expressions that lead to ranges.
         | 
| 72 | 
            -
                        current.expressions.each do |intersected|
         | 
| 73 | 
            -
                          populate(intersected)
         | 
| 74 | 
            -
                        end
         | 
| 75 | 
            -
                      end
         | 
| 76 | 
            -
                    end
         | 
| 77 | 
            -
             | 
| 78 | 
            -
                    def compose_range(expressions, current)
         | 
| 79 | 
            -
                      range_start, range_end = current.expressions
         | 
| 80 | 
            -
                      range_start = if @compound_token.size.between?(1, 2) && octal_digit?(range_start.text)
         | 
| 81 | 
            -
                                      @compound_token.dup << range_start
         | 
| 82 | 
            -
                                    else
         | 
| 83 | 
            -
                                      [range_start]
         | 
| 84 | 
            -
                                    end
         | 
| 85 | 
            -
                      range_end = [range_end]
         | 
| 86 | 
            -
                      range_end.concat(pop_octal_digits(expressions)) if escaped_octal?(range_end.first)
         | 
| 87 | 
            -
                      [range_start, range_end]
         | 
| 88 | 
            -
                    end
         | 
| 89 | 
            -
             | 
| 90 | 
            -
                    def escaped_octal?(expr)
         | 
| 91 | 
            -
                      expr.text.valid_encoding? && expr.text =~ /^\\[0-7]$/
         | 
| 92 | 
            -
                    end
         | 
| 93 | 
            -
             | 
| 94 | 
            -
                    def octal_digit?(char)
         | 
| 95 | 
            -
                      ('0'..'7').cover?(char)
         | 
| 96 | 
            -
                    end
         | 
| 97 | 
            -
             | 
| 98 | 
            -
                    def pop_octal_digits(expressions)
         | 
| 99 | 
            -
                      digits = []
         | 
| 100 | 
            -
             | 
| 101 | 
            -
                      2.times do
         | 
| 102 | 
            -
                        next unless (next_child = expressions.first)
         | 
| 103 | 
            -
                        next unless next_child.type == :literal && next_child.text =~ /^[0-7]$/
         | 
| 104 | 
            -
             | 
| 105 | 
            -
                        digits << expressions.shift
         | 
| 106 | 
            -
                      end
         | 
| 107 | 
            -
             | 
| 108 | 
            -
                      digits
         | 
| 109 | 
            -
                    end
         | 
| 110 | 
            -
                  end
         | 
| 111 | 
            -
                end
         | 
| 112 | 
            -
              end
         | 
| 113 | 
            -
            end
         |