rubocop-performance 1.5.2 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/LICENSE.txt +1 -1
- data/README.md +5 -1
- data/config/default.yml +96 -13
- data/lib/rubocop/cop/mixin/regexp_metacharacter.rb +76 -0
- data/lib/rubocop/cop/mixin/sort_block.rb +28 -0
- data/lib/rubocop/cop/performance/ancestors_include.rb +48 -0
- data/lib/rubocop/cop/performance/big_decimal_with_numeric_argument.rb +45 -0
- data/lib/rubocop/cop/performance/bind_call.rb +77 -0
- data/lib/rubocop/cop/performance/caller.rb +5 -4
- data/lib/rubocop/cop/performance/case_when_splat.rb +18 -11
- data/lib/rubocop/cop/performance/casecmp.rb +17 -23
- data/lib/rubocop/cop/performance/chain_array_allocation.rb +5 -11
- data/lib/rubocop/cop/performance/collection_literal_in_loop.rb +140 -0
- data/lib/rubocop/cop/performance/compare_with_block.rb +12 -23
- data/lib/rubocop/cop/performance/count.rb +14 -17
- data/lib/rubocop/cop/performance/delete_prefix.rb +87 -0
- data/lib/rubocop/cop/performance/delete_suffix.rb +87 -0
- data/lib/rubocop/cop/performance/detect.rb +30 -27
- data/lib/rubocop/cop/performance/double_start_end_with.rb +18 -26
- data/lib/rubocop/cop/performance/end_with.rb +38 -25
- data/lib/rubocop/cop/performance/fixed_size.rb +2 -2
- data/lib/rubocop/cop/performance/flat_map.rb +21 -23
- data/lib/rubocop/cop/performance/inefficient_hash_search.rb +14 -15
- data/lib/rubocop/cop/performance/io_readlines.rb +116 -0
- data/lib/rubocop/cop/performance/open_struct.rb +3 -3
- data/lib/rubocop/cop/performance/range_include.rb +15 -12
- data/lib/rubocop/cop/performance/redundant_block_call.rb +14 -9
- data/lib/rubocop/cop/performance/redundant_match.rb +13 -8
- data/lib/rubocop/cop/performance/redundant_merge.rb +36 -23
- data/lib/rubocop/cop/performance/redundant_sort_block.rb +43 -0
- data/lib/rubocop/cop/performance/redundant_string_chars.rb +133 -0
- data/lib/rubocop/cop/performance/regexp_match.rb +32 -32
- data/lib/rubocop/cop/performance/reverse_each.rb +10 -5
- data/lib/rubocop/cop/performance/reverse_first.rb +72 -0
- data/lib/rubocop/cop/performance/size.rb +41 -43
- data/lib/rubocop/cop/performance/sort_reverse.rb +45 -0
- data/lib/rubocop/cop/performance/squeeze.rb +66 -0
- data/lib/rubocop/cop/performance/start_with.rb +38 -28
- data/lib/rubocop/cop/performance/string_include.rb +55 -0
- data/lib/rubocop/cop/performance/string_replacement.rb +25 -36
- data/lib/rubocop/cop/performance/sum.rb +129 -0
- data/lib/rubocop/cop/performance/times_map.rb +12 -19
- data/lib/rubocop/cop/performance/unfreeze_string.rb +4 -8
- data/lib/rubocop/cop/performance/uri_default_parser.rb +7 -13
- data/lib/rubocop/cop/performance_cops.rb +17 -0
- data/lib/rubocop/performance/inject.rb +1 -1
- data/lib/rubocop/performance/version.rb +1 -1
- metadata +27 -11
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 00b98a3d2af1bcfd781dfab24e4a8deb118d29fdaedeca8b2d404ff03eab3529
         | 
| 4 | 
            +
              data.tar.gz: cc5508a731d9c932d2c141892aefbe15f635d18bdd95ae6ad5b4998c931fcaf2
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 806f21556b5e791a6a00866714c4feec42726b20d4c82db7c4cd89ec576624eaac3007f4a68fca4fd633fbc3ed7a41801fdb0dfc64f767ee241582a4185bbb8b
         | 
