rubocop 1.72.2 → 1.74.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +3 -3
- data/config/default.yml +56 -15
- data/config/internal_affairs.yml +20 -0
- data/lib/rubocop/config_loader.rb +0 -1
- data/lib/rubocop/config_loader_resolver.rb +4 -3
- data/lib/rubocop/config_obsoletion/extracted_cop.rb +4 -3
- data/lib/rubocop/config_obsoletion.rb +1 -1
- data/lib/rubocop/config_validator.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/example_description.rb +3 -1
- data/lib/rubocop/cop/internal_affairs/node_type_group.rb +91 -0
- data/lib/rubocop/cop/internal_affairs.rb +1 -0
- data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +4 -4
- data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +26 -1
- data/lib/rubocop/cop/layout/line_length.rb +3 -3
- data/lib/rubocop/cop/lint/duplicate_methods.rb +0 -14
- data/lib/rubocop/cop/lint/empty_conditional_body.rb +14 -64
- data/lib/rubocop/cop/lint/erb_new_arguments.rb +0 -6
- data/lib/rubocop/cop/lint/float_comparison.rb +1 -6
- data/lib/rubocop/cop/lint/literal_as_condition.rb +103 -9
- data/lib/rubocop/cop/lint/mixed_case_range.rb +2 -2
- data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +2 -2
- data/lib/rubocop/cop/lint/redundant_require_statement.rb +0 -21
- data/lib/rubocop/cop/lint/redundant_type_conversion.rb +32 -5
- data/lib/rubocop/cop/lint/return_in_void_context.rb +4 -11
- data/lib/rubocop/cop/lint/shared_mutable_default.rb +12 -1
- data/lib/rubocop/cop/lint/useless_constant_scoping.rb +2 -11
- data/lib/rubocop/cop/lint/void.rb +6 -0
- data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +1 -1
- data/lib/rubocop/cop/mixin/hash_subset.rb +19 -4
- data/lib/rubocop/cop/mixin/range_help.rb +12 -0
- data/lib/rubocop/cop/mixin/target_ruby_version.rb +1 -1
- data/lib/rubocop/cop/mixin/trailing_comma.rb +12 -0
- data/lib/rubocop/cop/naming/variable_name.rb +64 -6
- data/lib/rubocop/cop/style/accessor_grouping.rb +19 -5
- data/lib/rubocop/cop/style/class_and_module_children.rb +29 -7
- data/lib/rubocop/cop/style/commented_keyword.rb +10 -3
- data/lib/rubocop/cop/style/comparable_between.rb +75 -0
- data/lib/rubocop/cop/style/double_negation.rb +1 -1
- data/lib/rubocop/cop/style/endless_method.rb +163 -18
- data/lib/rubocop/cop/style/expand_path_arguments.rb +2 -7
- data/lib/rubocop/cop/style/exponential_notation.rb +2 -2
- data/lib/rubocop/cop/style/format_string_token.rb +38 -11
- data/lib/rubocop/cop/style/if_unless_modifier.rb +2 -2
- data/lib/rubocop/cop/style/inverse_methods.rb +8 -5
- data/lib/rubocop/cop/style/keyword_parameters_order.rb +13 -7
- data/lib/rubocop/cop/style/line_end_concatenation.rb +10 -4
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +3 -3
- data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +1 -1
- data/lib/rubocop/cop/style/multiline_block_chain.rb +1 -1
- data/lib/rubocop/cop/style/multiline_method_signature.rb +1 -9
- data/lib/rubocop/cop/style/redundant_condition.rb +45 -0
- data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +14 -4
- data/lib/rubocop/cop/style/redundant_format.rb +23 -11
- data/lib/rubocop/cop/style/redundant_freeze.rb +1 -1
- data/lib/rubocop/cop/style/redundant_self_assignment.rb +1 -1
- data/lib/rubocop/cop/style/rescue_modifier.rb +3 -0
- data/lib/rubocop/cop/style/single_line_methods.rb +3 -3
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +0 -6
- data/lib/rubocop/cop/style/string_concatenation.rb +1 -1
- data/lib/rubocop/cop/style/trailing_comma_in_array_literal.rb +47 -6
- data/lib/rubocop/cop/style/trailing_comma_in_hash_literal.rb +48 -6
- data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
- data/lib/rubocop/cop/utils/format_string.rb +5 -2
- data/lib/rubocop/cops_documentation_generator.rb +12 -1
- data/lib/rubocop/directive_comment.rb +1 -1
- data/lib/rubocop/ext/regexp_node.rb +0 -1
- data/lib/rubocop/plugin/load_error.rb +1 -1
- data/lib/rubocop/plugin.rb +9 -2
- data/lib/rubocop/rspec/shared_contexts.rb +15 -0
- data/lib/rubocop/rspec/support.rb +1 -0
- data/lib/rubocop/version.rb +1 -1
- data/lib/rubocop.rb +1 -1
- metadata +6 -5
- data/lib/rubocop/cop/utils/regexp_ranges.rb +0 -113
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 440bee0e28f294bab2eba4c11e9c681342917c69ad4c00e36eceb88743767c29
         | 
| 4 | 
            +
              data.tar.gz: 68e9e209a22e891a38b677f97344d2d10e9a8913dd999751472f301deed43b31
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 70db27a5b7a0e00696672a5b4fcd4e3bf35aa40c85ef65ccb630914ab110a5e5b657927aa1b1c8637be76b7041a90e2ad3c4ed188110266c048d0c4d6a4be0b4
         | 
