rubocop 1.27.0 → 1.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/config/default.yml +50 -9
- data/config/obsoletion.yml +10 -1
- data/lib/rubocop/cli/command/suggest_extensions.rb +1 -1
- data/lib/rubocop/cop/gemspec/date_assignment.rb +2 -2
- data/lib/rubocop/cop/layout/case_indentation.rb +16 -0
- data/lib/rubocop/cop/layout/indentation_width.rb +2 -2
- data/lib/rubocop/cop/layout/line_length.rb +4 -4
- data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +19 -2
- data/lib/rubocop/cop/layout/trailing_whitespace.rb +1 -1
- data/lib/rubocop/cop/lint/duplicate_require.rb +10 -1
- data/lib/rubocop/cop/lint/unreachable_loop.rb +4 -4
- data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +1 -1
- data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +16 -2
- data/lib/rubocop/cop/mixin/allowed_pattern.rb +40 -0
- data/lib/rubocop/cop/mixin/comments_help.rb +3 -1
- data/lib/rubocop/cop/naming/method_name.rb +5 -5
- data/lib/rubocop/cop/offense.rb +1 -1
- data/lib/rubocop/cop/security/compound_hash.rb +105 -0
- data/lib/rubocop/cop/style/fetch_env_var.rb +76 -0
- data/lib/rubocop/cop/style/guard_clause.rb +45 -0
- data/lib/rubocop/cop/style/if_unless_modifier.rb +5 -4
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/require_parentheses.rb +1 -1
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +4 -4
- data/lib/rubocop/cop/style/multiline_ternary_operator.rb +33 -11
- data/lib/rubocop/cop/style/object_then.rb +69 -0
- data/lib/rubocop/cop/style/redundant_initialize.rb +39 -4
- data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +5 -0
- data/lib/rubocop/cop/style/single_argument_dig.rb +4 -0
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +7 -7
- data/lib/rubocop/cop/style/special_global_vars.rb +66 -8
- data/lib/rubocop/cop/style/symbol_proc.rb +24 -0
- data/lib/rubocop/cop/variable_force/branch.rb +1 -1
- data/lib/rubocop/options.rb +27 -1
- data/lib/rubocop/result_cache.rb +3 -3
- data/lib/rubocop/rspec/shared_contexts.rb +2 -2
- data/lib/rubocop/runner.rb +29 -3
- data/lib/rubocop/version.rb +1 -1
- data/lib/rubocop.rb +4 -1
- metadata +9 -6
- data/lib/rubocop/cop/mixin/ignored_pattern.rb +0 -29
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: af243a553ad28a14173bdaad5e52f46e61c2d61096c6cab37ae41ccf88cad1ff
         | 
| 4 | 
            +
              data.tar.gz: efe4a129082e9e879501b01772d7708a80020ab71b10f24fc2ffff32819d50b3
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 536ced62e51af2fa59a347dc416d0af919ebbe04335e37a2011d704c11821d170decaad13bc7f6abe59da23146cdc2be31820458941fa8272c59b266bb852dae
         | 
| 7 | 
            +
              data.tar.gz: 3087db4a3f808c630eaf850d1ac371cca4dda687fe1459cf5125e1fc49e55451b4c90fd9fdace47d93049bfa0d569138e361461ead47eac8503553907b47b32c
         | 
    
        data/README.md
    CHANGED
    
    | @@ -53,7 +53,7 @@ To prevent an unwanted RuboCop update you might want to use a conservative versi | |
| 53 53 | 
             
            in your `Gemfile`:
         | 
| 54 54 |  | 
| 55 55 | 
             
            ```rb
         | 
| 56 | 
            -
            gem 'rubocop', '~> 1. | 
| 56 | 
            +
            gem 'rubocop', '~> 1.28', require: false
         | 
| 57 57 | 
             
            ```
         | 