| 7 | 
            +
              data.tar.gz: 1e922a3d51a62df60cdb26f99960fec91e1fa558ceea751bcce7ec529f7d4db6e1644d0dfd24848cb75e384e08fd6a3f2afaaa8f531a1118a09d35d6fa1b0e21
         | 
    
        data/LICENSE.txt
    CHANGED
    
    
    
        data/README.md
    CHANGED
    
    | @@ -16,7 +16,7 @@ gem install rubocop-performance | |
| 16 16 | 
             
            or if you use bundler put this in your `Gemfile`
         | 
| 17 17 |  | 
| 18 18 | 
             
            ```ruby
         | 
| 19 | 
            -
            gem 'rubocop-performance'
         | 
| 19 | 
            +
            gem 'rubocop-performance', require: false
         | 
| 20 20 | 
             
            ```
         | 
| 21 21 |  | 
| 22 22 | 
             
            ## Usage
         | 
| @@ -72,6 +72,10 @@ Performance/Size: | |
| 72 72 | 
             
                - lib/example.rb
         | 
| 73 73 | 
             
            ```
         | 
| 74 74 |  | 
| 75 | 
            +
            ## Documentation
         | 
| 76 | 
            +
             | 
| 77 | 
            +
            You can read a lot more about RuboCop Performance in its [official docs](https://docs.rubocop.org/rubocop-performance/).
         | 
| 78 | 
            +
             | 
| 75 79 | 
             
            ## Contributing
         | 
| 76 80 |  | 
| 77 81 | 
             
            Checkout the [contribution guidelines](CONTRIBUTING.md).
         | 
    
        data/config/default.yml
    CHANGED
    
    | @@ -1,5 +1,22 @@ | |
| 1 1 | 
             
            # This is the default configuration file.
         | 
| 2 2 |  | 
| 3 | 
            +
            Performance/AncestorsInclude:
         | 
| 4 | 
            +
              Description: 'Use `A <= B` instead of `A.ancestors.include?(B)`.'
         | 
| 5 | 
            +
              Reference: 'https://github.com/JuanitoFatas/fast-ruby#ancestorsinclude-vs--code'
         | 
| 6 | 
            +
              Enabled: 'pending'
         | 
| 7 | 
            +
              Safe: false
         | 
| 8 | 
            +
              VersionAdded: '1.7'
         | 
| 9 | 
            +
             | 
| 10 | 
            +
            Performance/BigDecimalWithNumericArgument:
         | 
| 11 | 
            +
              Description: 'Convert numeric argument to string before passing to BigDecimal.'
         | 
| 12 | 
            +
              Enabled: 'pending'
         | 
| 13 | 
            +
              VersionAdded: '1.7'
         | 
| 14 | 
            +
             | 
| 15 | 
            +
            Performance/BindCall:
         | 
| 16 | 
            +
              Description: 'Use `bind_call(obj, args, ...)` instead of `bind(obj).call(args, ...)`.'
         | 
| 17 | 
            +
              Enabled: true
         | 
| 18 | 
            +
              VersionAdded: '1.6'
         | 
| 19 | 
            +
             | 
| 3 20 | 
             
            Performance/Caller:
         | 
| 4 21 | 
             
              Description: >-
         | 
| 5 22 | 
             
                         Use `caller(n..n)` instead of `caller`.
         | 
| @@ -21,6 +38,7 @@ Performance/Casecmp: | |
| 21 38 | 
             
                         Use `casecmp` rather than `downcase ==`, `upcase ==`, `== downcase`, or `== upcase`..
         | 
| 22 39 | 
             
              Reference: 'https://github.com/JuanitoFatas/fast-ruby#stringcasecmp-vs-stringdowncase---code'
         | 
| 23 40 | 
             
              Enabled: true
         | 
| 41 | 
            +
              Safe: false
         | 
| 24 42 | 
             
              VersionAdded: '0.36'
         | 
| 25 43 |  | 
| 26 44 | 
             
            Performance/ChainArrayAllocation:
         | 
| @@ -31,6 +49,13 @@ Performance/ChainArrayAllocation: | |
| 31 49 | 
             
              Enabled: false
         | 
| 32 50 | 
             
              VersionAdded: '0.59'
         | 
| 33 51 |  | 
| 52 | 
            +
            Performance/CollectionLiteralInLoop:
         | 
| 53 | 
            +
              Description: 'Extract Array and Hash literals outside of loops into local variables or constants.'
         | 
| 54 | 
            +
              Enabled: true
         | 
| 55 | 
            +
              VersionAdded: '1.8'
         | 
| 56 | 
            +
              # Min number of elements to consider an offense
         | 
| 57 | 
            +
              MinSize: 1
         | 
| 58 | 
            +
             | 
| 34 59 | 
             
            Performance/CompareWithBlock:
         | 
| 35 60 | 
             
              Description: 'Use `sort_by(&:foo)` instead of `sort { |a, b| a.foo <=> b.foo }`.'
         | 
| 36 61 | 
             
              Enabled: true
         | 
| @@ -38,21 +63,31 @@ Performance/CompareWithBlock: | |
| 38 63 |  | 
| 39 64 | 
             
            Performance/Count:
         | 
| 40 65 | 
             
              Description: >-
         | 
| 41 | 
            -
                              Use `count` instead of `select | 