| 7 | 
            +
              data.tar.gz: e5599d30a4f776d85d202acad2ac03c7e4568e64a1c4038cb87b8ee3372b2428882924a91ea49853c98cf0614280d002918363eef41fe0990dc8b1895d8e9776
         | 
    
        data/README.md
    CHANGED
    
    | @@ -52,7 +52,7 @@ To prevent an unwanted RuboCop update you might want to use a conservative versi | |
| 52 52 | 
             
            in your `Gemfile`:
         | 
| 53 53 |  | 
| 54 54 | 
             
            ```rb
         | 
| 55 | 
            -
            gem 'rubocop', '~> 1. | 
| 55 | 
            +
            gem 'rubocop', '~> 1.74', require: false
         | 
| 56 56 | 
             
            ```
         | 
| 57 57 |  | 
| 58 58 | 
             
            See [our versioning policy](https://docs.rubocop.org/rubocop/versioning.html) for further details.
         | 
| @@ -241,9 +241,9 @@ Become a sponsor and get your logo on our README on GitHub with a link to your s | |
| 241 241 | 
             
            <a href="https://opencollective.com/rubocop/organization/28/website" target="_blank"><img src="https://opencollective.com/rubocop/organization/28/avatar.svg"></a>
         | 
| 242 242 | 
             
            <a href="https://opencollective.com/rubocop/organization/29/website" target="_blank"><img src="https://opencollective.com/rubocop/organization/29/avatar.svg"></a>
         | 
| 243 243 |  | 
| 244 | 
            -
            ##  | 
| 244 | 
            +
            ## Release Notes
         | 
| 245 245 |  | 
| 246 | 
            -
            RuboCop's  | 
| 246 | 
            +
            RuboCop's release notes are available [here](https://github.com/rubocop/rubocop/releases).
         | 
| 247 247 |  | 
| 248 248 | 
             
            ## Copyright
         | 
| 249 249 |  | 
    
        data/config/default.yml
    CHANGED
    
    | @@ -1887,10 +1887,9 @@ Lint/EmptyConditionalBody: | |
| 1887 1887 | 
             
              Description: 'Checks for the presence of `if`, `elsif` and `unless` branches without a body.'
         | 
| 1888 1888 | 
             
              Enabled: true
         | 
| 1889 1889 | 
             
              AutoCorrect: contextual
         | 
| 1890 | 
            -
              SafeAutoCorrect: false
         | 
| 1891 1890 | 
             
              AllowComments: true
         | 
| 1892 1891 | 
             
              VersionAdded: '0.89'
         | 
| 1893 | 
            -
              VersionChanged: '1. | 
| 1892 | 
            +
              VersionChanged: '1.73'
         | 
| 1894 1893 |  | 
| 1895 1894 | 
             
            Lint/EmptyEnsure:
         | 
| 1896 1895 | 
             
              Description: 'Checks for empty ensure block.'
         | 
| @@ -2046,6 +2045,7 @@ Lint/LambdaWithoutLiteralBlock: | |
| 2046 2045 | 
             
            Lint/LiteralAsCondition:
         | 
| 2047 2046 | 
             
              Description: 'Checks of literals used in conditions.'
         | 
| 2048 2047 | 
             
              Enabled: true
         | 
| 2048 | 
            +
              AutoCorrect: contextual
         | 
| 2049 2049 | 
             
              VersionAdded: '0.51'
         | 
| 2050 2050 |  | 
| 2051 2051 | 
             
            Lint/LiteralAssignmentInCondition:
         | 
| @@ -2259,9 +2259,8 @@ Lint/RedundantRegexpQuantifiers: | |
| 2259 2259 | 
             
            Lint/RedundantRequireStatement:
         | 
| 2260 2260 | 
             
              Description: 'Checks for unnecessary `require` statement.'
         | 
| 2261 2261 | 
             
              Enabled: true
         | 
| 2262 | 
            -
              SafeAutoCorrect: false
         | 
| 2263 2262 | 
             
              VersionAdded: '0.76'
         | 
| 2264 | 
            -
              VersionChanged: '1. | 
| 2263 | 
            +
              VersionChanged: '1.73'
         | 
| 2265 2264 |  | 
| 2266 2265 | 
             
            Lint/RedundantSafeNavigation:
         | 
| 2267 2266 | 
             
              Description: 'Checks for redundant safe navigation calls.'
         | 
| @@ -3081,13 +3080,15 @@ Naming/VariableName: | |
| 3081 3080 | 
             
              StyleGuide: '#snake-case-symbols-methods-vars'
         | 
| 3082 3081 | 
             
              Enabled: true
         | 
| 3083 3082 | 
             
              VersionAdded: '0.50'
         | 
| 3084 | 
            -
              VersionChanged: '1. | 
| 3083 | 
            +
              VersionChanged: '1.73'
         | 
| 3085 3084 | 
             
              EnforcedStyle: snake_case
         | 
| 3086 3085 | 
             
              SupportedStyles:
         | 
| 3087 3086 | 
             
                - snake_case
         | 
| 3088 3087 | 
             
                - camelCase
         | 
| 3089 3088 | 
             
              AllowedIdentifiers: []
         | 
| 3090 3089 | 
             
              AllowedPatterns: []
         | 
| 3090 | 
            +
              ForbiddenIdentifiers: []
         | 
| 3091 | 
            +
              ForbiddenPatterns: []
         | 
| 3091 3092 |  | 
| 3092 3093 | 
             
            Naming/VariableNumber:
         | 
| 3093 3094 | 
             
              Description: 'Use the configured style when numbering symbols, methods and variables.'
         | 
| @@ -3103,6 +3104,8 @@ Naming/VariableNumber: | |
| 3103 3104 | 
             
              CheckMethodNames: true
         | 
| 3104 3105 | 
             
              CheckSymbols: true
         | 
| 3105 3106 | 
             
              AllowedIdentifiers:
         | 
| 3107 | 
            +
                - TLS1_1       # OpenSSL::SSL::TLS1_1_VERSION
         | 
| 3108 | 
            +
                - TLS1_2       # OpenSSL::SSL::TLS1_2_VERSION
         | 
| 3106 3109 | 
             
                - capture3     # Open3.capture3
         | 
| 3107 3110 | 
             
                - iso8601      # Time#iso8601
         | 
| 3108 3111 | 
             
                - rfc1123_date # CGI.rfc1123_date
         | 
| @@ -3498,6 +3501,7 @@ Style/ClassAndModuleChildren: | |
| 3498 3501 | 
             
              SafeAutoCorrect: false
         | 
| 3499 3502 | 
             
              Enabled: true
         | 
| 3500 3503 | 
             
              VersionAdded: '0.19'
         | 
| 3504 | 
            +
              VersionChanged: '1.74'
         | 
| 3501 3505 | 
             
              #
         | 
| 3502 3506 | 
             
              # Basically there are two different styles:
         | 
| 3503 3507 | 
             
              #
         | 
| @@ -3513,7 +3517,21 @@ Style/ClassAndModuleChildren: | |
| 3513 3517 | 
             
              #
         | 
| 3514 3518 | 
             
              # The compact style is only forced, for classes or modules with one child.
         | 
| 3515 3519 | 
             
              EnforcedStyle: nested
         | 
| 3516 | 
            -
              SupportedStyles:
         | 
| 3520 | 
            +
              SupportedStyles: &supported_styles
         | 
| 3521 | 
            +
                - nested
         | 
| 3522 | 
            +
                - compact
         | 
| 3523 | 
            +
              # Configure classes separately, if desired. If not set, or set to `nil`,
         | 
| 3524 | 
            +
              # the `EnforcedStyle` value will be used.
         | 
| 3525 | 
            +
              EnforcedStyleForClasses: ~
         | 
| 3526 | 
            +
              SupportedStylesForClasses:
         | 
| 3527 | 
            +
                - ~
         | 
| 3528 | 
            +
                - nested
         | 
| 3529 | 
            +
                - compact
         | 
| 3530 | 
            +
              # Configure modules separately, if desired. If not set, or set to `nil`,
         | 
| 3531 | 
            +
              # the `EnforcedStyle` value will be used.
         | 
| 3532 | 
            +
              EnforcedStyleForModules: ~
         | 
| 3533 | 
            +
              SupportedStylesForModules:
         | 
| 3534 | 
            +
                - ~
         | 
| 3517 3535 | 
             
                - nested
         | 
| 3518 3536 | 
             
                - compact
         | 
| 3519 3537 |  | 
| @@ -3666,6 +3684,12 @@ Style/CommentedKeyword: | |
| 3666 3684 | 
             
              VersionAdded: '0.51'
         | 
| 3667 3685 | 
             
              VersionChanged: '1.19'
         | 
| 3668 3686 |  | 
| 3687 | 
            +
            Style/ComparableBetween:
         | 
| 3688 | 
            +
              Description: 'Enforces the use of `Comparable#between?` instead of logical comparison.'
         | 
| 3689 | 
            +
              Enabled: pending
         | 
| 3690 | 
            +
              VersionAdded: '1.74'
         | 
| 3691 | 
            +
              StyleGuide: '#ranges-or-between'
         | 
| 3692 | 
            +
             | 
| 3669 3693 | 
             
            Style/ComparableClamp:
         | 
| 3670 3694 | 
             
              Description: 'Enforces the use of `Comparable#clamp` instead of comparison by minimum and maximum.'
         | 
| 3671 3695 | 
             
              Enabled: pending
         | 
| @@ -3922,6 +3946,8 @@ Style/EndlessMethod: | |
| 3922 3946 | 
             
                - allow_single_line
         | 
| 3923 3947 | 
             
                - allow_always
         | 
| 3924 3948 | 
             
                - disallow
         | 
| 3949 | 
            +
                - require_single_line
         | 
| 3950 | 
            +
                - require_always
         | 
| 3925 3951 |  | 
| 3926 3952 | 
             
            Style/EnvHome:
         | 
| 3927 3953 | 
             
              Description: "Checks for consistent usage of `ENV['HOME']`."
         | 
| @@ -4066,8 +4092,14 @@ Style/FormatStringToken: | |
| 4066 4092 | 
             
              # style token in a format string to be allowed when enforced style is not
         | 
| 4067 4093 | 
             
              # `unannotated`.
         | 
| 4068 4094 | 
             
              MaxUnannotatedPlaceholdersAllowed: 1
         | 
| 4095 | 
            +
              # The mode the cop operates in. Two values are allowed:
         | 
| 4096 | 
            +
              # * aggressive (default): all strings are considered
         | 
| 4097 | 
            +
              # * conservative:
         | 
| 4098 | 
            +
              #     only register offenses for strings given to `printf`, `sprintf`,
         | 
| 4099 | 
            +
              #     format` and `%` methods. Other strings are not considered.
         | 
| 4100 | 
            +
              Mode: aggressive
         | 
| 4069 4101 | 
             
              VersionAdded: '0.49'
         | 
| 4070 | 
            -
              VersionChanged: '1. | 
| 4102 | 
            +
              VersionChanged: '1.74'
         | 
| 4071 4103 | 
             
              AllowedMethods: []
         | 
| 4072 4104 | 
             
              AllowedPatterns: []
         | 
| 4073 4105 |  | 
| @@ -5104,6 +5136,9 @@ Style/RedundantCondition: | |
| 5104 5136 | 
             
              Description: 'Checks for unnecessary conditional expressions.'
         | 
| 5105 5137 | 
             
              Enabled: true
         | 
| 5106 5138 | 
             
              VersionAdded: '0.76'
         | 
| 5139 | 
            +
              VersionChanged: '1.73'
         | 
| 5140 | 
            +
              AllowedMethods:
         | 
| 5141 | 
            +
                - nonzero?
         | 
| 5107 5142 |  | 
| 5108 5143 | 
             
            Style/RedundantConditional:
         | 
| 5109 5144 | 
             
              Description: "Don't return true/false from a conditional."
         | 
| @@ -5701,14 +5736,17 @@ Style/TrailingCommaInArrayLiteral: | |
| 5701 5736 | 
             
              StyleGuide: '#no-trailing-array-commas'
         | 
| 5702 5737 | 
             
              Enabled: true
         | 
| 5703 5738 | 
             
              VersionAdded: '0.53'
         | 
| 5704 | 
            -
              # If `comma`, the cop requires a comma after the last item in an array,
         | 
| 5705 | 
            -
              #  | 
| 5706 | 
            -
              # If `consistent_comma`, the cop requires a comma after the last item of all
         | 
| 5707 | 
            -
              #  | 
| 5739 | 
            +
              # If `comma`, the cop requires a comma after the last item in an array, but only when each item is
         | 
| 5740 | 
            +
              # on its own line.
         | 
| 5741 | 
            +
              # If `consistent_comma`, the cop requires a comma after the last item of all non-empty, multiline
         | 
| 5742 | 
            +
              # array literals.
         | 
| 5743 | 
            +
              # If `diff_comma`, the cop requires a comma after the last item of all non-empty, multiline array
         | 
| 5744 | 
            +
              # literals, but only when that last item immediately precedes a newline.
         | 
| 5708 5745 | 
             
              EnforcedStyleForMultiline: no_comma
         | 
| 5709 5746 | 
             
              SupportedStylesForMultiline:
         | 
| 5710 5747 | 
             
                - comma
         | 
| 5711 5748 | 
             
                - consistent_comma
         | 
| 5749 | 
            +
                - diff_comma
         | 
| 5712 5750 | 
             
                - no_comma
         | 
| 5713 5751 |  | 
| 5714 5752 | 
             
            Style/TrailingCommaInBlockArgs:
         | 
| @@ -5720,14 +5758,17 @@ Style/TrailingCommaInBlockArgs: | |
| 5720 5758 | 
             
            Style/TrailingCommaInHashLiteral:
         | 
| 5721 5759 | 
             
              Description: 'Checks for trailing comma in hash literals.'
         | 
| 5722 5760 | 
             
              Enabled: true
         | 
| 5723 | 
            -
              # If `comma`, the cop requires a comma after the last item in a hash,
         | 
| 5724 | 
            -
              #  | 
| 5725 | 
            -
              # If `consistent_comma`, the cop requires a comma after the last item of all
         | 
| 5726 | 
            -
              #  | 
| 5761 | 
            +
              # If `comma`, the cop requires a comma after the last item in a hash, but only when each item is
         | 
| 5762 | 
            +
              # on its own line.
         | 
| 5763 | 
            +
              # If `consistent_comma`, the cop requires a comma after the last item of all non-empty, multiline
         | 
| 5764 | 
            +
              # hash literals.
         | 
| 5765 | 
            +
              # If `diff_comma`, the cop requires a comma after the last item of all non-empty, multiline hash
         | 
| 5766 | 
            +
              # literals, but only when that last item immediately precedes a newline.
         | 
| 5727 5767 | 
             
              EnforcedStyleForMultiline: no_comma
         | 
| 5728 5768 | 
             
              SupportedStylesForMultiline:
         | 
| 5729 5769 | 
             
                - comma
         | 
| 5730 5770 | 
             
                - consistent_comma
         | 
| 5771 | 
            +
                - diff_comma
         | 
| 5731 5772 | 
             
                - no_comma
         | 
| 5732 5773 | 
             
              VersionAdded: '0.53'
         | 
| 5733 5774 |  | 
    
        data/config/internal_affairs.yml
    CHANGED
    
    | @@ -6,6 +6,26 @@ InternalAffairs/CopDescription: | |
| 6 6 | 
             
              Include:
         | 
| 7 7 | 
             
                - 'lib/rubocop/cop/**/*.rb'
         | 
| 8 8 |  | 
| 9 | 
            +
            InternalAffairs/ExampleHeredocDelimiter:
         | 
| 10 | 
            +
              Include:
         | 
| 11 | 
            +
                - 'spec/rubocop/cop/**/*.rb'
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            InternalAffairs/ExampleDescription:
         | 
| 14 | 
            +
              Include:
         | 
| 15 | 
            +
                - 'spec/rubocop/cop/**/*.rb'
         | 
| 16 | 
            +
             | 
| 17 | 
            +
            InternalAffairs/NodeTypeGroup:
         | 
| 18 | 
            +
              Include:
         | 
| 19 | 
            +
                - 'lib/rubocop/cop/**/*.rb'
         | 
| 20 | 
            +
             | 
| 21 | 
            +
            InternalAffairs/OnSendWithoutOnCSend:
         | 
| 22 | 
            +
              Include:
         | 
| 23 | 
            +
                - 'lib/rubocop/cop/**/*.rb'
         | 
| 24 | 
            +
             | 
| 25 | 
            +
            InternalAffairs/UndefinedConfig:
         | 
| 26 | 
            +
              Include:
         | 
| 27 | 
            +
                - 'lib/rubocop/cop/**/*.rb'
         | 
| 28 | 
            +
             | 
| 9 29 | 
             
            InternalAffairs/UselessMessageAssertion:
         | 
| 10 30 | 
             
              Include:
         | 
| 11 31 | 
             
                - '**/*_spec.rb'
         | 
| @@ -63,7 +63,6 @@ module RuboCop | |
| 63 63 | 
             
                    loaded_features = resolver.resolve_requires(path, hash)
         | 
| 64 64 | 
             
                    add_loaded_features(loaded_features)
         | 
| 65 65 |  | 
| 66 | 
            -
                    resolver.override_department_setting_for_cops({}, hash)
         | 
| 67 66 | 
             
                    resolver.resolve_inheritance_from_gems(hash)
         | 
| 68 67 | 
             
                    resolver.resolve_inheritance(path, hash, file, debug?)
         | 
| 69 68 | 
             
                    hash.delete('inherit_from')
         | 
| @@ -9,7 +9,8 @@ module RuboCop | |
| 9 9 | 
             
              # @api private
         | 
| 10 10 | 
             
              class ConfigLoaderResolver # rubocop:disable Metrics/ClassLength
         | 
| 11 11 | 
             
                def resolve_plugins(rubocop_config, plugins)
         | 
| 12 | 
            -
                   | 
| 12 | 
            +
                  plugins = Array(plugins) - ConfigLoader.loaded_plugins.map { |plugin| plugin.about.name }
         | 
| 13 | 
            +
                  return if plugins.empty?
         | 
| 13 14 |  | 
| 14 15 | 
             
                  Plugin.integrate_plugins(rubocop_config, plugins)
         | 
| 15 16 | 
             
                end
         | 
| @@ -123,7 +124,7 @@ module RuboCop | |
| 123 124 | 
             
                    elsif merge_hashes?(base_hash, derived_hash, key)
         | 
| 124 125 | 
             
                      result[key] = merge(base_hash[key], derived_hash[key], **opts)
         | 
| 125 126 | 
             
                    elsif should_union?(derived_hash, base_hash, opts[:inherit_mode], key)
         | 
| 126 | 
            -
                      result[key] = base_hash[key] | derived_hash[key]
         | 
| 127 | 
            +
                      result[key] = Array(base_hash[key]) | Array(derived_hash[key])
         | 
| 127 128 | 
             
                    elsif opts[:debug]
         | 
| 128 129 | 
             
                      warn_on_duplicate_setting(base_hash, derived_hash, key, **opts)
         | 
| 129 130 | 
             
                    end
         | 
| @@ -205,7 +206,7 @@ module RuboCop | |
| 205 206 | 
             
                end
         | 
| 206 207 |  | 
| 207 208 | 
             
                def should_union?(derived_hash, base_hash, root_mode, key)
         | 
| 208 | 
            -
                  return false unless base_hash[key].is_a?(Array)
         | 
| 209 | 
            +
                  return false unless base_hash[key].is_a?(Array) || derived_hash[key].is_a?(Array)
         | 
| 209 210 |  | 
| 210 211 | 
             
                  derived_mode = derived_hash['inherit_mode']
         | 
| 211 212 | 
             
                  return false if should_override?(derived_mode, key)
         | 
| @@ -15,7 +15,7 @@ module RuboCop | |
| 15 15 | 
             
                  end
         | 
| 16 16 |  | 
| 17 17 | 
             
                  def violated?
         | 
| 18 | 
            -
                    return false if  | 
| 18 | 
            +
                    return false if plugin_loaded?
         | 
| 19 19 |  | 
| 20 20 | 
             
                    affected_cops.any?
         | 
| 21 21 | 
             
                  end
         | 
| @@ -38,8 +38,9 @@ module RuboCop | |
| 38 38 | 
             
                    end
         | 
| 39 39 | 
             
                  end
         | 
| 40 40 |  | 
| 41 | 
            -
                  def  | 
| 42 | 
            -
                     | 
| 41 | 
            +
                  def plugin_loaded?
         | 
| 42 | 
            +
                    # Plugins loaded via `require` are included in `loaded_features`.
         | 
| 43 | 
            +
                    config.loaded_plugins.include?(gem) || config.loaded_features.include?(gem)
         | 
| 43 44 | 
             
                  end
         | 
| 44 45 | 
             
                end
         | 
| 45 46 | 
             
              end
         | 
| @@ -50,7 +50,7 @@ module RuboCop | |
| 50 50 | 
             
                # Default rules for obsoletions are in config/obsoletion.yml
         | 
| 51 51 | 
             
                # Additional rules files can be added with `RuboCop::ConfigObsoletion.files << filename`
         | 
| 52 52 | 
             
                def load_rules # rubocop:disable Metrics/AbcSize
         | 
| 53 | 
            -
                  rules = LOAD_RULES_CACHE[self.class.files] ||=
         | 
| 53 | 
            +
                  rules = LOAD_RULES_CACHE[self.class.files.hash] ||=
         | 
| 54 54 | 
             
                    self.class.files.each_with_object({}) do |filename, hash|
         | 
| 55 55 | 
             
                      hash.merge!(YAML.safe_load(File.read(filename)) || {}) do |_key, first, second|
         | 
| 56 56 | 
             
                        case first
         | 
| @@ -9,7 +9,7 @@ module RuboCop | |
| 9 9 |  | 
| 10 10 | 
             
                # @api private
         | 
| 11 11 | 
             
                COMMON_PARAMS = %w[Exclude Include Severity inherit_mode AutoCorrect StyleGuide Details
         | 
| 12 | 
            -
                                   Enabled].freeze
         | 
| 12 | 
            +
                                   Enabled Reference].freeze
         | 