| 58 58 |  | 
| 59 59 | 
             
            See [our versioning policy](https://docs.rubocop.org/rubocop/versioning.html) for further details.
         | 
    
        data/config/default.yml
    CHANGED
    
    | @@ -931,7 +931,8 @@ Layout/IndentationWidth: | |
| 931 931 | 
             
              VersionAdded: '0.49'
         | 
| 932 932 | 
             
              # Number of spaces for each indentation level.
         | 
| 933 933 | 
             
              Width: 2
         | 
| 934 | 
            -
               | 
| 934 | 
            +
              AllowedPatterns: []
         | 
| 935 | 
            +
              IgnoredPatterns: [] # deprecated
         | 
| 935 936 |  | 
| 936 937 | 
             
            Layout/InitialIndentation:
         | 
| 937 938 | 
             
              Description: >-
         | 
| @@ -985,10 +986,11 @@ Layout/LineLength: | |
| 985 986 | 
             
              # The IgnoreCopDirectives option causes the LineLength rule to ignore cop
         | 
| 986 987 | 
             
              # directives like '# rubocop: enable ...' when calculating a line's length.
         | 
| 987 988 | 
             
              IgnoreCopDirectives: true
         | 
| 988 | 
            -
              # The  | 
| 989 | 
            +
              # The AllowedPatterns option is a list of !ruby/regexp and/or string
         | 
| 989 990 | 
             
              # elements. Strings will be converted to Regexp objects. A line that matches
         | 
| 990 991 | 
             
              # any regular expression listed in this option will be ignored by LineLength.
         | 
| 991 | 
            -
               | 
| 992 | 
            +
              AllowedPatterns: []
         | 
| 993 | 
            +
              IgnoredPatterns: [] # deprecated
         | 
| 992 994 |  | 
| 993 995 | 
             
            Layout/MultilineArrayBraceLayout:
         | 
| 994 996 | 
             
              Description: >-
         | 
| @@ -1661,7 +1663,9 @@ Lint/DuplicateRegexpCharacterClassElement: | |
| 1661 1663 | 
             
            Lint/DuplicateRequire:
         | 
| 1662 1664 | 
             
              Description: 'Check for duplicate `require`s and `require_relative`s.'
         | 
| 1663 1665 | 
             
              Enabled: true
         | 
| 1666 | 
            +
              SafeAutoCorrect: false
         | 
| 1664 1667 | 
             
              VersionAdded: '0.90'
         | 
| 1668 | 
            +
              VersionChanged: '1.28'
         | 
| 1665 1669 |  | 
| 1666 1670 | 
             
            Lint/DuplicateRescueException:
         | 
| 1667 1671 | 
             
              Description: 'Checks that there are no repeated exceptions used in `rescue` expressions.'
         | 
| @@ -2270,10 +2274,11 @@ Lint/UnreachableLoop: | |
| 2270 2274 | 
             
              Enabled: true
         | 
| 2271 2275 | 
             
              VersionAdded: '0.89'
         | 
| 2272 2276 | 
             
              VersionChanged: '1.7'
         | 
| 2273 | 
            -
               | 
| 2277 | 
            +
              AllowedPatterns:
         | 
| 2274 2278 | 
             
                # RSpec uses `times` in its message expectations
         | 
| 2275 2279 | 
             
                # eg. `exactly(2).times`
         | 
| 2276 2280 | 
             
                - !ruby/regexp /(exactly|at_least|at_most)\(\d+\)\.times/
         | 
| 2281 | 
            +
              IgnoredPatterns: [] # deprecated
         | 
| 2277 2282 |  | 
| 2278 2283 | 
             
            Lint/UnusedBlockArgument:
         | 
| 2279 2284 | 
             
              Description: 'Checks for unused block arguments.'
         | 
| @@ -2686,11 +2691,12 @@ Naming/MethodName: | |
| 2686 2691 | 
             
                - camelCase
         | 
| 2687 2692 | 
             
              # Method names matching patterns are always allowed.
         | 
| 2688 2693 | 
             
              #
         | 
| 2689 | 
            -
              #    | 
| 2694 | 
            +
              #   AllowedPatterns:
         | 
| 2690 2695 | 
             
              #     - '\A\s*onSelectionBulkChange\s*'
         | 
| 2691 2696 | 
             
              #     - '\A\s*onSelectionCleared\s*'
         | 
| 2692 2697 | 
             
              #
         | 
| 2693 | 
            -
               | 
| 2698 | 
            +
              AllowedPatterns: []
         | 
| 2699 | 
            +
              IgnoredPatterns: [] # deprecated
         | 
| 2694 2700 |  | 
| 2695 2701 | 
             
            Naming/MethodParameterName:
         | 
| 2696 2702 | 
             
              Description: >-
         | 
| @@ -2790,6 +2796,11 @@ Naming/VariableNumber: | |
| 2790 2796 |  | 
| 2791 2797 | 
             
            #################### Security ##############################
         | 
| 2792 2798 |  | 
| 2799 | 
            +
            Security/CompoundHash:
         | 
| 2800 | 
            +
              Description: 'When overwriting Object#hash to combine values, prefer delegating to Array#hash over writing a custom implementation.'
         | 
| 2801 | 
            +
              Enabled: pending
         | 
| 2802 | 
            +
              VersionAdded: '1.28'
         | 
| 2803 | 
            +
             | 
| 2793 2804 | 
             
            Security/Eval:
         | 
| 2794 2805 | 
             
              Description: 'The use of eval represents a serious security risk.'
         | 
| 2795 2806 | 
             
              Enabled: true
         | 
| @@ -3521,6 +3532,16 @@ Style/ExponentialNotation: | |
| 3521 3532 | 
             
                - engineering
         | 
| 3522 3533 | 
             
                - integral
         | 
| 3523 3534 |  | 
| 3535 | 
            +
            Style/FetchEnvVar:
         | 
| 3536 | 
            +
              Description: >-
         | 
| 3537 | 
            +
                             This cop suggests `ENV.fetch` for the replacement of `ENV[]`.
         | 
| 3538 | 
            +
              Reference:
         | 
| 3539 | 
            +
                - https://rubystyle.guide/#hash-fetch-defaults
         | 
| 3540 | 
            +
              Enabled: pending
         | 
| 3541 | 
            +
              VersionAdded: '1.28'
         | 
| 3542 | 
            +
              # Environment variables to be excluded from the inspection.
         | 
| 3543 | 
            +
              AllowedVars: []
         | 
| 3544 | 
            +
             | 
| 3524 3545 | 
             
            Style/FileRead:
         | 
| 3525 3546 | 
             
              Description: 'Favor `File.(bin)read` convenience methods.'
         | 
| 3526 3547 | 
             
              StyleGuide: '#file-read'
         | 
| @@ -3634,10 +3655,11 @@ Style/GuardClause: | |
| 3634 3655 | 
             
              StyleGuide: '#no-nested-conditionals'
         | 
| 3635 3656 | 
             
              Enabled: true
         | 
| 3636 3657 | 
             
              VersionAdded: '0.20'
         | 
| 3637 | 
            -
              VersionChanged: ' | 
| 3658 | 
            +
              VersionChanged: '1.28'
         | 
| 3638 3659 | 
             
              # `MinBodyLength` defines the number of lines of the a body of an `if` or `unless`
         | 
| 3639 3660 | 
             
              # needs to have to trigger this cop
         | 
| 3640 3661 | 
             
              MinBodyLength: 1
         | 
| 3662 | 
            +
              AllowConsecutiveConditionals: false
         | 
| 3641 3663 |  | 
| 3642 3664 | 
             
            Style/HashAsLastArrayItem:
         | 
| 3643 3665 | 
             
              Description: >-
         | 
| @@ -3902,7 +3924,8 @@ Style/MethodCallWithArgsParentheses: | |
| 3902 3924 | 
             
              VersionChanged: '1.7'
         | 
| 3903 3925 | 
             
              IgnoreMacros: true
         | 
| 3904 3926 | 
             
              IgnoredMethods: []
         | 
| 3905 | 
            -
               | 
| 3927 | 
            +
              AllowedPatterns: []
         | 
| 3928 | 
            +
              IgnoredPatterns: [] # deprecated
         | 
| 3906 3929 | 
             
              IncludedMacros: []
         | 
| 3907 3930 | 
             
              AllowParenthesesInMultilineCall: false
         | 
| 3908 3931 | 
             
              AllowParenthesesInChaining: false
         | 
| @@ -4293,6 +4316,19 @@ Style/NumericPredicate: | |
| 4293 4316 | 
             
              Exclude:
         | 
| 4294 4317 | 
             
                - 'spec/**/*'
         | 
| 4295 4318 |  | 
| 4319 | 
            +
            Style/ObjectThen:
         | 
| 4320 | 
            +
              Description: 'Enforces the use of consistent method names `Object#yield_self` or `Object#then`.'
         | 
| 4321 | 
            +
              StyleGuide: '#object-yield-self-vs-object-then'
         | 
| 4322 | 
            +
              Enabled: pending
         | 
| 4323 | 
            +
              VersionAdded: '1.28'
         | 
| 4324 | 
            +
              # Use `Object#yield_self` or `Object#then`?
         | 
| 4325 | 
            +
              # Prefer `Object#yield_self` to `Object#then` (yield_self)
         | 
| 4326 | 
            +
              # Prefer `Object#then` to `Object#yield_self` (then)
         | 
| 4327 | 
            +
              EnforcedStyle: 'then'
         | 
| 4328 | 
            +
              SupportedStyles:
         | 
| 4329 | 
            +
                - then
         | 
| 4330 | 
            +
                - yield_self
         | 
| 4331 | 
            +
             | 
| 4296 4332 | 
             
            Style/OneLineConditional:
         | 
| 4297 4333 | 
             
              Description: >-
         | 
| 4298 4334 | 
             
                             Favor the ternary operator (?:) or multi-line constructs over
         | 
| @@ -4533,7 +4569,10 @@ Style/RedundantFreeze: | |
| 4533 4569 | 
             
            Style/RedundantInitialize:
         | 
| 4534 4570 | 
             
              Description: 'Checks for redundant `initialize` methods.'
         | 
| 4535 4571 | 
             
              Enabled: pending
         | 
| 4572 | 
            +
              Safe: false
         | 
| 4573 | 
            +
              AllowComments: true
         | 
| 4536 4574 | 
             
              VersionAdded: '1.27'
         | 
| 4575 | 
            +
              VersionChanged: '1.28'
         | 
| 4537 4576 |  | 
| 4538 4577 | 
             
            Style/RedundantInterpolation:
         | 
| 4539 4578 | 
             
              Description: 'Checks for strings that are just an interpolated expression.'
         | 
| @@ -4774,6 +4813,7 @@ Style/SpecialGlobalVars: | |
| 4774 4813 | 
             
              SupportedStyles:
         | 
| 4775 4814 | 
             
                - use_perl_names
         | 
| 4776 4815 | 
             
                - use_english_names
         | 
| 4816 | 
            +
                - use_builtin_english_names
         | 
| 4777 4817 |  | 
| 4778 4818 | 
             
            Style/StabbyLambdaParentheses:
         | 
| 4779 4819 | 
             
              Description: 'Check for the usage of parentheses around stabby lambda arguments.'
         | 
| @@ -4903,13 +4943,14 @@ Style/SymbolProc: | |
| 4903 4943 | 
             
              Enabled: true
         | 
| 4904 4944 | 
             
              Safe: false
         | 
| 4905 4945 | 
             
              VersionAdded: '0.26'
         | 
| 4906 | 
            -
              VersionChanged: '1. | 
| 4946 | 
            +
              VersionChanged: '1.28'
         | 
| 4907 4947 | 
             
              AllowMethodsWithArguments: false
         | 
| 4908 4948 | 
             
              # A list of method names to be ignored by the check.
         | 
| 4909 4949 | 
             
              # The names should be fairly unique, otherwise you'll end up ignoring lots of code.
         | 
| 4910 4950 | 
             
              IgnoredMethods:
         | 
| 4911 4951 | 
             
                - respond_to
         | 
| 4912 4952 | 
             
                - define_method
         | 
| 4953 | 
            +
              AllowComments: false
         | 
| 4913 4954 |  | 
| 4914 4955 | 
             
            Style/TernaryParentheses:
         | 
| 4915 4956 | 
             
              Description: 'Checks for use of parentheses around ternary conditions.'
         | 
    
        data/config/obsoletion.yml
    CHANGED
    
    | @@ -152,7 +152,7 @@ changed_parameters: | |
| 152 152 | 
             
                alternative: EnforcedStyle
         | 
| 153 153 | 
             
              - cops: Style/MethodCallWithArgsParentheses
         | 
| 154 154 | 
             
                parameters: IgnoredMethodPatterns
         | 
| 155 | 
            -
                alternative:  | 
| 155 | 
            +
                alternative: AllowedPatterns
         | 
| 156 156 | 
             
              - cops:
         | 
| 157 157 | 
             
                  - Performance/Count
         | 
| 158 158 | 
             
                  - Performance/Detect
         | 
| @@ -191,6 +191,15 @@ changed_parameters: | |
| 191 191 | 
             
                parameters: DebuggerReceivers
         | 
| 192 192 | 
             
                reason: "`DebuggerReceivers` is no longer necessary, method receivers should be specified in `DebuggerMethods` instead."
         | 
| 193 193 | 
             
                severity: warning
         | 
| 194 | 
            +
              - cops:
         | 
| 195 | 
            +
                  - Layout/IndentationWidth
         | 
| 196 | 
            +
                  - Layout/LineLength
         | 
| 197 | 
            +
                  - Lint/UnreachableLoop
         | 
| 198 | 
            +
                  - Naming/MethodName
         | 
| 199 | 
            +
                  - Style/MethodCallWithArgsParentheses
         | 
| 200 | 
            +
                parameters: IgnoredPatterns
         | 
| 201 | 
            +
                alternative: AllowedPatterns
         | 
| 202 | 
            +
                severity: warning
         | 
| 194 203 |  | 
| 195 204 | 
             
            # Enforced styles that have been removed or replaced
         | 
| 196 205 | 
             
            changed_enforced_styles:
         | 
| @@ -42,7 +42,7 @@ module RuboCop | |
| 42 42 | 
             
                      # 1. On CI
         | 
| 43 43 | 
             
                      # 2. When given RuboCop options that it doesn't make sense for
         | 
| 44 44 | 
             
                      # 3. For all formatters except specified in `INCLUDED_FORMATTERS'`
         | 
| 45 | 
            -
                      ENV | 
| 45 | 
            +
                      ENV.fetch('CI', nil) ||
         | 
| 46 46 | 
             
                        @options[:only] || @options[:debug] || @options[:list_target_files] ||
         | 
| 47 47 | 
             
                        @options[:out] || @options[:stdin] ||
         | 
| 48 48 | 
             
                        !INCLUDED_FORMATTERS.include?(current_formatter)
         | 
| @@ -10,13 +10,13 @@ module RuboCop | |
| 10 10 | 
             
                  #
         | 
| 11 11 | 
             
                  #   # bad
         | 
| 12 12 | 
             
                  #   Gem::Specification.new do |spec|
         | 
| 13 | 
            -
                  #      | 
| 13 | 
            +
                  #     spec.name = 'your_cool_gem_name'
         | 
| 14 14 | 
             
                  #     spec.date = Time.now.strftime('%Y-%m-%d')
         | 
| 15 15 | 
             
                  #   end
         | 
| 16 16 | 
             
                  #
         | 
| 17 17 | 
             
                  #   # good
         | 
| 18 18 | 
             
                  #   Gem::Specification.new do |spec|
         | 
| 19 | 
            -
                  #      | 
| 19 | 
            +
                  #     spec.name = 'your_cool_gem_name'
         | 
| 20 20 | 
             
                  #   end
         | 
| 21 21 | 
             
                  #
         | 
| 22 22 | 
             
                  class DateAssignment < Base
         | 
| @@ -119,18 +119,34 @@ module RuboCop | |
| 119 119 |  | 
| 120 120 | 
             
                    def on_case(case_node)
         | 
| 121 121 | 
             
                      return if case_node.single_line?
         | 
| 122 | 
            +
                      return if enforced_style_end? && end_and_last_conditional_same_line?(case_node)
         | 
| 122 123 |  | 
| 123 124 | 
             
                      case_node.each_when { |when_node| check_when(when_node, 'when') }
         | 
| 124 125 | 
             
                    end
         | 
| 125 126 |  | 
| 126 127 | 
             
                    def on_case_match(case_match_node)
         | 
| 127 128 | 
             
                      return if case_match_node.single_line?
         | 
| 129 | 
            +
                      return if enforced_style_end? && end_and_last_conditional_same_line?(case_match_node)
         | 
| 128 130 |  | 
| 129 131 | 
             
                      case_match_node.each_in_pattern { |in_pattern_node| check_when(in_pattern_node, 'in') }
         | 
| 130 132 | 
             
                    end
         | 
| 131 133 |  | 
| 132 134 | 
             
                    private
         | 
| 133 135 |  | 
| 136 | 
            +
                    def end_and_last_conditional_same_line?(node)
         | 
| 137 | 
            +
                      end_line = node.loc.end&.line
         | 
| 138 | 
            +
                      last_conditional_line = if node.loc.else
         | 
| 139 | 
            +
                                                node.loc.else.line
         | 
| 140 | 
            +
                                              else
         | 
| 141 | 
            +
                                                node.child_nodes.last.loc.begin&.line
         | 
| 142 | 
            +
                                              end
         | 
| 143 | 
            +
                      end_line && last_conditional_line && end_line == last_conditional_line
         | 
| 144 | 
            +
                    end
         | 
| 145 | 
            +
             | 
| 146 | 
            +
                    def enforced_style_end?
         | 
| 147 | 
            +
                      cop_config[style_parameter_name] == 'end'
         | 
| 148 | 
            +
                    end
         | 
| 149 | 
            +
             | 
| 134 150 | 
             
                    def check_when(when_node, branch_type)
         | 
| 135 151 | 
             
                      when_column = when_node.loc.keyword.column
         | 
| 136 152 | 
             
                      base_column = base_column(when_node.parent, style)
         | 
| @@ -24,7 +24,7 @@ module RuboCop | |
| 24 24 | 
             
                  #     end
         | 
| 25 25 | 
             
                  #   end
         | 
| 26 26 | 
             
                  #
         | 
| 27 | 
            -
                  # @example  | 
| 27 | 
            +
                  # @example AllowedPatterns: ['^\s*module']
         | 
| 28 28 | 
             
                  #   # bad
         | 
| 29 29 | 
             
                  #   module A
         | 
| 30 30 | 
             
                  #   class B
         | 
| @@ -46,7 +46,7 @@ module RuboCop | |
| 46 46 | 
             
                    include EndKeywordAlignment
         | 
| 47 47 | 
             
                    include Alignment
         | 
| 48 48 | 
             
                    include CheckAssignment
         | 
| 49 | 
            -
                    include  | 
| 49 | 
            +
                    include AllowedPattern
         | 
| 50 50 | 
             
                    include RangeHelp
         | 
| 51 51 | 
             
                    extend AutoCorrector
         | 
| 52 52 |  | 
| @@ -60,7 +60,7 @@ module RuboCop | |
| 60 60 | 
             
                  #   }
         | 
| 61 61 | 
             
                  class LineLength < Base
         | 
| 62 62 | 
             
                    include CheckLineBreakable
         | 
| 63 | 
            -
                    include  | 
| 63 | 
            +
                    include AllowedPattern
         | 
| 64 64 | 
             
                    include RangeHelp
         | 
| 65 65 | 
             
                    include LineLengthHelp
         | 
| 66 66 | 
             
                    extend AutoCorrector
         | 
| @@ -163,7 +163,7 @@ module RuboCop | |
| 163 163 |  | 
| 164 164 | 
             
                    def check_line(line, line_index)
         | 
| 165 165 | 
             
                      return if line_length(line) <= max
         | 
| 166 | 
            -
                      return if  | 
| 166 | 
            +
                      return if allowed_line?(line, line_index)
         | 
| 167 167 |  | 
| 168 168 | 
             
                      if ignore_cop_directives? && directive_on_source_line?(line_index)
         | 
| 169 169 | 
             
                        return check_directive_line(line, line_index)
         | 
| @@ -173,8 +173,8 @@ module RuboCop | |
| 173 173 | 
             
                      register_offense(excess_range(nil, line, line_index), line, line_index)
         | 
| 174 174 | 
             
                    end
         | 
| 175 175 |  | 
| 176 | 
            -
                    def  | 
| 177 | 
            -
                       | 
| 176 | 
            +
                    def allowed_line?(line, line_index)
         | 
| 177 | 
            +
                      matches_allowed_pattern?(line) ||
         | 
| 178 178 | 
             
                        shebang?(line, line_index) ||
         | 
| 179 179 | 
             
                        (heredocs && line_in_permitted_heredoc?(line_index.succ))
         | 
| 180 180 | 
             
                    end
         | 
| @@ -201,14 +201,31 @@ module RuboCop | |
| 201 201 | 
             
                    def semantic_alignment_node(node)
         | 
| 202 202 | 
             
                      return if argument_in_method_call(node, :with_parentheses)
         | 
| 203 203 |  | 
| 204 | 
            +
                      dot_right_above = get_dot_right_above(node)
         | 
| 205 | 
            +
                      return dot_right_above if dot_right_above
         | 
| 206 | 
            +
             | 
| 207 | 
            +
                      node = first_call_has_a_dot(node)
         | 
| 208 | 
            +
                      return if node.loc.dot.line != node.first_line
         | 
| 209 | 
            +
             | 
| 210 | 
            +
                      node
         | 
| 211 | 
            +
                    end
         | 
| 212 | 
            +
             | 
| 213 | 
            +
                    def get_dot_right_above(node)
         | 
| 214 | 
            +
                      node.each_ancestor.find do |a|
         | 
| 215 | 
            +
                        dot = a.loc.respond_to?(:dot) && a.loc.dot
         | 
| 216 | 
            +
                        next unless dot
         | 
| 217 | 
            +
             | 
| 218 | 
            +
                        dot.line == node.loc.dot.line - 1 && dot.column == node.loc.dot.column
         | 
| 219 | 
            +
                      end
         | 
| 220 | 
            +
                    end
         | 
| 221 | 
            +
             | 
| 222 | 
            +
                    def first_call_has_a_dot(node)
         | 
| 204 223 | 
             
                      # descend to root of method chain
         | 
| 205 224 | 
             
                      node = node.receiver while node.receiver
         | 
| 206 225 | 
             
                      # ascend to first call which has a dot
         | 
| 207 226 | 
             
                      node = node.parent
         | 
| 208 227 | 
             
                      node = node.parent until node.loc.respond_to?(:dot) && node.loc.dot
         | 
| 209 228 |  | 
| 210 | 
            -
                      return if node.loc.dot.line != node.first_line
         | 
| 211 | 
            -
             | 
| 212 229 | 
             
                      node
         | 
| 213 230 | 
             
                    end
         | 
| 214 231 |  | 
| @@ -5,6 +5,10 @@ module RuboCop | |
| 5 5 | 
             
                module Lint
         | 
| 6 6 | 
             
                  # This cop checks for duplicate `require`s and `require_relative`s.
         | 
| 7 7 | 
             
                  #
         | 
| 8 | 
            +
                  # @safety
         | 
| 9 | 
            +
                  #   This cop's autocorrection is unsafe because it may break the dependency order
         | 
| 10 | 
            +
                  #   of `require`.
         | 
| 11 | 
            +
                  #
         | 
| 8 12 | 
             
                  # @example
         | 
| 9 13 | 
             
                  #   # bad
         | 
| 10 14 | 
             
                  #   require 'foo'
         | 
| @@ -20,6 +24,9 @@ module RuboCop | |
| 20 24 | 
             
                  #   require_relative 'foo'
         | 
| 21 25 | 
             
                  #
         | 
| 22 26 | 
             
                  class DuplicateRequire < Base
         | 
| 27 | 
            +
                    include RangeHelp
         | 
| 28 | 
            +
                    extend AutoCorrector
         | 
| 29 | 
            +
             | 
| 23 30 | 
             
                    MSG = 'Duplicate `%<method>s` detected.'
         | 
| 24 31 | 
             
                    REQUIRE_METHODS = Set.new(%i[require require_relative]).freeze
         | 
| 25 32 | 
             
                    RESTRICT_ON_SEND = REQUIRE_METHODS
         | 
| @@ -39,7 +46,9 @@ module RuboCop | |
| 39 46 | 
             
                      return unless require_call?(node)
         | 
| 40 47 | 
             
                      return if @required[node.parent].add?("#{node.method_name}#{node.first_argument}")
         | 
| 41 48 |  | 
| 42 | 
            -
                      add_offense(node, message: format(MSG, method: node.method_name))
         | 
| 49 | 
            +
                      add_offense(node, message: format(MSG, method: node.method_name)) do |corrector|
         | 
| 50 | 
            +
                        corrector.remove(range_by_whole_lines(node.source_range, include_final_newline: true))
         | 
| 51 | 
            +
                      end
         | 
| 43 52 | 
             
                    end
         | 
| 44 53 | 
             
                  end
         | 
| 45 54 | 
             
                end
         | 
| @@ -11,7 +11,7 @@ module RuboCop | |
| 11 11 | 
             
                  #
         | 
| 12 12 | 
             
                  # NOTE: Block methods that are used with `Enumerable`s are considered to be loops.
         | 
| 13 13 | 
             
                  #
         | 
| 14 | 
            -
                  # ` | 
| 14 | 
            +
                  # `AllowedPatterns` can be used to match against the block receiver in order to allow
         | 
| 15 15 | 
             
                  # code that would otherwise be registered as an offense (eg. `times` used not in an
         | 
| 16 16 | 
             
                  # `Enumerable` context).
         | 
| 17 17 | 
             
                  #
         | 
| @@ -79,12 +79,12 @@ module RuboCop | |
| 79 79 | 
             
                  #   # bad
         | 
| 80 80 | 
             
                  #   2.times { raise ArgumentError }
         | 
| 81 81 | 
             
                  #
         | 
| 82 | 
            -
                  # @example  | 
| 82 | 
            +
                  # @example AllowedPatterns: [/(exactly|at_least|at_most)\(\d+\)\.times/] (default)
         | 
| 83 83 | 
             
                  #
         | 
| 84 84 | 
             
                  #   # good
         | 
| 85 85 | 
             
                  #   exactly(2).times { raise StandardError }
         | 
| 86 86 | 
             
                  class UnreachableLoop < Base
         | 
| 87 | 
            -
                    include  | 
| 87 | 
            +
                    include AllowedPattern
         | 
| 88 88 |  | 
| 89 89 | 
             
                    MSG = 'This loop will have at most one iteration.'
         | 
| 90 90 | 
             
                    CONTINUE_KEYWORDS = %i[next redo].freeze
         | 
| @@ -107,7 +107,7 @@ module RuboCop | |
| 107 107 | 
             
                      return false unless node.block_type?
         | 
| 108 108 |  | 
| 109 109 | 
             
                      send_node = node.send_node
         | 
| 110 | 
            -
                      return false if  | 
| 110 | 
            +
                      return false if matches_allowed_pattern?(send_node.source)
         | 
| 111 111 |  | 
| 112 112 | 
             
                      send_node.enumerable_method? || send_node.enumerator_method? || send_node.method?(:loop)
         | 
| 113 113 | 
             
                    end
         | 
| @@ -96,7 +96,7 @@ module RuboCop | |
| 96 96 | 
             
                      end
         | 
| 97 97 |  | 
| 98 98 | 
             
                      def compound_assignment(node)
         | 
| 99 | 
            -
                        # Methods setter  | 
| 99 | 
            +
                        # Methods setter cannot be detected for multiple assignments
         | 
| 100 100 | 
             
                        # and shorthand assigns, so we'll count them here instead
         | 
| 101 101 | 
             
                        children = node.masgn_type? ? node.children[0].children : node.children
         | 
| 102 102 |  | 
| @@ -30,8 +30,8 @@ module RuboCop | |
| 30 30 |  | 
| 31 31 | 
             
                          descendant_length = code_length(descendant)
         | 
| 32 32 | 
             
                          length = length - descendant_length + 1
         | 
| 33 | 
            -
                          # Subtract  | 
| 34 | 
            -
                          length -=  | 
| 33 | 
            +
                          # Subtract length of opening and closing brace if method argument omits hash braces.
         | 
| 34 | 
            +
                          length -= omit_length(descendant) if descendant.hash_type? && !descendant.braces?
         | 
| 35 35 | 
             
                        end
         | 
| 36 36 |  | 
| 37 37 | 
             
                        length
         | 
| @@ -153,6 +153,20 @@ module RuboCop | |
| 153 153 | 
             
                      def count_comments?
         | 
| 154 154 | 
             
                        @count_comments
         | 
| 155 155 | 
             
                      end
         | 
| 156 | 
            +
             | 
| 157 | 
            +
                      def omit_length(descendant)
         | 
| 158 | 
            +
                        parent = descendant.parent
         | 
| 159 | 
            +
                        return 0 if another_args?(parent)
         | 
| 160 | 
            +
             | 
| 161 | 
            +
                        [
         | 
| 162 | 
            +
                          parent.loc.begin.end_pos != descendant.loc.expression.begin_pos,
         | 
| 163 | 
            +
                          parent.loc.end.begin_pos != descendant.loc.expression.end_pos
         | 
| 164 | 
            +
                        ].count(true)
         | 
| 165 | 
            +
                      end
         | 
| 166 | 
            +
             | 
| 167 | 
            +
                      def another_args?(node)
         | 
| 168 | 
            +
                        node.call_type? && node.arguments.count > 1
         | 
| 169 | 
            +
                      end
         | 
| 156 170 | 
             
                    end
         | 
| 157 171 | 
             
                  end
         | 
| 158 172 | 
             
                end
         | 
| @@ -0,0 +1,40 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module RuboCop
         | 
| 4 | 
            +
              module Cop
         | 
| 5 | 
            +
                # This module encapsulates the ability to ignore certain lines when
         | 
| 6 | 
            +
                # parsing.
         | 
| 7 | 
            +
                module AllowedPattern
         | 
| 8 | 
            +
                  private
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                  def allowed_line?(line)
         | 
| 11 | 
            +
                    line = if line.respond_to?(:source_line)
         | 
| 12 | 
            +
                             line.source_line
         | 
| 13 | 
            +
                           elsif line.respond_to?(:node)
         | 
| 14 | 
            +
                             line.node.source_range.source_line
         | 
| 15 | 
            +
                           end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                    matches_allowed_pattern?(line)
         | 
| 18 | 
            +
                  end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                  # @deprecated Use allowed_line? instead
         | 
| 21 | 
            +
                  alias ignored_line? allowed_line?
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                  def matches_allowed_pattern?(line)
         | 
| 24 | 
            +
                    allowed_patterns.any? { |pattern| Regexp.new(pattern).match?(line) }
         | 
| 25 | 
            +
                  end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                  # @deprecated Use matches_allowed_pattern?? instead
         | 
| 28 | 
            +
                  alias matches_ignored_pattern? matches_allowed_pattern?
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                  def allowed_patterns
         | 
| 31 | 
            +
                    # Since there could be a pattern specified in the default config, merge the two
         | 
| 32 | 
            +
                    # arrays together.
         | 
| 33 | 
            +
                    Array(cop_config['AllowedPatterns']).concat(Array(cop_config['IgnoredPatterns']))
         | 
| 34 | 
            +
                  end
         | 
| 35 | 
            +
                end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                # @deprecated IgnoredPattern class has been replaced with AllowedPattern.
         | 
| 38 | 
            +
                IgnoredPattern = AllowedPattern
         | 
| 39 | 
            +
              end
         | 
| 40 | 
            +
            end
         | 
| @@ -46,17 +46,19 @@ module RuboCop | |
| 46 46 | 
             
                  # Returns the end line of a node, which might be a comment and not part of the AST
         | 
| 47 47 | 
             
                  # End line is considered either the line at which another node starts, or
         | 
| 48 48 | 
             
                  # the line at which the parent node ends.
         | 
| 49 | 
            +
                  # rubocop:disable Metrics/AbcSize
         | 
| 49 50 | 
             
                  def find_end_line(node)
         | 
| 50 51 | 
             
                    if node.if_type? && node.loc.else
         | 
| 51 52 | 
             
                      node.loc.else.line
         | 
| 52 53 | 
             
                    elsif (next_sibling = node.right_sibling)
         | 
| 53 54 | 
             
                      next_sibling.loc.line
         | 
| 54 55 | 
             
                    elsif (parent = node.parent)
         | 
| 55 | 
            -
                      parent.loc.end.line
         | 
| 56 | 
            +
                      parent.loc.end ? parent.loc.end.line : parent.loc.line
         | 
| 56 57 | 
             
                    else
         | 
| 57 58 | 
             
                      node.loc.end.line
         | 
| 58 59 | 
             
                    end
         | 
| 59 60 | 
             
                  end
         | 
| 61 | 
            +
                  # rubocop:enable Metrics/AbcSize
         | 
| 60 62 | 
             
                end
         | 
| 61 63 | 
             
              end
         | 
| 62 64 | 
             
            end
         | 
| @@ -6,10 +6,10 @@ module RuboCop | |
| 6 6 | 
             
                  # This cop makes sure that all methods use the configured style,
         | 
| 7 7 | 
             
                  # snake_case or camelCase, for their names.
         | 
| 8 8 | 
             
                  #
         | 
| 9 | 
            -
                  # This cop has ` | 
| 9 | 
            +
                  # This cop has `AllowedPatterns` configuration option.
         | 
| 10 10 | 
             
                  #
         | 
| 11 11 | 
             
                  #   Naming/MethodName:
         | 
| 12 | 
            -
                  #      | 
| 12 | 
            +
                  #     AllowedPatterns:
         | 
| 13 13 | 
             
                  #       - '\A\s*onSelectionBulkChange\s*'
         | 
| 14 14 | 
             
                  #       - '\A\s*onSelectionCleared\s*'
         | 
| 15 15 | 
             
                  #
         | 
| @@ -30,7 +30,7 @@ module RuboCop | |
| 30 30 | 
             
                  #   def fooBar; end
         | 
| 31 31 | 
             
                  class MethodName < Base
         | 
| 32 32 | 
             
                    include ConfigurableNaming
         | 
| 33 | 
            -
                    include  | 
| 33 | 
            +
                    include AllowedPattern
         | 
| 34 34 | 
             
                    include RangeHelp
         | 
| 35 35 |  | 
| 36 36 | 
             
                    MSG = 'Use %<style>s for method names.'
         | 
| @@ -46,14 +46,14 @@ module RuboCop | |
| 46 46 |  | 
| 47 47 | 
             
                      attrs.last.each do |name_item|
         | 
| 48 48 | 
             
                        name = attr_name(name_item)
         | 
| 49 | 
            -
                        next if !name ||  | 
| 49 | 
            +
                        next if !name || matches_allowed_pattern?(name)
         | 
| 50 50 |  | 
| 51 51 | 
             
                        check_name(node, name, range_position(node))
         | 
| 52 52 | 
             
                      end
         | 
| 53 53 | 
             
                    end
         | 
| 54 54 |  | 
| 55 55 | 
             
                    def on_def(node)
         | 
| 56 | 
            -
                      return if node.operator_method? ||  | 
| 56 | 
            +
                      return if node.operator_method? || matches_allowed_pattern?(node.method_name)
         | 
| 57 57 |  | 
| 58 58 | 
             
                      check_name(node, node.method_name, node.loc.name)
         | 
| 59 59 | 
             
                    end
         | 
    
        data/lib/rubocop/cop/offense.rb
    CHANGED