rubocop-performance 1.9.2 → 1.11.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/LICENSE.txt +1 -1
- data/README.md +3 -2
- data/config/default.yml +32 -6
- data/config/obsoletion.yml +7 -0
- data/lib/rubocop/cop/performance/array_semi_infinite_range_slice.rb +1 -1
- data/lib/rubocop/cop/performance/bind_call.rb +2 -2
- data/lib/rubocop/cop/performance/chain_array_allocation.rb +2 -0
- data/lib/rubocop/cop/performance/constant_regexp.rb +12 -7
- data/lib/rubocop/cop/performance/flat_map.rb +2 -1
- data/lib/rubocop/cop/performance/map_compact.rb +77 -0
- data/lib/rubocop/cop/performance/redundant_block_call.rb +7 -1
- data/lib/rubocop/cop/performance/redundant_equality_comparison_block.rb +89 -0
- data/lib/rubocop/cop/performance/redundant_merge.rb +3 -0
- data/lib/rubocop/cop/performance/redundant_split_regexp_argument.rb +64 -0
- data/lib/rubocop/cop/performance/reverse_each.rb +18 -2
- data/lib/rubocop/cop/performance/select_map.rb +60 -0
- data/lib/rubocop/cop/performance/sum.rb +8 -2
- data/lib/rubocop/cop/performance_cops.rb +4 -0
- data/lib/rubocop/performance.rb +2 -0
- data/lib/rubocop/performance/version.rb +1 -1
- metadata +16 -11
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 0fddb9566bda412ba7ab8f26966cca63207064468d2c2da5796a81cd84da1c69
         | 
| 4 | 
            +
              data.tar.gz: f49da21e50225a0f35fe6959ad3a37a2c26ff73e64df03f5a94025811d380b02
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: a70fd0b8cf0778f410098e889dc52c828202f0d197a10a9fb4edff36991204cad23cfba361039b9b80952c7f5f814679d7277e2f9c533fe29fd55e708c4d1bb9
         | 
| 7 | 
            +
              data.tar.gz: a2ce3b7915ed3c3bc208ef020f031646e3350d46397759eb0c5a772e826dc30ad8d72d75c009b385358ef015be4b6af4c7cd1b6f337b6f34c583432bef608a65
         | 
    
        data/LICENSE.txt
    CHANGED
    
    
    
        data/README.md
    CHANGED
    
    | @@ -1,9 +1,10 @@ | |
| 1 1 | 
             
            # RuboCop Performance
         | 