| 42 | 
            -
                              `select...count`, `reject...count`, `select...length`,
         | 
| 43 | 
            -
                              and `reject...length`.
         | 
| 66 | 
            +
                              Use `count` instead of `{select,find_all,filter,reject}...{size,count,length}`.
         | 
| 44 67 | 
             
              # This cop has known compatibility issues with `ActiveRecord` and other
         | 
| 45 68 | 
             
              # frameworks. ActiveRecord's `count` ignores the block that is passed to it.
         | 
| 46 69 | 
             
              # For more information, see the documentation in the cop itself.
         | 
| 47 70 | 
             
              SafeAutoCorrect: false
         | 
| 48 71 | 
             
              Enabled: true
         | 
| 49 72 | 
             
              VersionAdded: '0.31'
         | 
| 50 | 
            -
              VersionChanged: '1. | 
| 73 | 
            +
              VersionChanged: '1.8'
         | 
| 74 | 
            +
             | 
| 75 | 
            +
            Performance/DeletePrefix:
         | 
| 76 | 
            +
              Description: 'Use `delete_prefix` instead of `gsub`.'
         | 
| 77 | 
            +
              Enabled: true
         | 
| 78 | 
            +
              SafeMultiline: true
         | 
| 79 | 
            +
              VersionAdded: '1.6'
         | 
| 80 | 
            +
             | 
| 81 | 
            +
            Performance/DeleteSuffix:
         | 
| 82 | 
            +
              Description: 'Use `delete_suffix` instead of `gsub`.'
         | 
| 83 | 
            +
              Enabled: true
         | 
| 84 | 
            +
              SafeMultiline: true
         | 
| 85 | 
            +
              VersionAdded: '1.6'
         | 
| 51 86 |  | 
| 52 87 | 
             
            Performance/Detect:
         | 
| 53 88 | 
             
              Description: >-
         | 
| 54 | 
            -
                              Use `detect` instead of `select.first`, `find_all.first`,
         | 