| 13 13 | 
             
                # @api private
         | 
| 14 14 | 
             
                INTERNAL_PARAMS = %w[Description StyleGuide
         | 
| 15 15 | 
             
                                     VersionAdded VersionChanged VersionRemoved
         | 
| @@ -50,10 +50,12 @@ module RuboCop | |
| 50 50 | 
             
                    }.freeze
         | 
| 51 51 |  | 
| 52 52 | 
             
                    EXPECT_NO_CORRECTIONS_DESCRIPTION_MAPPING = {
         | 
| 53 | 
            -
                      /\A(auto[- ]?)? | 
| 53 | 
            +
                      /\A(auto[- ]?)?corrects?/ => 'does not correct',
         | 
| 54 | 
            +
                      /\band (auto[- ]?)?corrects/ => 'but does not correct'
         | 
| 54 55 | 
             
                    }.freeze
         | 
| 55 56 |  | 
| 56 57 | 
             
                    EXPECT_CORRECTION_DESCRIPTION_MAPPING = {
         | 
| 58 | 
            +
                      /\bbut (does not|doesn't) (auto[- ]?)?correct/ => 'and autocorrects',
         | 
| 57 59 | 
             
                      /\b(does not|doesn't) (auto[- ]?)?correct/ => 'autocorrects'
         | 
| 58 60 | 
             
                    }.freeze
         | 
| 59 61 |  | 
| @@ -0,0 +1,91 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module RuboCop
         | 
| 4 | 
            +
              module Cop
         | 
| 5 | 
            +
                module InternalAffairs
         | 
| 6 | 
            +
                  # Checks that node types are checked against their group when all types of a
         | 
| 7 | 
            +
                  # group are checked.
         | 
| 8 | 
            +
                  #
         | 
| 9 | 
            +
                  # @example
         | 
| 10 | 
            +
                  #   # bad
         | 
| 11 | 
            +
                  #   node.type?(:irange, :erange)
         | 
| 12 | 
            +
                  #
         | 
| 13 | 
            +
                  #   # good
         | 
| 14 | 
            +
                  #   node.range_type?
         | 
| 15 | 
            +
                  #
         | 
| 16 | 
            +
                  #   # bad
         | 
| 17 | 
            +
                  #   node.type?(:irange, :erange, :send, :csend)
         | 
| 18 | 
            +
                  #
         | 
| 19 | 
            +
                  #   # good
         | 
| 20 | 
            +
                  #   node.type?(:range, :call)
         | 
| 21 | 
            +
                  #
         | 
| 22 | 
            +
                  class NodeTypeGroup < Base
         | 
| 23 | 
            +
                    extend AutoCorrector
         | 
| 24 | 
            +
                    include RangeHelp
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                    MSG = 'Use `:%<group>s` instead of individually listing group types.'
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                    RESTRICT_ON_SEND = %i[type? each_ancestor each_child_node each_descendant each_node].freeze
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                    def on_send(node)
         | 
| 31 | 
            +
                      return unless node.receiver
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                      symbol_args = node.arguments.select(&:sym_type?)
         | 
| 34 | 
            +
                      return if symbol_args.none?
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                      NodePatternGroups::NODE_GROUPS.each do |group_name, group_types|
         | 
| 37 | 
            +
                        next unless group_satisfied?(group_types, symbol_args)
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                        offense_range = arguments_range(node)
         | 
| 40 | 
            +
                        add_offense(offense_range, message: format(MSG, group: group_name)) do |corrector|
         | 
| 41 | 
            +
                          autocorrect(corrector, node, symbol_args, group_name, group_types)
         | 
| 42 | 
            +
                        end
         | 
| 43 | 
            +
                      end
         | 
| 44 | 
            +
                    end
         | 
| 45 | 
            +
                    alias on_csend on_send
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                    private
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                    def arguments_range(node)
         | 
| 50 | 
            +
                      range_between(
         | 
| 51 | 
            +
                        node.first_argument.source_range.begin_pos,
         | 
| 52 | 
            +
                        node.last_argument.source_range.end_pos
         | 
| 53 | 
            +
                      )
         | 
| 54 | 
            +
                    end
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                    def group_satisfied?(group_types, symbol_args)
         | 
| 57 | 
            +
                      group_types.all? { |type| symbol_args.any? { |arg| arg.value == type } }
         | 
| 58 | 
            +
                    end
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                    def autocorrect(corrector, node, symbol_args, group_name, group_types)
         | 
| 61 | 
            +
                      if node.method?(:type?) && node.arguments.count == group_types.count
         | 
| 62 | 
            +
                        autocorrect_to_explicit_predicate(corrector, node, group_name)
         | 
| 63 | 
            +
                      else
         | 
| 64 | 
            +
                        autocorrect_keep_method(corrector, symbol_args, group_name, group_types)
         | 
| 65 | 
            +
                      end
         | 
| 66 | 
            +
                    end
         | 
| 67 | 
            +
             | 
| 68 | 
            +
                    def autocorrect_to_explicit_predicate(corrector, node, group_name)
         | 
| 69 | 
            +
                      corrector.replace(node.selector, "#{group_name}_type?")
         | 
| 70 | 
            +
                      corrector.remove(arguments_range(node))
         | 
| 71 | 
            +
                    end
         | 
| 72 | 
            +
             | 
| 73 | 
            +
                    def autocorrect_keep_method(corrector, symbol_args, group_name, group_types)
         | 
| 74 | 
            +
                      first_replaced = false
         | 
| 75 | 
            +
                      symbol_args.each do |arg|
         | 
| 76 | 
            +
                        next unless group_types.include?(arg.value)
         | 
| 77 | 
            +
             | 
| 78 | 
            +
                        if first_replaced
         | 
| 79 | 
            +
                          range = range_with_surrounding_space(arg.source_range)
         | 
| 80 | 
            +
                          range = range_with_surrounding_comma(range, :left)
         | 
| 81 | 
            +
                          corrector.remove(range)
         | 
| 82 | 
            +
                        else
         | 
| 83 | 
            +
                          first_replaced = true
         | 
| 84 | 
            +
                          corrector.replace(arg, ":#{group_name}")
         | 
| 85 | 
            +
                        end
         | 
| 86 | 
            +
                      end
         | 
| 87 | 
            +
                    end
         | 
| 88 | 
            +
                  end
         | 
| 89 | 
            +
                end
         | 
| 90 | 
            +
              end
         | 
| 91 | 
            +
            end
         | 
| @@ -17,6 +17,7 @@ require_relative 'internal_affairs/node_destructuring' | |
| 17 17 | 
             
            require_relative 'internal_affairs/node_first_or_last_argument'
         | 
| 18 18 | 
             
            require_relative 'internal_affairs/node_matcher_directive'
         | 
| 19 19 | 
             
            require_relative 'internal_affairs/node_pattern_groups'
         | 
| 20 | 
            +
            require_relative 'internal_affairs/node_type_group'
         | 
| 20 21 | 
             
            require_relative 'internal_affairs/node_type_multiple_predicates'
         | 
| 21 22 | 
             
            require_relative 'internal_affairs/node_type_predicate'
         | 
| 22 23 | 
             
            require_relative 'internal_affairs/numblock_handler'
         | 
| @@ -155,10 +155,10 @@ module RuboCop | |
| 155 155 | 
             
                    end
         | 
| 156 156 |  | 
| 157 157 | 
             
                    def all_elements_aligned?(elements)
         | 
| 158 | 
            -
                      elements. | 
| 159 | 
            -
                         | 
| 160 | 
            -
             | 
| 161 | 
            -
                         | 
| 158 | 
            +
                      if elements.first.hash_type?
         | 
| 159 | 
            +
                        elements.first.each_child_node.map { |child| child.loc.column }
         | 
| 160 | 
            +
                      else
         | 
| 161 | 
            +
                        elements.flat_map do |e|
         | 
| 162 162 | 
             
                          e.loc.column
         | 
| 163 163 | 
             
                        end
         | 
| 164 164 | 
             
                      end.uniq.count == 1
         | 
| @@ -93,7 +93,7 @@ module RuboCop | |
| 93 93 | 
             
                      add_offense(node, message: message) do |corrector|
         | 
| 94 94 | 
             
                        line = range_by_whole_lines(node.source_range)
         | 
| 95 95 |  | 
| 96 | 
            -
                        corrector.insert_before(line, "\n")  | 
| 96 | 
            +
                        corrector.insert_before(line, "\n") if should_insert_line_before?(node)
         | 
| 97 97 |  | 
| 98 98 | 
             
                        correct_next_line_if_denied_style(corrector, node, line)
         | 
| 99 99 | 
             
                      end
         | 
| @@ -122,6 +122,8 @@ module RuboCop | |
| 122 122 | 
             
                    end
         | 
| 123 123 |  | 
| 124 124 | 
             
                    def correct_next_line_if_denied_style(corrector, node, line)
         | 
| 125 | 
            +
                      return unless should_insert_line_after?(node)
         | 
| 126 | 
            +
             | 
| 125 127 | 
             
                      case style
         | 
| 126 128 | 
             
                      when :around
         | 
| 127 129 | 
             
                        corrector.insert_after(line, "\n") unless next_line_empty?(node.last_line)
         | 
| @@ -205,6 +207,29 @@ module RuboCop | |
| 205 207 | 
             
                        format(MSG_BEFORE_FOR_ONLY_BEFORE, modifier: modifier)
         | 
| 206 208 | 
             
                      end
         | 
| 207 209 | 
             
                    end
         | 
| 210 | 
            +
             | 
| 211 | 
            +
                    def should_insert_line_before?(node)
         | 
| 212 | 
            +
                      return false if previous_line_empty?(node.first_line)
         | 
| 213 | 
            +
                      return true unless inside_block?(node) && no_empty_lines_around_block_body?
         | 
| 214 | 
            +
                      return true unless node.parent.begin_type?
         | 
| 215 | 
            +
             | 
| 216 | 
            +
                      node.parent.children.first != node
         | 
| 217 | 
            +
                    end
         | 
| 218 | 
            +
             | 
| 219 | 
            +
                    def should_insert_line_after?(node)
         | 
| 220 | 
            +
                      return true unless inside_block?(node) && no_empty_lines_around_block_body?
         | 
| 221 | 
            +
             | 
| 222 | 
            +
                      node.parent.children.last != node
         | 
| 223 | 
            +
                    end
         | 
| 224 | 
            +
             | 
| 225 | 
            +
                    def inside_block?(node)
         | 
| 226 | 
            +
                      node.parent.block_type? || (node.parent.begin_type? && node.parent.parent&.block_type?)
         | 
| 227 | 
            +
                    end
         | 
| 228 | 
            +
             | 
| 229 | 
            +
                    def no_empty_lines_around_block_body?
         | 
| 230 | 
            +
                      config.for_enabled_cop('Layout/EmptyLinesAroundBlockBody')['EnforcedStyle'] ==
         | 
| 231 | 
            +
                        'no_empty_lines'
         | 
| 232 | 
            +
                    end
         | 
| 208 233 | 
             
                  end
         | 
| 209 234 | 
             
                end
         | 
| 210 235 | 
             
              end
         | 
| @@ -209,7 +209,7 @@ module RuboCop | |
| 209 209 | 
             
                    # are not bisected.
         | 
| 210 210 | 
             
                    # If the string contains spaces, use them to determine a place for a clean break;
         | 
| 211 211 | 
             
                    # otherwise, the string will be broken at the line length limit.
         | 
| 212 | 
            -
                    def breakable_string_range(node) | 
| 212 | 
            +
                    def breakable_string_range(node)
         | 
| 213 213 | 
             
                      source_range = node.source_range
         | 
| 214 214 | 
             
                      relevant_substr = largest_possible_string(node)
         | 
| 215 215 |  | 
| @@ -221,13 +221,13 @@ module RuboCop | |
| 221 221 | 
             
                        adjustment = max - source_range.last_column - 3
         | 
| 222 222 | 
             
                        return if adjustment.abs > source_range.size
         | 
| 223 223 |  | 
| 224 | 
            -
                        source_range.adjust(end_pos:  | 
| 224 | 
            +
                        source_range.adjust(end_pos: adjustment)
         | 
| 225 225 | 
             
                      end
         | 
| 226 226 | 
             
                    end
         | 
| 227 227 |  | 
| 228 228 | 
             
                    def breakable_dstr_begin_position(node)
         | 
| 229 229 | 
             
                      source_range = node.source_range
         | 
| 230 | 
            -
                      source_range.begin_pos if source_range. | 
| 230 | 
            +
                      source_range.begin_pos if source_range.column < max && source_range.last_column >= max
         | 
| 231 231 | 
             
                    end
         | 
| 232 232 |  | 
| 233 233 | 
             
                    def breakable_range_by_line_index
         | 
| @@ -54,14 +54,12 @@ module RuboCop | |
| 54 54 | 
             
                      # if a method definition is inside an if, it is very likely
         | 
| 55 55 | 
             
                      # that a different definition is used depending on platform, etc.
         | 
| 56 56 | 
             
                      return if node.each_ancestor.any?(&:if_type?)
         | 
| 57 | 
            -
                      return if possible_dsl?(node)
         | 
| 58 57 |  | 
| 59 58 | 
             
                      found_instance_method(node, node.method_name)
         | 
| 60 59 | 
             
                    end
         | 
| 61 60 |  | 
| 62 61 | 
             
                    def on_defs(node)
         | 
| 63 62 | 
             
                      return if node.each_ancestor.any?(&:if_type?)
         | 
| 64 | 
            -
                      return if possible_dsl?(node)
         | 
| 65 63 |  | 
| 66 64 | 
             
                      if node.receiver.const_type?
         | 
| 67 65 | 
             
                        _, const_name = *node.receiver
         | 
| @@ -79,7 +77,6 @@ module RuboCop | |
| 79 77 | 
             
                    def on_alias(node)
         | 
| 80 78 | 
             
                      return unless (name = method_alias?(node))
         | 
| 81 79 | 
             
                      return if node.ancestors.any?(&:if_type?)
         | 
| 82 | 
            -
                      return if possible_dsl?(node)
         | 
| 83 80 |  | 
| 84 81 | 
             
                      found_instance_method(node, name)
         | 
| 85 82 | 
             
                    end
         | 
| @@ -94,7 +91,6 @@ module RuboCop | |
| 94 91 | 
             
                    def on_send(node)
         | 
| 95 92 | 
             
                      if (name = alias_method?(node))
         | 
| 96 93 | 
             
                        return if node.ancestors.any?(&:if_type?)
         | 
| 97 | 
            -
                        return if possible_dsl?(node)
         | 
| 98 94 |  | 
| 99 95 | 
             
                        found_instance_method(node, name)
         | 
| 100 96 | 
             
                      elsif (attr = node.attribute_accessor?)
         | 
| @@ -237,16 +233,6 @@ module RuboCop | |
| 237 233 | 
             
                      end
         | 
| 238 234 | 
             
                    end
         | 
| 239 235 |  | 
| 240 | 
            -
                    def possible_dsl?(node)
         | 
| 241 | 
            -
                      # DSL methods may evaluate a block in the context of a newly created
         | 
| 242 | 
            -
                      # class or module
         | 
| 243 | 
            -
                      # Assume that if a method definition is inside any block call which
         | 
| 244 | 
            -
                      # we can't identify, it could be a DSL
         | 
| 245 | 
            -
                      node.each_ancestor(:block).any? do |ancestor|
         | 
| 246 | 
            -
                        !ancestor.method?(:class_eval) && !ancestor.class_constructor?
         | 
| 247 | 
            -
                      end
         | 
| 248 | 
            -
                    end
         | 
| 249 | 
            -
             | 
| 250 236 | 
             
                    def source_location(node)
         | 
| 251 237 | 
             
                      range = node.source_range
         | 
| 252 238 | 
             
                      path = smart_path(range.source_buffer.name)
         |