| 2 2 |  | 
| 3 3 | 
             
            [](https://badge.fury.io/rb/rubocop-performance)
         | 
| 4 | 
            -
            [](https://circleci.com/gh/rubocop/rubocop-performance)
         | 
| 5 | 
            +
            [](https://discord.gg/wJjWvGRDmm)
         | 
| 5 6 |  | 
| 6 | 
            -
            Performance optimization analysis for your projects, as an extension to [RuboCop](https://github.com/rubocop | 
| 7 | 
            +
            Performance optimization analysis for your projects, as an extension to [RuboCop](https://github.com/rubocop/rubocop).
         | 
| 7 8 |  | 
| 8 9 | 
             
            ## Installation
         | 
| 9 10 |  | 
    
        data/config/default.yml
    CHANGED
    
    | @@ -10,7 +10,7 @@ Performance/AncestorsInclude: | |
| 10 10 | 
             
            Performance/ArraySemiInfiniteRangeSlice:
         | 
| 11 11 | 
             
              Description: 'Identifies places where slicing arrays with semi-infinite ranges can be replaced by `Array#take` and `Array#drop`.'
         | 
| 12 12 | 
             
              # This cop was created due to a mistake in microbenchmark.
         | 
| 13 | 
            -
              # Refer https://github.com/rubocop | 
| 13 | 
            +
              # Refer https://github.com/rubocop/rubocop-performance/pull/175#issuecomment-731892717
         | 
| 14 14 | 
             
              Enabled: false
         | 
| 15 15 | 
             
              # Unsafe for string slices because strings do not have `#take` and `#drop` methods.
         | 
| 16 16 | 
             
              Safe: false
         | 
| @@ -80,6 +80,7 @@ Performance/ConstantRegexp: | |
| 80 80 | 
             
              Description: 'Finds regular expressions with dynamic components that are all constants.'
         | 
| 81 81 | 
             
              Enabled: pending
         | 
| 82 82 | 
             
              VersionAdded: '1.9'
         | 
| 83 | 
            +
              VersionChanged: '1.10'
         | 
| 83 84 |  | 
| 84 85 | 
             
            Performance/Count:
         | 
| 85 86 | 
             
              Description: >-
         | 
| @@ -136,11 +137,10 @@ Performance/EndWith: | |
| 136 137 | 
             
              # object. Switching these methods has to be done with knowledge of the types
         | 
| 137 138 | 
             
              # of the variables which rubocop doesn't have.
         | 
| 138 139 | 
             
              SafeAutoCorrect: false
         | 
| 139 | 
            -
              AutoCorrect: false
         | 
| 140 140 | 
             
              Enabled: true
         | 
| 141 141 | 
             
              SafeMultiline: true
         | 
| 142 142 | 
             
              VersionAdded: '0.36'
         | 
| 143 | 
            -
              VersionChanged: '1. | 
| 143 | 
            +
              VersionChanged: '1.10'
         | 
| 144 144 |  | 
| 145 145 | 
             
            Performance/FixedSize:
         | 
| 146 146 | 
             
              Description: 'Do not compute the size of statically sized objects except in constants.'
         | 
| @@ -174,6 +174,12 @@ Performance/IoReadlines: | |
| 174 174 | 
             
              Enabled: false
         | 
| 175 175 | 
             
              VersionAdded: '1.7'
         | 
| 176 176 |  | 
| 177 | 
            +
            Performance/MapCompact:
         | 
| 178 | 
            +
              Description: 'Use `filter_map` instead of `collection.map(&:do_something).compact`.'
         | 
| 179 | 
            +
              Enabled: pending
         | 
| 180 | 
            +
              SafeAutoCorrect: false
         | 
| 181 | 
            +
              VersionAdded: '1.11'
         | 
| 182 | 
            +
             | 
| 177 183 | 
             
            Performance/MethodObjectAsBlock:
         | 
| 178 184 | 
             
              Description: 'Use block explicitly instead of block-passing a method object.'
         | 
| 179 185 | 
             
              Reference: 'https://github.com/JuanitoFatas/fast-ruby#normal-way-to-apply-method-vs-method-code'
         | 
| @@ -200,6 +206,15 @@ Performance/RedundantBlockCall: | |
| 200 206 | 
             
              Enabled: true
         | 
| 201 207 | 
             
              VersionAdded: '0.36'
         | 
| 202 208 |  | 
| 209 | 
            +
            Performance/RedundantEqualityComparisonBlock:
         | 
| 210 | 
            +
              Description: >-
         | 
| 211 | 
            +
                              Checks for uses `Enumerable#all?`, `Enumerable#any?`, `Enumerable#one?`,
         | 
| 212 | 
            +
                              or `Enumerable#none?` are compared with `===` or similar methods in block.
         | 
| 213 | 
            +
              Reference: 'https://github.com/rails/rails/pull/41363'
         | 
| 214 | 
            +
              Enabled: pending
         | 
| 215 | 
            +
              Safe: false
         | 
| 216 | 
            +
              VersionAdded: '1.10'
         | 
| 217 | 
            +
             | 
| 203 218 | 
             
            Performance/RedundantMatch:
         | 
| 204 219 | 
             
              Description: >-
         | 
| 205 220 | 
             
                              Use `=~` instead of `String#match` or `Regexp#match` in a context where the
         | 
| @@ -211,7 +226,9 @@ Performance/RedundantMerge: | |
| 211 226 | 
             
              Description: 'Use Hash#[]=, rather than Hash#merge! with a single key-value pair.'
         | 
| 212 227 | 
             
              Reference: 'https://github.com/JuanitoFatas/fast-ruby#hashmerge-vs-hash-code'
         | 
| 213 228 | 
             
              Enabled: true
         | 
| 229 | 
            +
              Safe: false
         | 
| 214 230 | 
             
              VersionAdded: '0.36'
         | 
| 231 | 
            +
              VersionChanged: '1.11'
         | 
| 215 232 | 
             
              # Max number of key-value pairs to consider an offense
         | 
| 216 233 | 
             
              MaxKeyValuePairs: 2
         | 
| 217 234 |  | 
| @@ -220,6 +237,11 @@ Performance/RedundantSortBlock: | |
| 220 237 | 
             
              Enabled: 'pending'
         | 
| 221 238 | 
             
              VersionAdded: '1.7'
         | 
| 222 239 |  | 
| 240 | 
            +
            Performance/RedundantSplitRegexpArgument:
         | 
| 241 | 
            +
              Description: 'This cop identifies places where `split` argument can be replaced from a deterministic regexp to a string.'
         | 
| 242 | 
            +
              Enabled: pending
         | 
| 243 | 
            +
              VersionAdded: '1.10'
         | 
| 244 | 
            +
             | 
| 223 245 | 
             
            Performance/RedundantStringChars:
         | 
| 224 246 | 
             
              Description: 'Checks for redundant `String#chars`.'
         | 
| 225 247 | 
             
              Enabled: 'pending'
         | 
| @@ -244,6 +266,11 @@ Performance/ReverseFirst: | |
| 244 266 | 
             
              Enabled: 'pending'
         | 
| 245 267 | 
             
              VersionAdded: '1.7'
         | 
| 246 268 |  | 
| 269 | 
            +
            Performance/SelectMap:
         | 
| 270 | 
            +
              Description: 'Use `filter_map` instead of `ary.select(&:foo).map(&:bar)`.'
         | 
| 271 | 
            +
              Enabled: false
         | 
| 272 | 
            +
              VersionAdded: '1.11'
         | 
| 273 | 
            +
             | 
| 247 274 | 
             
            Performance/Size:
         | 
| 248 275 | 
             
              Description: >-
         | 
| 249 276 | 
             
                              Use `size` instead of `count` for counting
         | 
| @@ -270,11 +297,10 @@ Performance/StartWith: | |
| 270 297 | 
             
              # object. Switching these methods has to be done with knowledge of the types
         | 
| 271 298 | 
             
              # of the variables which rubocop doesn't have.
         | 
| 272 299 | 
             
              SafeAutoCorrect: false
         | 
| 273 | 
            -
              AutoCorrect: false
         | 
| 274 300 | 
             
              Enabled: true
         | 
| 275 301 | 
             
              SafeMultiline: true
         | 
| 276 302 | 
             
              VersionAdded: '0.36'
         | 
| 277 | 
            -
              VersionChanged: '1. | 
| 303 | 
            +
              VersionChanged: '1.10'
         | 
| 278 304 |  | 
| 279 305 | 
             
            Performance/StringInclude:
         | 
| 280 306 | 
             
              Description: 'Use `String#include?` instead of a regex match with literal-only pattern.'
         | 
| @@ -304,7 +330,7 @@ Performance/TimesMap: | |
| 304 330 | 
             
              Enabled: true
         | 
| 305 331 | 
             
              VersionAdded: '0.36'
         | 
| 306 332 | 
             
              VersionChanged: '0.50'
         | 
| 307 | 
            -
              SafeAutoCorrect: false # see https://github.com/rubocop | 
| 333 | 
            +
              SafeAutoCorrect: false # see https://github.com/rubocop/rubocop/issues/4658
         | 
| 308 334 |  | 
| 309 335 | 
             
            Performance/UnfreezeString:
         | 
| 310 336 | 
             
              Description: 'Use unary plus to get an unfrozen string literal.'
         | 
| @@ -6,7 +6,7 @@ module RuboCop | |
| 6 6 | 
             
                  # This cop identifies places where slicing arrays with semi-infinite ranges
         | 
| 7 7 | 
             
                  # can be replaced by `Array#take` and `Array#drop`.
         | 
| 8 8 | 
             
                  # This cop was created due to a mistake in microbenchmark and hence is disabled by default.
         | 
| 9 | 
            -
                  # Refer https://github.com/rubocop | 
| 9 | 
            +
                  # Refer https://github.com/rubocop/rubocop-performance/pull/175#issuecomment-731892717
         | 
| 10 10 | 
             
                  # This cop is also unsafe for string slices because strings do not have `#take` and `#drop` methods.
         | 
| 11 11 | 
             
                  #
         | 
| 12 12 | 
             
                  # @example
         | 
| @@ -33,7 +33,7 @@ module RuboCop | |
| 33 33 | 
             
                    def_node_matcher :bind_with_call_method?, <<~PATTERN
         | 
| 34 34 | 
             
                      (send
         | 
| 35 35 | 
             
                        $(send
         | 
| 36 | 
            -
                           | 
| 36 | 
            +
                          _ :bind
         | 
| 37 37 | 
             
                          $(...)) :call
         | 
| 38 38 | 
             
                        $...)
         | 
| 39 39 | 
             
                    PATTERN
         | 
| @@ -64,7 +64,7 @@ module RuboCop | |
| 64 64 |  | 
| 65 65 | 
             
                    def correction_range(receiver, node)
         | 
| 66 66 | 
             
                      location_of_bind = receiver.loc.selector.begin_pos
         | 
| 67 | 
            -
                      location_of_call = node. | 
| 67 | 
            +
                      location_of_call = node.source_range.end.end_pos
         | 
| 68 68 |  | 
| 69 69 | 
             
                      range_between(location_of_bind, location_of_call)
         | 
| 70 70 | 
             
                    end
         | 
| @@ -63,6 +63,8 @@ module RuboCop | |
| 63 63 |  | 
| 64 64 | 
             
                    def on_send(node)
         | 
| 65 65 | 
             
                      chain_array_allocation?(node) do |fm, sm|
         | 
| 66 | 
            +
                        return if node.each_descendant(:send).any? { |descendant| descendant.method?(:lazy) }
         | 
| 67 | 
            +
             | 
| 66 68 | 
             
                        range = range_between(node.loc.dot.begin_pos, node.source_range.end_pos)
         | 
| 67 69 |  | 
| 68 70 | 
             
                        add_offense(range, message: format(MSG, method: fm, second_method: sm))
         | 
| @@ -6,9 +6,9 @@ module RuboCop | |
| 6 6 | 
             
                  # This cop finds regular expressions with dynamic components that are all constants.
         | 
| 7 7 | 
             
                  #
         | 
| 8 8 | 
             
                  # Ruby allocates a new Regexp object every time it executes a code containing such
         | 
| 9 | 
            -
                  # a regular expression. It is more efficient to extract it into a constant
         | 
| 10 | 
            -
                  # or add an `/o` option to perform `#{}` interpolation only once and | 
| 11 | 
            -
                  # Regexp object.
         | 
| 9 | 
            +
                  # a regular expression. It is more efficient to extract it into a constant,
         | 
| 10 | 
            +
                  # memoize it, or add an `/o` option to perform `#{}` interpolation only once and
         | 
| 11 | 
            +
                  # reuse that Regexp object.
         | 
| 12 12 | 
             
                  #
         | 
| 13 13 | 
             
                  # @example
         | 
| 14 14 | 
             
                  #
         | 
| @@ -28,13 +28,18 @@ module RuboCop | |
| 28 28 | 
             
                  #     pattern.scan(TOKEN).reject { |token| token.match?(/\A#{SEPARATORS}\Z/o) }
         | 
| 29 29 | 
             
                  #   end
         | 
| 30 30 | 
             
                  #
         | 
| 31 | 
            +
                  #   # good
         | 
| 32 | 
            +
                  #   def separators
         | 
| 33 | 
            +
                  #     @separators ||= /\A#{SEPARATORS}\Z/
         | 
| 34 | 
            +
                  #   end
         | 
| 35 | 
            +
                  #
         | 
| 31 36 | 
             
                  class ConstantRegexp < Base
         | 
| 32 37 | 
             
                    extend AutoCorrector
         | 
| 33 38 |  | 
| 34 | 
            -
                    MSG = 'Extract this regexp into a constant or append an `/o` option to its options.'
         | 
| 39 | 
            +
                    MSG = 'Extract this regexp into a constant, memoize it, or append an `/o` option to its options.'
         | 
| 35 40 |  | 
| 36 41 | 
             
                    def on_regexp(node)
         | 
| 37 | 
            -
                      return if  | 
| 42 | 
            +
                      return if within_allowed_assignment?(node) ||
         | 
| 38 43 | 
             
                                !include_interpolated_const?(node) ||
         | 
| 39 44 | 
             
                                node.single_interpolation?
         | 
| 40 45 |  | 
| @@ -45,8 +50,8 @@ module RuboCop | |
| 45 50 |  | 
| 46 51 | 
             
                    private
         | 
| 47 52 |  | 
| 48 | 
            -
                    def  | 
| 49 | 
            -
                      node.each_ancestor(:casgn).any?
         | 
| 53 | 
            +
                    def within_allowed_assignment?(node)
         | 
| 54 | 
            +
                      node.each_ancestor(:casgn, :or_asgn).any?
         | 
| 50 55 | 
             
                    end
         | 
| 51 56 |  | 
| 52 57 | 
             
                    def_node_matcher :regexp_escape?, <<~PATTERN
         | 
| @@ -0,0 +1,77 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module RuboCop
         | 
| 4 | 
            +
              module Cop
         | 
| 5 | 
            +
                module Performance
         | 
| 6 | 
            +
                  # In Ruby 2.7, `Enumerable#filter_map` has been added.
         | 
| 7 | 
            +
                  #
         | 
| 8 | 
            +
                  # This cop identifies places where `map { ... }.compact` can be replaced by `filter_map`.
         | 
| 9 | 
            +
                  # It is marked as unsafe auto-correction by default because `map { ... }.compact`
         | 
| 10 | 
            +
                  # that is not compatible with `filter_map`.
         | 
| 11 | 
            +
                  #
         | 
| 12 | 
            +
                  # [source,ruby]
         | 
| 13 | 
            +
                  # ----
         | 
| 14 | 
            +
                  # [true, false, nil].compact              #=> [true, false]
         | 
| 15 | 
            +
                  # [true, false, nil].filter_map(&:itself) #=> [true]
         | 
| 16 | 
            +
                  # ----
         | 
| 17 | 
            +
                  #
         | 
| 18 | 
            +
                  # @example
         | 
| 19 | 
            +
                  #   # bad
         | 
| 20 | 
            +
                  #   ary.map(&:foo).compact
         | 
| 21 | 
            +
                  #   ary.collect(&:foo).compact
         | 
| 22 | 
            +
                  #
         | 
| 23 | 
            +
                  #   # good
         | 
| 24 | 
            +
                  #   ary.filter_map(&:foo)
         | 
| 25 | 
            +
                  #   ary.map(&:foo).compact!
         | 
| 26 | 
            +
                  #
         | 
| 27 | 
            +
                  class MapCompact < Base
         | 
| 28 | 
            +
                    include RangeHelp
         | 
| 29 | 
            +
                    extend AutoCorrector
         | 
| 30 | 
            +
                    extend TargetRubyVersion
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                    MSG = 'Use `filter_map` instead.'
         | 
| 33 | 
            +
                    RESTRICT_ON_SEND = %i[compact].freeze
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                    minimum_target_ruby_version 2.7
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                    def_node_matcher :map_compact, <<~PATTERN
         | 
| 38 | 
            +
                      {
         | 
| 39 | 
            +
                        (send
         | 
| 40 | 
            +
                          $(send _ {:map :collect}
         | 
| 41 | 
            +
                            (block_pass
         | 
| 42 | 
            +
                              (sym _))) _)
         | 
| 43 | 
            +
                        (send
         | 
| 44 | 
            +
                          (block
         | 
| 45 | 
            +
                            $(send _ {:map :collect})
         | 
| 46 | 
            +
                              (args ...) _) _)
         | 
| 47 | 
            +
                      }
         | 
| 48 | 
            +
                    PATTERN
         | 
| 49 | 
            +
             | 
| 50 | 
            +
                    def on_send(node)
         | 
| 51 | 
            +
                      return unless (map_node = map_compact(node))
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                      compact_loc = node.loc
         | 
| 54 | 
            +
                      range = range_between(map_node.loc.selector.begin_pos, compact_loc.selector.end_pos)
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                      add_offense(range) do |corrector|
         | 
| 57 | 
            +
                        corrector.replace(map_node.loc.selector, 'filter_map')
         | 
| 58 | 
            +
                        corrector.remove(compact_loc.dot)
         | 
| 59 | 
            +
                        corrector.remove(compact_method_range(node))
         | 
| 60 | 
            +
                      end
         | 
| 61 | 
            +
                    end
         | 
| 62 | 
            +
             | 
| 63 | 
            +
                    private
         | 
| 64 | 
            +
             | 
| 65 | 
            +
                    def compact_method_range(compact_node)
         | 
| 66 | 
            +
                      compact_method_range = compact_node.loc.selector
         | 
| 67 | 
            +
             | 
| 68 | 
            +
                      if compact_node.multiline?
         | 
| 69 | 
            +
                        range_by_whole_lines(compact_method_range, include_final_newline: true)
         | 
| 70 | 
            +
                      else
         | 
| 71 | 
            +
                        compact_method_range
         | 
| 72 | 
            +
                      end
         | 
| 73 | 
            +
                    end
         | 
| 74 | 
            +
                  end
         | 
| 75 | 
            +
                end
         | 
| 76 | 
            +
              end
         | 
| 77 | 
            +
            end
         | 
| @@ -78,7 +78,7 @@ module RuboCop | |
| 78 78 | 
             
                    end
         | 
| 79 79 |  | 
| 80 80 | 
             
                    def calls_to_report(argname, body)
         | 
| 81 | 
            -
                      return [] if blockarg_assigned?(body, argname)
         | 
| 81 | 
            +
                      return [] if blockarg_assigned?(body, argname) || shadowed_block_argument?(body, argname)
         | 
| 82 82 |  | 
| 83 83 | 
             
                      blockarg_calls(body, argname).map do |call|
         | 
| 84 84 | 
             
                        return [] if args_include_block_pass?(call)
         | 
| @@ -87,6 +87,12 @@ module RuboCop | |
| 87 87 | 
             
                      end
         | 
| 88 88 | 
             
                    end
         | 
| 89 89 |  | 
| 90 | 
            +
                    def shadowed_block_argument?(body, block_argument_of_method_signature)
         | 
| 91 | 
            +
                      return false unless body.block_type?
         | 
| 92 | 
            +
             | 
| 93 | 
            +
                      body.arguments.map(&:source).include?(block_argument_of_method_signature.to_s)
         | 
| 94 | 
            +
                    end
         | 
| 95 | 
            +
             | 
| 90 96 | 
             
                    def args_include_block_pass?(blockcall)
         | 
| 91 97 | 
             
                      _receiver, _call, *args = *blockcall
         | 
| 92 98 |  | 
| @@ -0,0 +1,89 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module RuboCop
         | 
| 4 | 
            +
              module Cop
         | 
| 5 | 
            +
                module Performance
         | 
| 6 | 
            +
                  # This cop checks for uses `Enumerable#all?`, `Enumerable#any?`, `Enumerable#one?`,
         | 
| 7 | 
            +
                  # and `Enumerable#none?` are compared with `===` or similar methods in block.
         | 
| 8 | 
            +
                  #
         | 
| 9 | 
            +
                  # By default, `Object#===` behaves the same as `Object#==`, but this
         | 
| 10 | 
            +
                  # behavior is appropriately overridden in subclass. For example,
         | 
| 11 | 
            +
                  # `Range#===` returns `true` when argument is within the range.
         | 
| 12 | 
            +
                  # Therefore, It is marked as unsafe by default because `===` and `==`
         | 
| 13 | 
            +
                  # do not always behave the same.
         | 
| 14 | 
            +
                  #
         | 
| 15 | 
            +
                  # @example
         | 
| 16 | 
            +
                  #   # bad
         | 
| 17 | 
            +
                  #   items.all? { |item| pattern === item }
         | 
| 18 | 
            +
                  #   items.all? { |item| item == other }
         | 
| 19 | 
            +
                  #   items.all? { |item| item.is_a?(Klass) }
         | 
| 20 | 
            +
                  #   items.all? { |item| item.kind_of?(Klass) }
         | 
| 21 | 
            +
                  #
         | 
| 22 | 
            +
                  #   # good
         | 
| 23 | 
            +
                  #   items.all?(pattern)
         | 
| 24 | 
            +
                  #
         | 
| 25 | 
            +
                  class RedundantEqualityComparisonBlock < Base
         | 
| 26 | 
            +
                    extend AutoCorrector
         | 
| 27 | 
            +
                    extend TargetRubyVersion
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                    minimum_target_ruby_version 2.5
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                    MSG = 'Use `%<prefer>s` instead of block.'
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                    TARGET_METHODS = %i[all? any? one? none?].freeze
         | 
| 34 | 
            +
                    COMPARISON_METHODS = %i[== === is_a? kind_of?].freeze
         | 
| 35 | 
            +
                    IS_A_METHODS = %i[is_a? kind_of?].freeze
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                    def on_block(node)
         | 
| 38 | 
            +
                      return unless TARGET_METHODS.include?(node.method_name)
         | 
| 39 | 
            +
                      return unless one_block_argument?(node.arguments)
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                      block_argument = node.arguments.first
         | 
| 42 | 
            +
                      block_body = node.body
         | 
| 43 | 
            +
                      return unless use_equality_comparison_block?(block_body)
         | 
| 44 | 
            +
                      return if same_block_argument_and_is_a_argument?(block_body, block_argument)
         | 
| 45 | 
            +
                      return unless (new_argument = new_argument(block_argument, block_body))
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                      range = offense_range(node)
         | 
| 48 | 
            +
                      prefer = "#{node.method_name}(#{new_argument})"
         | 
| 49 | 
            +
             | 
| 50 | 
            +
                      add_offense(range, message: format(MSG, prefer: prefer)) do |corrector|
         | 
| 51 | 
            +
                        corrector.replace(range, prefer)
         | 
| 52 | 
            +
                      end
         | 
| 53 | 
            +
                    end
         | 
| 54 | 
            +
             | 
| 55 | 
            +
                    private
         | 
| 56 | 
            +
             | 
| 57 | 
            +
                    def one_block_argument?(block_arguments)
         | 
| 58 | 
            +
                      block_arguments.one? && !block_arguments.source.include?(',')
         | 
| 59 | 
            +
                    end
         | 
| 60 | 
            +
             | 
| 61 | 
            +
                    def use_equality_comparison_block?(block_body)
         | 
| 62 | 
            +
                      block_body.send_type? && COMPARISON_METHODS.include?(block_body.method_name)
         | 
| 63 | 
            +
                    end
         | 
| 64 | 
            +
             | 
| 65 | 
            +
                    def same_block_argument_and_is_a_argument?(block_body, block_argument)
         | 
| 66 | 
            +
                      if block_body.method?(:===)
         | 
| 67 | 
            +
                        block_argument.source != block_body.children[2].source
         | 
| 68 | 
            +
                      elsif IS_A_METHODS.include?(block_body.method_name)
         | 
| 69 | 
            +
                        block_argument.source == block_body.first_argument.source
         | 
| 70 | 
            +
                      else
         | 
| 71 | 
            +
                        false
         | 
| 72 | 
            +
                      end
         | 
| 73 | 
            +
                    end
         | 
| 74 | 
            +
             | 
| 75 | 
            +
                    def new_argument(block_argument, block_body)
         | 
| 76 | 
            +
                      if block_argument.source == block_body.receiver.source
         | 
| 77 | 
            +
                        block_body.first_argument.source
         | 
| 78 | 
            +
                      elsif block_argument.source == block_body.first_argument.source
         | 
| 79 | 
            +
                        block_body.receiver.source
         | 
| 80 | 
            +
                      end
         | 
| 81 | 
            +
                    end
         | 
| 82 | 
            +
             | 
| 83 | 
            +
                    def offense_range(node)
         | 
| 84 | 
            +
                      node.send_node.loc.selector.join(node.source_range.end)
         | 
| 85 | 
            +
                    end
         | 
| 86 | 
            +
                  end
         | 
| 87 | 
            +
                end
         | 
| 88 | 
            +
              end
         | 
| 89 | 
            +
            end
         | 
| @@ -8,6 +8,9 @@ module RuboCop | |
| 8 8 | 
             
                  # You can set the maximum number of key-value pairs to consider
         | 
| 9 9 | 
             
                  # an offense with `MaxKeyValuePairs`.
         | 
| 10 10 | 
             
                  #
         | 
| 11 | 
            +
                  # This cop is marked as unsafe because RuboCop cannot determine if the
         | 
| 12 | 
            +
                  # receiver of `merge!` is actually a hash or not.
         | 
| 13 | 
            +
                  #
         | 
| 11 14 | 
             
                  # @example
         | 
| 12 15 | 
             
                  #   # bad
         | 
| 13 16 | 
             
                  #   hash.merge!(a: 1)
         | 
| @@ -0,0 +1,64 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module RuboCop
         | 
| 4 | 
            +
              module Cop
         | 
| 5 | 
            +
                module Performance
         | 
| 6 | 
            +
                  # This cop identifies places where `split` argument can be replaced from
         | 
| 7 | 
            +
                  # a deterministic regexp to a string.
         | 
| 8 | 
            +
                  #
         | 
| 9 | 
            +
                  # @example
         | 
| 10 | 
            +
                  #   # bad
         | 
| 11 | 
            +
                  #   'a,b,c'.split(/,/)
         | 
| 12 | 
            +
                  #
         | 
| 13 | 
            +
                  #   # good
         | 
| 14 | 
            +
                  #   'a,b,c'.split(',')
         | 
| 15 | 
            +
                  class RedundantSplitRegexpArgument < Base
         | 
| 16 | 
            +
                    extend AutoCorrector
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                    MSG = 'Use string as argument instead of regexp.'
         | 
| 19 | 
            +
                    RESTRICT_ON_SEND = %i[split].freeze
         | 
| 20 | 
            +
                    DETERMINISTIC_REGEX = /\A(?:#{LITERAL_REGEX})+\Z/.freeze
         | 
| 21 | 
            +
                    STR_SPECIAL_CHARS = %w[\n \" \' \\\\ \t \b \f \r].freeze
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                    def_node_matcher :split_call_with_regexp?, <<~PATTERN
         | 
| 24 | 
            +
                      {(send !nil? :split $regexp)}
         | 
| 25 | 
            +
                    PATTERN
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                    def on_send(node)
         | 
| 28 | 
            +
                      return unless (regexp_node = split_call_with_regexp?(node))
         | 
| 29 | 
            +
                      return if regexp_node.ignore_case? || regexp_node.content == ' '
         | 
| 30 | 
            +
                      return unless determinist_regexp?(regexp_node)
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                      add_offense(regexp_node) do |corrector|
         | 
| 33 | 
            +
                        new_argument = replacement(regexp_node)
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                        corrector.replace(regexp_node, "\"#{new_argument}\"")
         | 
| 36 | 
            +
                      end
         | 
| 37 | 
            +
                    end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                    private
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                    def determinist_regexp?(regexp_node)
         | 
| 42 | 
            +
                      DETERMINISTIC_REGEX.match?(regexp_node.source)
         | 
| 43 | 
            +
                    end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                    def replacement(regexp_node)
         | 
| 46 | 
            +
                      regexp_content = regexp_node.content
         | 
| 47 | 
            +
                      stack = []
         | 
| 48 | 
            +
                      chars = regexp_content.chars.each_with_object([]) do |char, strings|
         | 
| 49 | 
            +
                        if stack.empty? && char == '\\'
         | 
| 50 | 
            +
                          stack.push(char)
         | 
| 51 | 
            +
                        else
         | 
| 52 | 
            +
                          strings << "#{stack.pop}#{char}"
         | 
| 53 | 
            +
                        end
         | 
| 54 | 
            +
                      end
         | 
| 55 | 
            +
                      chars.map do |char|
         | 
| 56 | 
            +
                        char = char.dup
         | 
| 57 | 
            +
                        char.delete!('\\') unless STR_SPECIAL_CHARS.include?(char)
         | 
| 58 | 
            +
                        char
         | 
| 59 | 
            +
                      end.join
         | 
| 60 | 
            +
                    end
         | 
| 61 | 
            +
                  end
         | 
| 62 | 
            +
                end
         | 
| 63 | 
            +
              end
         | 
| 64 | 
            +
            end
         | 
| @@ -6,12 +6,20 @@ module RuboCop | |
| 6 6 | 
             
                  # This cop is used to identify usages of `reverse.each` and
         | 
| 7 7 | 
             
                  # change them to use `reverse_each` instead.
         | 
| 8 8 | 
             
                  #
         | 
| 9 | 
            +
                  # If the return value is used, it will not be detected because the result will be different.
         | 
| 10 | 
            +
                  #
         | 
| 11 | 
            +
                  # [source,ruby]
         | 
| 12 | 
            +
                  # ----
         | 
| 13 | 
            +
                  # [1, 2, 3].reverse.each {} #=> [3, 2, 1]
         | 
| 14 | 
            +
                  # [1, 2, 3].reverse_each {} #=> [1, 2, 3]
         | 
| 15 | 
            +
                  # ----
         | 
| 16 | 
            +
                  #
         | 
| 9 17 | 
             
                  # @example
         | 
| 10 18 | 
             
                  #   # bad
         | 
| 11 | 
            -
                  #    | 
| 19 | 
            +
                  #   items.reverse.each
         | 
| 12 20 | 
             
                  #
         | 
| 13 21 | 
             
                  #   # good
         | 
| 14 | 
            -
                  #    | 
| 22 | 
            +
                  #   items.reverse_each
         | 
| 15 23 | 
             
                  class ReverseEach < Base
         | 
| 16 24 | 
             
                    include RangeHelp
         | 
| 17 25 | 
             
                    extend AutoCorrector
         | 
| @@ -24,6 +32,8 @@ module RuboCop | |
| 24 32 | 
             
                    MATCHER
         | 
| 25 33 |  | 
| 26 34 | 
             
                    def on_send(node)
         | 
| 35 | 
            +
                      return if use_return_value?(node)
         | 
| 36 | 
            +
             | 
| 27 37 | 
             
                      reverse_each?(node) do
         | 
| 28 38 | 
             
                        range = offense_range(node)
         | 
| 29 39 |  | 
| @@ -35,6 +45,12 @@ module RuboCop | |
| 35 45 |  | 
| 36 46 | 
             
                    private
         | 
| 37 47 |  | 
| 48 | 
            +
                    def use_return_value?(node)
         | 
| 49 | 
            +
                      !!node.ancestors.detect do |ancestor|
         | 
| 50 | 
            +
                        ancestor.assignment? || ancestor.send_type? || ancestor.return_type?
         | 
| 51 | 
            +
                      end
         | 
| 52 | 
            +
                    end
         | 
| 53 | 
            +
             | 
| 38 54 | 
             
                    def offense_range(node)
         | 
| 39 55 | 
             
                      range_between(node.children.first.loc.selector.begin_pos, node.loc.selector.end_pos)
         | 
| 40 56 | 
             
                    end
         | 
| @@ -0,0 +1,60 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module RuboCop
         | 
| 4 | 
            +
              module Cop
         | 
| 5 | 
            +
                module Performance
         | 
| 6 | 
            +
                  # In Ruby 2.7, `Enumerable#filter_map` has been added.
         | 
| 7 | 
            +
                  #
         | 
| 8 | 
            +
                  # This cop identifies places where `select.map` can be replaced by `filter_map`.
         | 
| 9 | 
            +
                  #
         | 
| 10 | 
            +
                  # @example
         | 
| 11 | 
            +
                  #   # bad
         | 
| 12 | 
            +
                  #   ary.select(&:foo).map(&:bar)
         | 
| 13 | 
            +
                  #   ary.filter(&:foo).map(&:bar)
         | 
| 14 | 
            +
                  #
         | 
| 15 | 
            +
                  #   # good
         | 
| 16 | 
            +
                  #   ary.filter_map { |o| o.bar if o.foo }
         | 
| 17 | 
            +
                  #
         | 
| 18 | 
            +
                  class SelectMap < Base
         | 
| 19 | 
            +
                    include RangeHelp
         | 
| 20 | 
            +
                    extend TargetRubyVersion
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                    minimum_target_ruby_version 2.7
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                    MSG = 'Use `filter_map` instead of `%<method_name>s.map`.'
         | 
| 25 | 
            +
                    RESTRICT_ON_SEND = %i[select filter].freeze
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                    def_node_matcher :bad_method?, <<~PATTERN
         | 
| 28 | 
            +
                      (send nil? :bad_method ...)
         | 
| 29 | 
            +
                    PATTERN
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                    def on_send(node)
         | 
| 32 | 
            +
                      return if (first_argument = node.first_argument) && !first_argument.block_pass_type?
         | 
| 33 | 
            +
                      return unless (send_node = map_method_candidate(node))
         | 
| 34 | 
            +
                      return unless send_node.method?(:map)
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                      map_method = send_node.parent&.block_type? ? send_node.parent : send_node
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                      range = offense_range(node, map_method)
         | 
| 39 | 
            +
                      add_offense(range, message: format(MSG, method_name: node.method_name))
         | 
| 40 | 
            +
                    end
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                    private
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                    def map_method_candidate(node)
         | 
| 45 | 
            +
                      return unless (parent = node.parent)
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                      if parent.block_type? && parent.parent&.send_type?
         | 
| 48 | 
            +
                        parent.parent
         | 
| 49 | 
            +
                      elsif parent.send_type?
         | 
| 50 | 
            +
                        parent
         | 
| 51 | 
            +
                      end
         | 
| 52 | 
            +
                    end
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                    def offense_range(node, map_method)
         | 
| 55 | 
            +
                      range_between(node.loc.selector.begin_pos, map_method.loc.expression.end_pos)
         | 
| 56 | 
            +
                    end
         | 
| 57 | 
            +
                  end
         | 
| 58 | 
            +
                end
         | 
| 59 | 
            +
              end
         | 
| 60 | 
            +
            end
         | 
| @@ -150,7 +150,9 @@ module RuboCop | |
| 150 150 | 
             
                      replacement = build_good_method(init, block_pass)
         | 
| 151 151 |  | 
| 152 152 | 
             
                      corrector.remove(sum_range)
         | 
| 153 | 
            -
             | 
| 153 | 
            +
             | 
| 154 | 
            +
                      dot = '.' if map.receiver
         | 
| 155 | 
            +
                      corrector.replace(map_range, "#{dot}#{replacement}")
         | 
| 154 156 | 
             
                    end
         | 
| 155 157 |  | 
| 156 158 | 
             
                    def sum_method_range(node)
         | 
| @@ -228,7 +230,11 @@ module RuboCop | |
| 228 230 | 
             
                    end
         | 
| 229 231 |  | 
| 230 232 | 
             
                    def method_call_with_args_range(node)
         | 
| 231 | 
            -
                      node.receiver | 
| 233 | 
            +
                      if (receiver = node.receiver)
         | 
| 234 | 
            +
                        receiver.source_range.end.join(node.source_range.end)
         | 
| 235 | 
            +
                      else
         | 
| 236 | 
            +
                        node.source_range
         | 
| 237 | 
            +
                      end
         | 
| 232 238 | 
             
                    end
         | 
| 233 239 | 
             
                  end
         | 
| 234 240 | 
             
                end
         | 
| @@ -23,18 +23,22 @@ require_relative 'performance/end_with' | |
| 23 23 | 
             
            require_relative 'performance/fixed_size'
         | 
| 24 24 | 
             
            require_relative 'performance/flat_map'
         | 
| 25 25 | 
             
            require_relative 'performance/inefficient_hash_search'
         | 
| 26 | 
            +
            require_relative 'performance/map_compact'
         | 
| 26 27 | 
             
            require_relative 'performance/method_object_as_block'
         | 
| 27 28 | 
             
            require_relative 'performance/open_struct'
         | 
| 28 29 | 
             
            require_relative 'performance/range_include'
         | 
| 29 30 | 
             
            require_relative 'performance/io_readlines'
         | 
| 30 31 | 
             
            require_relative 'performance/redundant_block_call'
         | 
| 32 | 
            +
            require_relative 'performance/redundant_equality_comparison_block'
         | 
| 31 33 | 
             
            require_relative 'performance/redundant_match'
         | 
| 32 34 | 
             
            require_relative 'performance/redundant_merge'
         | 
| 33 35 | 
             
            require_relative 'performance/redundant_sort_block'
         | 
| 36 | 
            +
            require_relative 'performance/redundant_split_regexp_argument'
         | 
| 34 37 | 
             
            require_relative 'performance/redundant_string_chars'
         | 
| 35 38 | 
             
            require_relative 'performance/regexp_match'
         | 
| 36 39 | 
             
            require_relative 'performance/reverse_each'
         | 
| 37 40 | 
             
            require_relative 'performance/reverse_first'
         | 
| 41 | 
            +
            require_relative 'performance/select_map'
         | 
| 38 42 | 
             
            require_relative 'performance/size'
         | 
| 39 43 | 
             
            require_relative 'performance/sort_reverse'
         | 
| 40 44 | 
             
            require_relative 'performance/squeeze'
         | 
    
        data/lib/rubocop/performance.rb
    CHANGED
    
    
    
        metadata
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: rubocop-performance
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 1. | 
| 4 | 
            +
              version: 1.11.1
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Bozhidar Batsov
         | 
| @@ -10,7 +10,7 @@ authors: | |
| 10 10 | 
             
            autorequire:
         | 
| 11 11 | 
             
            bindir: bin
         | 
| 12 12 | 
             
            cert_chain: []
         | 
| 13 | 
            -
            date: 2021- | 
| 13 | 
            +
            date: 2021-05-01 00:00:00.000000000 Z
         | 
| 14 14 | 
             
            dependencies:
         | 
| 15 15 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 16 16 | 
             
              name: rubocop
         | 
| @@ -18,7 +18,7 @@ dependencies: | |
| 18 18 | 
             
                requirements:
         | 
| 19 19 | 
             
                - - ">="
         | 
| 20 20 | 
             
                  - !ruby/object:Gem::Version
         | 
| 21 | 
            -
                    version:  | 
| 21 | 
            +
                    version: 1.7.0
         | 
| 22 22 | 
             
                - - "<"
         | 
| 23 23 | 
             
                  - !ruby/object:Gem::Version
         | 
| 24 24 | 
             
                    version: '2.0'
         | 
| @@ -28,7 +28,7 @@ dependencies: | |
| 28 28 | 
             
                requirements:
         | 
| 29 29 | 
             
                - - ">="
         | 
| 30 30 | 
             
                  - !ruby/object:Gem::Version
         | 
| 31 | 
            -
                    version:  | 
| 31 | 
            +
                    version: 1.7.0
         | 
| 32 32 | 
             
                - - "<"
         | 
| 33 33 | 
             
                  - !ruby/object:Gem::Version
         | 
| 34 34 | 
             
                    version: '2.0'
         | 
| @@ -59,6 +59,7 @@ files: | |
| 59 59 | 
             
            - LICENSE.txt
         | 
| 60 60 | 
             
            - README.md
         | 
| 61 61 | 
             
            - config/default.yml
         | 
| 62 | 
            +
            - config/obsoletion.yml
         | 
| 62 63 | 
             
            - lib/rubocop-performance.rb
         | 
| 63 64 | 
             
            - lib/rubocop/cop/mixin/regexp_metacharacter.rb
         | 
| 64 65 | 
             
            - lib/rubocop/cop/mixin/sort_block.rb
         | 
| @@ -84,17 +85,21 @@ files: | |
| 84 85 | 
             
            - lib/rubocop/cop/performance/flat_map.rb
         | 
| 85 86 | 
             
            - lib/rubocop/cop/performance/inefficient_hash_search.rb
         | 
| 86 87 | 
             
            - lib/rubocop/cop/performance/io_readlines.rb
         | 
| 88 | 
            +
            - lib/rubocop/cop/performance/map_compact.rb
         | 
| 87 89 | 
             
            - lib/rubocop/cop/performance/method_object_as_block.rb
         | 
| 88 90 | 
             
            - lib/rubocop/cop/performance/open_struct.rb
         | 
| 89 91 | 
             
            - lib/rubocop/cop/performance/range_include.rb
         | 
| 90 92 | 
             
            - lib/rubocop/cop/performance/redundant_block_call.rb
         | 
| 93 | 
            +
            - lib/rubocop/cop/performance/redundant_equality_comparison_block.rb
         | 
| 91 94 | 
             
            - lib/rubocop/cop/performance/redundant_match.rb
         | 
| 92 95 | 
             
            - lib/rubocop/cop/performance/redundant_merge.rb
         | 
| 93 96 | 
             
            - lib/rubocop/cop/performance/redundant_sort_block.rb
         | 
| 97 | 
            +
            - lib/rubocop/cop/performance/redundant_split_regexp_argument.rb
         | 
| 94 98 | 
             
            - lib/rubocop/cop/performance/redundant_string_chars.rb
         | 
| 95 99 | 
             
            - lib/rubocop/cop/performance/regexp_match.rb
         | 
| 96 100 | 
             
            - lib/rubocop/cop/performance/reverse_each.rb
         | 
| 97 101 | 
             
            - lib/rubocop/cop/performance/reverse_first.rb
         | 
| 102 | 
            +
            - lib/rubocop/cop/performance/select_map.rb
         | 
| 98 103 | 
             
            - lib/rubocop/cop/performance/size.rb
         | 
| 99 104 | 
             
            - lib/rubocop/cop/performance/sort_reverse.rb
         | 
| 100 105 | 
             
            - lib/rubocop/cop/performance/squeeze.rb
         | 
| @@ -109,15 +114,15 @@ files: | |
| 109 114 | 
             
            - lib/rubocop/performance.rb
         | 
| 110 115 | 
             
            - lib/rubocop/performance/inject.rb
         | 
| 111 116 | 
             
            - lib/rubocop/performance/version.rb
         | 
| 112 | 
            -
            homepage: https://github.com/rubocop | 
| 117 | 
            +
            homepage: https://github.com/rubocop/rubocop-performance
         | 
| 113 118 | 
             
            licenses:
         | 
| 114 119 | 
             
            - MIT
         | 
| 115 120 | 
             
            metadata:
         | 
| 116 121 | 
             
              homepage_uri: https://docs.rubocop.org/rubocop-performance/
         | 
| 117 | 
            -
              changelog_uri: https://github.com/rubocop | 
| 118 | 
            -
              source_code_uri: https://github.com/rubocop | 
| 119 | 
            -
              documentation_uri: https://docs.rubocop.org/rubocop-performance/1. | 
| 120 | 
            -
              bug_tracker_uri: https://github.com/rubocop | 
| 122 | 
            +
              changelog_uri: https://github.com/rubocop/rubocop-performance/blob/master/CHANGELOG.md
         | 
| 123 | 
            +
              source_code_uri: https://github.com/rubocop/rubocop-performance/
         | 
| 124 | 
            +
              documentation_uri: https://docs.rubocop.org/rubocop-performance/1.11/
         | 
| 125 | 
            +
              bug_tracker_uri: https://github.com/rubocop/rubocop-performance/issues
         | 
| 121 126 | 
             
            post_install_message:
         | 
| 122 127 | 
             
            rdoc_options: []
         | 
| 123 128 | 
             
            require_paths:
         | 
| @@ -126,14 +131,14 @@ required_ruby_version: !ruby/object:Gem::Requirement | |
| 126 131 | 
             
              requirements:
         | 
| 127 132 | 
             
              - - ">="
         | 
| 128 133 | 
             
                - !ruby/object:Gem::Version
         | 
| 129 | 
            -
                  version: 2. | 
| 134 | 
            +
                  version: 2.5.0
         | 
| 130 135 | 
             
            required_rubygems_version: !ruby/object:Gem::Requirement
         | 
| 131 136 | 
             
              requirements:
         | 
| 132 137 | 
             
              - - ">="
         | 
| 133 138 | 
             
                - !ruby/object:Gem::Version
         | 
| 134 139 | 
             
                  version: '0'
         | 
| 135 140 | 
             
            requirements: []
         | 
| 136 | 
            -
            rubygems_version: 3.2. | 
| 141 | 
            +
            rubygems_version: 3.2.12
         | 
| 137 142 | 
             
            signing_key:
         | 
| 138 143 | 
             
            specification_version: 4
         | 
| 139 144 | 
             
            summary: Automatic performance checking tool for Ruby code.
         |