| 55 | 
            -
                              `select.last`, and ` | 
| 89 | 
            +
                              Use `detect` instead of `select.first`, `find_all.first`, `filter.first`,
         | 
| 90 | 
            +
                              `select.last`, `find_all.last`, and `filter.last`.
         | 
| 56 91 | 
             
              Reference: 'https://github.com/JuanitoFatas/fast-ruby#enumerabledetect-vs-enumerableselectfirst-code'
         | 
| 57 92 | 
             
              # This cop has known compatibility issues with `ActiveRecord` and other
         | 
| 58 93 | 
             
              # frameworks. `ActiveRecord` does not implement a `detect` method and `find`
         | 
| @@ -61,7 +96,7 @@ Performance/Detect: | |
| 61 96 | 
             
              SafeAutoCorrect: false
         | 
| 62 97 | 
             
              Enabled: true
         | 
| 63 98 | 
             
              VersionAdded: '0.30'
         | 
| 64 | 
            -
              VersionChanged: '1. | 
| 99 | 
            +
              VersionChanged: '1.8'
         | 
| 65 100 |  | 
| 66 101 | 
             
            Performance/DoubleStartEndWith:
         | 
| 67 102 | 
             
              Description: >-
         | 
| @@ -83,11 +118,12 @@ Performance/EndWith: | |
| 83 118 | 
             
              SafeAutoCorrect: false
         | 
| 84 119 | 
             
              AutoCorrect: false
         | 
| 85 120 | 
             
              Enabled: true
         | 
| 121 | 
            +
              SafeMultiline: true
         | 
| 86 122 | 
             
              VersionAdded: '0.36'
         | 
| 87 | 
            -
              VersionChanged: ' | 
| 123 | 
            +
              VersionChanged: '1.6'
         | 
| 88 124 |  | 
| 89 125 | 
             
            Performance/FixedSize:
         | 
| 90 | 
            -
              Description: 'Do not compute the size of statically sized objects except in constants'
         | 
| 126 | 
            +
              Description: 'Do not compute the size of statically sized objects except in constants.'
         | 
| 91 127 | 
             
              Enabled: true
         | 
| 92 128 | 
             
              VersionAdded: '0.35'
         | 
| 93 129 |  | 
| @@ -95,7 +131,7 @@ Performance/FlatMap: | |
| 95 131 | 
             
              Description: >-
         | 
| 96 132 | 
             
                              Use `Enumerable#flat_map`
         | 
| 97 133 | 
             
                              instead of `Enumerable#map...Array#flatten(1)`
         | 
| 98 | 
            -
                              or `Enumberable#collect..Array#flatten(1) | 
| 134 | 
            +
                              or `Enumberable#collect..Array#flatten(1)`.
         | 
| 99 135 | 
             
              Reference: 'https://github.com/JuanitoFatas/fast-ruby#enumerablemaparrayflatten-vs-enumerableflat_map-code'
         | 
| 100 136 | 
             
              Enabled: true
         | 
| 101 137 | 
             
              VersionAdded: '0.30'
         | 
| @@ -106,12 +142,18 @@ Performance/FlatMap: | |
| 106 142 | 
             
              # `flatten` without any parameters can flatten multiple levels.
         | 
| 107 143 |  | 
| 108 144 | 
             
            Performance/InefficientHashSearch:
         | 
| 109 | 
            -
              Description: 'Use `key?` or `value?` instead of `keys.include?` or `values.include | 
| 145 | 
            +
              Description: 'Use `key?` or `value?` instead of `keys.include?` or `values.include?`.'
         | 
| 110 146 | 
             
              Reference: 'https://github.com/JuanitoFatas/fast-ruby#hashkey-instead-of-hashkeysinclude-code'
         | 
| 111 147 | 
             
              Enabled: true
         | 
| 112 148 | 
             
              VersionAdded: '0.56'
         | 
| 113 149 | 
             
              Safe: false
         | 
| 114 150 |  | 
| 151 | 
            +
            Performance/IoReadlines:
         | 
| 152 | 
            +
              Description: 'Use `IO.each_line` (`IO#each_line`) instead of `IO.readlines` (`IO#readlines`).'
         | 
| 153 | 
            +
              Reference: 'https://docs.gitlab.com/ee/development/performance.html#reading-from-files-and-other-data-sources'
         | 
| 154 | 
            +
              Enabled: false
         | 
| 155 | 
            +
              VersionAdded: '1.7'
         | 
| 156 | 
            +
             | 
| 115 157 | 
             
            Performance/OpenStruct:
         | 
| 116 158 | 
             
              Description: 'Use `Struct` instead of `OpenStruct`.'
         | 
| 117 159 | 
             
              Enabled: false
         | 
| @@ -119,10 +161,11 @@ Performance/OpenStruct: | |
| 119 161 | 
             
              Safe: false
         | 
| 120 162 |  | 
| 121 163 | 
             
            Performance/RangeInclude:
         | 
| 122 | 
            -
              Description: 'Use `Range#cover?` instead of `Range#include | 
| 164 | 
            +
              Description: 'Use `Range#cover?` instead of `Range#include?` (or `Range#member?`).'
         | 
| 123 165 | 
             
              Reference: 'https://github.com/JuanitoFatas/fast-ruby#cover-vs-include-code'
         | 
| 124 166 | 
             
              Enabled: true
         | 
| 125 167 | 
             
              VersionAdded: '0.36'
         | 
| 168 | 
            +
              VersionChanged: '1.7'
         | 
| 126 169 | 
             
              Safe: false
         | 
| 127 170 |  | 
| 128 171 | 
             
            Performance/RedundantBlockCall:
         | 
| @@ -146,6 +189,16 @@ Performance/RedundantMerge: | |
| 146 189 | 
             
              # Max number of key-value pairs to consider an offense
         | 
| 147 190 | 
             
              MaxKeyValuePairs: 2
         | 
| 148 191 |  | 
| 192 | 
            +
            Performance/RedundantSortBlock:
         | 
| 193 | 
            +
              Description: 'Use `sort` instead of `sort { |a, b| a <=> b }`.'
         | 
| 194 | 
            +
              Enabled: 'pending'
         | 
| 195 | 
            +
              VersionAdded: '1.7'
         | 
| 196 | 
            +
             | 
| 197 | 
            +
            Performance/RedundantStringChars:
         | 
| 198 | 
            +
              Description: 'Checks for redundant `String#chars`.'
         | 
| 199 | 
            +
              Enabled: 'pending'
         | 
| 200 | 
            +
              VersionAdded: '1.7'
         | 
| 201 | 
            +
             | 
| 149 202 | 
             
            Performance/RegexpMatch:
         | 
| 150 203 | 
             
              Description: >-
         | 
| 151 204 | 
             
                              Use `match?` instead of `Regexp#match`, `String#match`, `Symbol#match`,
         | 
| @@ -160,6 +213,11 @@ Performance/ReverseEach: | |
| 160 213 | 
             
              Enabled: true
         | 
| 161 214 | 
             
              VersionAdded: '0.30'
         | 
| 162 215 |  | 
| 216 | 
            +
            Performance/ReverseFirst:
         | 
| 217 | 
            +
              Description: 'Use `last(n).reverse` instead of `reverse.first(n)`.'
         | 
| 218 | 
            +
              Enabled: 'pending'
         | 
| 219 | 
            +
              VersionAdded: '1.7'
         | 
| 220 | 
            +
             | 
| 163 221 | 
             
            Performance/Size:
         | 
| 164 222 | 
             
              Description: >-
         | 
| 165 223 | 
             
                              Use `size` instead of `count` for counting
         | 
| @@ -168,6 +226,17 @@ Performance/Size: | |
| 168 226 | 
             
              Enabled: true
         | 
| 169 227 | 
             
              VersionAdded: '0.30'
         | 
| 170 228 |  | 
| 229 | 
            +
            Performance/SortReverse:
         | 
| 230 | 
            +
              Description: 'Use `sort.reverse` instead of `sort { |a, b| b <=> a }`.'
         | 
| 231 | 
            +
              Enabled: 'pending'
         | 
| 232 | 
            +
              VersionAdded: '1.7'
         | 
| 233 | 
            +
             | 
| 234 | 
            +
            Performance/Squeeze:
         | 
| 235 | 
            +
              Description: "Use `squeeze('a')` instead of `gsub(/a+/, 'a')`."
         | 
| 236 | 
            +
              Reference: 'https://github.com/JuanitoFatas/fast-ruby#remove-extra-spaces-or-other-contiguous-characters-code'
         | 
| 237 | 
            +
              Enabled: 'pending'
         | 
| 238 | 
            +
              VersionAdded: '1.7'
         | 
| 239 | 
            +
             | 
| 171 240 | 
             
            Performance/StartWith:
         | 
| 172 241 | 
             
              Description: 'Use `start_with?` instead of a regex match anchored to the beginning of a string.'
         | 
| 173 242 | 
             
              Reference: 'https://github.com/JuanitoFatas/fast-ruby#stringmatch-vs-stringstart_withstringend_with-code-start-code-end'
         | 
| @@ -177,8 +246,16 @@ Performance/StartWith: | |
| 177 246 | 
             
              SafeAutoCorrect: false
         | 
| 178 247 | 
             
              AutoCorrect: false
         | 
| 179 248 | 
             
              Enabled: true
         | 
| 249 | 
            +
              SafeMultiline: true
         | 
| 180 250 | 
             
              VersionAdded: '0.36'
         | 
| 181 | 
            -
              VersionChanged: ' | 
| 251 | 
            +
              VersionChanged: '1.6'
         | 
| 252 | 
            +
             | 
| 253 | 
            +
            Performance/StringInclude:
         | 
| 254 | 
            +
              Description: 'Use `String#include?` instead of a regex match with literal-only pattern.'
         | 
| 255 | 
            +
              Enabled: 'pending'
         | 
| 256 | 
            +
              AutoCorrect: false
         | 
| 257 | 
            +
              SafeAutoCorrect: false
         | 
| 258 | 
            +
              VersionAdded: '1.7'
         | 
| 182 259 |  | 
| 183 260 | 
             
            Performance/StringReplacement:
         | 
| 184 261 | 
             
              Description: >-
         | 
| @@ -189,6 +266,12 @@ Performance/StringReplacement: | |
| 189 266 | 
             
              Enabled: true
         | 
| 190 267 | 
             
              VersionAdded: '0.33'
         | 
| 191 268 |  | 
| 269 | 
            +
            Performance/Sum:
         | 
| 270 | 
            +
              Description: 'Use `sum` instead of a custom array summation.'
         | 
| 271 | 
            +
              Reference: 'https://blog.bigbinary.com/2016/11/02/ruby-2-4-introduces-enumerable-sum.html'
         | 
| 272 | 
            +
              Enabled: 'pending'
         | 
| 273 | 
            +
              VersionAdded: '1.8'
         | 
| 274 | 
            +
             | 
| 192 275 | 
             
            Performance/TimesMap:
         | 
| 193 276 | 
             
              Description: 'Checks for .times.map calls.'
         | 
| 194 277 | 
             
              AutoCorrect: false
         | 
| @@ -0,0 +1,76 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module RuboCop
         | 
| 4 | 
            +
              module Cop
         | 
| 5 | 
            +
                # Common functionality for handling regexp metacharacters.
         | 
| 6 | 
            +
                module RegexpMetacharacter
         | 
| 7 | 
            +
                  private
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                  def literal_at_start?(regexp)
         | 
| 10 | 
            +
                    return true if literal_at_start_with_backslash_a?(regexp)
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                    !safe_multiline? && literal_at_start_with_caret?(regexp)
         | 
| 13 | 
            +
                  end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                  def literal_at_end?(regexp)
         | 
| 16 | 
            +
                    return true if literal_at_end_with_backslash_z?(regexp)
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                    !safe_multiline? && literal_at_end_with_dollar?(regexp)
         | 
| 19 | 
            +
                  end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                  def literal_at_start_with_backslash_a?(regex_str)
         | 
| 22 | 
            +
                    # is this regexp 'literal' in the sense of only matching literal
         | 
| 23 | 
            +
                    # chars, rather than using metachars like `.` and `*` and so on?
         | 
| 24 | 
            +
                    # also, is it anchored at the start of the string?
         | 
| 25 | 
            +
                    # (tricky: \s, \d, and so on are metacharacters, but other characters
         | 
| 26 | 
            +
                    #  escaped with a slash are just literals. LITERAL_REGEX takes all
         | 
| 27 | 
            +
                    #  that into account.)
         | 
| 28 | 
            +
                    /\A\\A(?:#{Util::LITERAL_REGEX})+\z/.match?(regex_str)
         | 
| 29 | 
            +
                  end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                  def literal_at_start_with_caret?(regex_str)
         | 
| 32 | 
            +
                    # is this regexp 'literal' in the sense of only matching literal
         | 
| 33 | 
            +
                    # chars, rather than using metachars like `.` and `*` and so on?
         | 
| 34 | 
            +
                    # also, is it anchored at the start of the string?
         | 
| 35 | 
            +
                    # (tricky: \s, \d, and so on are metacharacters, but other characters
         | 
| 36 | 
            +
                    #  escaped with a slash are just literals. LITERAL_REGEX takes all
         | 
| 37 | 
            +
                    #  that into account.)
         | 
| 38 | 
            +
                    /\A\^(?:#{Util::LITERAL_REGEX})+\z/.match?(regex_str)
         | 
| 39 | 
            +
                  end
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                  def literal_at_end_with_backslash_z?(regex_str)
         | 
| 42 | 
            +
                    # is this regexp 'literal' in the sense of only matching literal
         | 
| 43 | 
            +
                    # chars, rather than using metachars like . and * and so on?
         | 
| 44 | 
            +
                    # also, is it anchored at the end of the string?
         | 
| 45 | 
            +
                    /\A(?:#{Util::LITERAL_REGEX})+\\z\z/.match?(regex_str)
         | 
| 46 | 
            +
                  end
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                  def literal_at_end_with_dollar?(regex_str)
         | 
| 49 | 
            +
                    # is this regexp 'literal' in the sense of only matching literal
         | 
| 50 | 
            +
                    # chars, rather than using metachars like . and * and so on?
         | 
| 51 | 
            +
                    # also, is it anchored at the end of the string?
         | 
| 52 | 
            +
                    /\A(?:#{Util::LITERAL_REGEX})+\$\z/.match?(regex_str)
         | 
| 53 | 
            +
                  end
         | 
| 54 | 
            +
             | 
| 55 | 
            +
                  def drop_start_metacharacter(regexp_string)
         | 
| 56 | 
            +
                    if regexp_string.start_with?('\\A')
         | 
| 57 | 
            +
                      regexp_string[2..-1] # drop `\A` anchor
         | 
| 58 | 
            +
                    else
         | 
| 59 | 
            +
                      regexp_string[1..-1] # drop `^` anchor
         | 
| 60 | 
            +
                    end
         | 
| 61 | 
            +
                  end
         | 
| 62 | 
            +
             | 
| 63 | 
            +
                  def drop_end_metacharacter(regexp_string)
         | 
| 64 | 
            +
                    if regexp_string.end_with?('\\z')
         | 
| 65 | 
            +
                      regexp_string.chomp('\z') # drop `\z` anchor
         | 
| 66 | 
            +
                    else
         | 
| 67 | 
            +
                      regexp_string.chop # drop `$` anchor
         | 
| 68 | 
            +
                    end
         | 
| 69 | 
            +
                  end
         | 
| 70 | 
            +
             | 
| 71 | 
            +
                  def safe_multiline?
         | 
| 72 | 
            +
                    cop_config.fetch('SafeMultiline', true)
         | 
| 73 | 
            +
                  end
         | 
| 74 | 
            +
                end
         | 
| 75 | 
            +
              end
         | 
| 76 | 
            +
            end
         | 
| @@ -0,0 +1,28 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module RuboCop
         | 
| 4 | 
            +
              module Cop
         | 
| 5 | 
            +
                # Common functionality for cops checking `Enumerable#sort` blocks.
         | 
| 6 | 
            +
                module SortBlock
         | 
| 7 | 
            +
                  extend NodePattern::Macros
         | 
| 8 | 
            +
                  include RangeHelp
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                  def_node_matcher :sort_with_block?, <<~PATTERN
         | 
| 11 | 
            +
                    (block
         | 
| 12 | 
            +
                      $(send _ :sort)
         | 
| 13 | 
            +
                      (args (arg $_a) (arg $_b))
         | 
| 14 | 
            +
                      $send)
         | 
| 15 | 
            +
                  PATTERN
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                  def_node_matcher :replaceable_body?, <<~PATTERN
         | 
| 18 | 
            +
                    (send (lvar %1) :<=> (lvar %2))
         | 
| 19 | 
            +
                  PATTERN
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                  private
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                  def sort_range(send, node)
         | 
| 24 | 
            +
                    range_between(send.loc.selector.begin_pos, node.loc.end.end_pos)
         | 
| 25 | 
            +
                  end
         | 
| 26 | 
            +
                end
         | 
| 27 | 
            +
              end
         | 
| 28 | 
            +
            end
         | 
| @@ -0,0 +1,48 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module RuboCop
         | 
| 4 | 
            +
              module Cop
         | 
| 5 | 
            +
                module Performance
         | 
| 6 | 
            +
                  # This cop is used to identify usages of `ancestors.include?` and
         | 
| 7 | 
            +
                  # change them to use `<=` instead.
         | 
| 8 | 
            +
                  #
         | 
| 9 | 
            +
                  # @example
         | 
| 10 | 
            +
                  #   # bad
         | 
| 11 | 
            +
                  #   A.ancestors.include?(B)
         | 
| 12 | 
            +
                  #
         | 
| 13 | 
            +
                  #   # good
         | 
| 14 | 
            +
                  #   A <= B
         | 
| 15 | 
            +
                  #
         | 
| 16 | 
            +
                  class AncestorsInclude < Base
         | 
| 17 | 
            +
                    include RangeHelp
         | 
| 18 | 
            +
                    extend AutoCorrector
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                    MSG = 'Use `<=` instead of `ancestors.include?`.'
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                    def_node_matcher :ancestors_include_candidate?, <<~PATTERN
         | 
| 23 | 
            +
                      (send (send $_subclass :ancestors) :include? $_superclass)
         | 
| 24 | 
            +
                    PATTERN
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                    def on_send(node)
         | 
| 27 | 
            +
                      return unless (subclass, superclass = ancestors_include_candidate?(node))
         | 
| 28 | 
            +
                      return if subclass && !subclass.const_type?
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                      add_offense(range(node)) do |corrector|
         | 
| 31 | 
            +
                        subclass_source = subclass ? subclass.source : 'self'
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                        corrector.replace(node, "#{subclass_source} <= #{superclass.source}")
         | 
| 34 | 
            +
                      end
         | 
| 35 | 
            +
                    end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                    private
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                    def range(node)
         | 
| 40 | 
            +
                      location_of_ancestors = node.children[0].loc.selector.begin_pos
         | 
| 41 | 
            +
                      end_location = node.loc.selector.end_pos
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                      range_between(location_of_ancestors, end_location)
         | 
| 44 | 
            +
                    end
         | 
| 45 | 
            +
                  end
         | 
| 46 | 
            +
                end
         | 
| 47 | 
            +
              end
         | 
| 48 | 
            +
            end
         | 
| @@ -0,0 +1,45 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module RuboCop
         | 
| 4 | 
            +
              module Cop
         | 
| 5 | 
            +
                module Performance
         | 
| 6 | 
            +
                  # This cop identifies places where numeric argument to BigDecimal should be
         | 
| 7 | 
            +
                  # converted to string. Initializing from String is faster
         | 
| 8 | 
            +
                  # than from Numeric for BigDecimal.
         | 
| 9 | 
            +
                  #
         | 
| 10 | 
            +
                  # @example
         | 
| 11 | 
            +
                  #   # bad
         | 
| 12 | 
            +
                  #   BigDecimal(1, 2)
         | 
| 13 | 
            +
                  #   BigDecimal(1.2, 3, exception: true)
         | 
| 14 | 
            +
                  #
         | 
| 15 | 
            +
                  #   # good
         | 
| 16 | 
            +
                  #   BigDecimal('1', 2)
         | 
| 17 | 
            +
                  #   BigDecimal('1.2', 3, exception: true)
         | 
| 18 | 
            +
                  #
         | 
| 19 | 
            +
                  class BigDecimalWithNumericArgument < Base
         | 
| 20 | 
            +
                    extend AutoCorrector
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                    MSG = 'Convert numeric argument to string before passing to `BigDecimal`.'
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                    def_node_matcher :big_decimal_with_numeric_argument?, <<~PATTERN
         | 
| 25 | 
            +
                      (send nil? :BigDecimal $numeric_type? ...)
         | 
| 26 | 
            +
                    PATTERN
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                    def on_send(node)
         | 
| 29 | 
            +
                      return unless (numeric = big_decimal_with_numeric_argument?(node))
         | 
| 30 | 
            +
                      return if numeric.float_type? && specifies_precision?(node)
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                      add_offense(numeric.source_range) do |corrector|
         | 
| 33 | 
            +
                        corrector.wrap(numeric, "'", "'")
         | 
| 34 | 
            +
                      end
         | 
| 35 | 
            +
                    end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                    private
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                    def specifies_precision?(node)
         | 
| 40 | 
            +
                      node.arguments.size > 1 && !node.arguments[1].hash_type?
         | 
| 41 | 
            +
                    end
         | 
| 42 | 
            +
                  end
         | 
| 43 | 
            +
                end
         | 
| 44 | 
            +
              end
         | 
| 45 | 
            +
            end
         |