rubocop 1.32.0 → 1.37.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 +2 -2
 - data/config/default.yml +104 -16
 - data/config/obsoletion.yml +23 -1
 - data/lib/rubocop/arguments_env.rb +17 -0
 - data/lib/rubocop/arguments_file.rb +17 -0
 - data/lib/rubocop/cache_config.rb +29 -0
 - data/lib/rubocop/cli/command/{auto_genenerate_config.rb → auto_generate_config.rb} +2 -2
 - data/lib/rubocop/cli/command/execute_runner.rb +7 -7
 - data/lib/rubocop/cli/command/init_dotfile.rb +1 -1
 - data/lib/rubocop/cli/command/suggest_extensions.rb +53 -15
 - data/lib/rubocop/config.rb +1 -1
 - data/lib/rubocop/config_finder.rb +68 -0
 - data/lib/rubocop/config_loader.rb +12 -40
 - data/lib/rubocop/config_loader_resolver.rb +1 -5
 - data/lib/rubocop/config_obsoletion/changed_parameter.rb +5 -0
 - data/lib/rubocop/config_obsoletion/parameter_rule.rb +4 -0
 - data/lib/rubocop/config_obsoletion.rb +7 -2
 - data/lib/rubocop/cop/cop.rb +1 -1
 - data/lib/rubocop/cop/correctors/parentheses_corrector.rb +58 -0
 - data/lib/rubocop/cop/gemspec/require_mfa.rb +1 -1
 - data/lib/rubocop/cop/generator/require_file_injector.rb +2 -2
 - data/lib/rubocop/cop/generator.rb +1 -2
 - data/lib/rubocop/cop/internal_affairs/numblock_handler.rb +69 -0
 - data/lib/rubocop/cop/internal_affairs/single_line_comparison.rb +62 -0
 - data/lib/rubocop/cop/internal_affairs.rb +2 -0
 - data/lib/rubocop/cop/layout/block_alignment.rb +16 -12
 - data/lib/rubocop/cop/layout/block_end_newline.rb +35 -5
 - data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +5 -2
 - data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +2 -0
 - data/lib/rubocop/cop/layout/end_of_line.rb +4 -4
 - data/lib/rubocop/cop/layout/first_argument_indentation.rb +7 -1
 - data/lib/rubocop/cop/layout/first_array_element_indentation.rb +2 -2
 - data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +2 -2
 - data/lib/rubocop/cop/layout/indentation_width.rb +6 -2
 - data/lib/rubocop/cop/layout/line_length.rb +4 -1
 - data/lib/rubocop/cop/layout/multiline_assignment_layout.rb +1 -1
 - data/lib/rubocop/cop/layout/multiline_block_layout.rb +2 -0
 - data/lib/rubocop/cop/layout/redundant_line_break.rb +1 -1
 - data/lib/rubocop/cop/layout/space_around_block_parameters.rb +1 -1
 - data/lib/rubocop/cop/layout/space_around_keyword.rb +1 -1
 - data/lib/rubocop/cop/layout/space_before_block_braces.rb +2 -0
 - data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +13 -9
 - data/lib/rubocop/cop/layout/space_inside_block_braces.rb +25 -9
 - data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +28 -3
 - data/lib/rubocop/cop/legacy/corrections_proxy.rb +1 -1
 - data/lib/rubocop/cop/legacy/corrector.rb +1 -1
 - data/lib/rubocop/cop/lint/ambiguous_block_association.rb +21 -8
 - data/lib/rubocop/cop/lint/debugger.rb +26 -16
 - data/lib/rubocop/cop/lint/deprecated_class_methods.rb +4 -4
 - data/lib/rubocop/cop/lint/duplicate_magic_comment.rb +73 -0
 - data/lib/rubocop/cop/lint/duplicate_methods.rb +11 -1
 - data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +25 -6
 - data/lib/rubocop/cop/lint/duplicate_require.rb +1 -1
 - data/lib/rubocop/cop/lint/empty_block.rb +1 -1
 - data/lib/rubocop/cop/lint/empty_class.rb +3 -1
 - data/lib/rubocop/cop/lint/empty_conditional_body.rb +107 -1
 - data/lib/rubocop/cop/lint/erb_new_arguments.rb +9 -9
 - data/lib/rubocop/cop/lint/literal_in_interpolation.rb +4 -0
 - data/lib/rubocop/cop/lint/nested_method_definition.rb +50 -1
 - data/lib/rubocop/cop/lint/next_without_accumulator.rb +25 -6
 - data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +6 -6
 - data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +12 -0
 - data/lib/rubocop/cop/lint/number_conversion.rb +24 -8
 - data/lib/rubocop/cop/lint/ordered_magic_comments.rb +4 -5
 - data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +1 -1
 - data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +12 -1
 - data/lib/rubocop/cop/lint/redundant_dir_glob_sort.rb +7 -0
 - data/lib/rubocop/cop/lint/redundant_require_statement.rb +29 -9
 - data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +9 -3
 - data/lib/rubocop/cop/lint/redundant_with_index.rb +13 -10
 - data/lib/rubocop/cop/lint/redundant_with_object.rb +12 -11
 - data/lib/rubocop/cop/lint/require_parentheses.rb +1 -1
 - data/lib/rubocop/cop/lint/safe_navigation_chain.rb +3 -2
 - data/lib/rubocop/cop/lint/shadowed_exception.rb +15 -10
 - data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +27 -3
 - data/lib/rubocop/cop/lint/unreachable_loop.rb +9 -3
 - data/lib/rubocop/cop/lint/unused_method_argument.rb +4 -0
 - data/lib/rubocop/cop/lint/useless_access_modifier.rb +8 -6
 - data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +1 -1
 - data/lib/rubocop/cop/lint/void.rb +2 -0
 - data/lib/rubocop/cop/metrics/abc_size.rb +3 -1
 - data/lib/rubocop/cop/metrics/block_length.rb +6 -7
 - data/lib/rubocop/cop/metrics/method_length.rb +8 -8
 - data/lib/rubocop/cop/mixin/allowed_methods.rb +20 -1
 - data/lib/rubocop/cop/mixin/allowed_pattern.rb +17 -1
 - data/lib/rubocop/cop/mixin/check_line_breakable.rb +1 -1
 - data/lib/rubocop/cop/mixin/comments_help.rb +17 -1
 - data/lib/rubocop/cop/mixin/enforce_superclass.rb +2 -1
 - data/lib/rubocop/cop/mixin/frozen_string_literal.rb +4 -0
 - data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +82 -4
 - data/lib/rubocop/cop/mixin/hash_transform_method.rb +10 -6
 - data/lib/rubocop/cop/mixin/method_complexity.rb +8 -13
 - data/lib/rubocop/cop/mixin/multiline_element_indentation.rb +1 -1
 - data/lib/rubocop/cop/mixin/range_help.rb +4 -5
 - data/lib/rubocop/cop/mixin/rescue_node.rb +3 -1
 - data/lib/rubocop/cop/mixin/surrounding_space.rb +6 -5
 - data/lib/rubocop/cop/naming/block_parameter_name.rb +1 -1
 - data/lib/rubocop/cop/naming/constant_name.rb +2 -2
 - data/lib/rubocop/cop/naming/inclusive_language.rb +1 -1
 - data/lib/rubocop/cop/naming/predicate_name.rb +24 -3
 - data/lib/rubocop/cop/style/access_modifier_declarations.rb +97 -1
 - data/lib/rubocop/cop/style/accessor_grouping.rb +7 -3
 - data/lib/rubocop/cop/style/arguments_forwarding.rb +2 -2
 - data/lib/rubocop/cop/style/block_delimiters.rb +26 -7
 - data/lib/rubocop/cop/style/case_equality.rb +40 -10
 - data/lib/rubocop/cop/style/class_and_module_children.rb +4 -4
 - data/lib/rubocop/cop/style/class_equality_comparison.rb +32 -7
 - data/lib/rubocop/cop/style/class_methods_definitions.rb +2 -1
 - data/lib/rubocop/cop/style/collection_compact.rb +6 -1
 - data/lib/rubocop/cop/style/collection_methods.rb +2 -0
 - data/lib/rubocop/cop/style/combinable_loops.rb +3 -1
 - data/lib/rubocop/cop/style/double_negation.rb +2 -0
 - data/lib/rubocop/cop/style/each_for_simple_loop.rb +41 -6
 - data/lib/rubocop/cop/style/each_with_object.rb +39 -8
 - data/lib/rubocop/cop/style/empty_block_parameter.rb +1 -1
 - data/lib/rubocop/cop/style/empty_heredoc.rb +15 -1
 - data/lib/rubocop/cop/style/empty_lambda_parameter.rb +1 -1
 - data/lib/rubocop/cop/style/empty_method.rb +1 -1
 - data/lib/rubocop/cop/style/endless_method.rb +1 -1
 - data/lib/rubocop/cop/style/explicit_block_argument.rb +4 -0
 - data/lib/rubocop/cop/style/for.rb +2 -0
 - data/lib/rubocop/cop/style/format_string_token.rb +21 -8
 - data/lib/rubocop/cop/style/guard_clause.rb +27 -16
 - data/lib/rubocop/cop/style/hash_each_methods.rb +3 -1
 - data/lib/rubocop/cop/style/hash_except.rb +0 -4
 - data/lib/rubocop/cop/style/hash_syntax.rb +17 -0
 - data/lib/rubocop/cop/style/if_unless_modifier.rb +1 -1
 - data/lib/rubocop/cop/style/inverse_methods.rb +8 -6
 - data/lib/rubocop/cop/style/magic_comment_format.rb +307 -0
 - data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +15 -4
 - data/lib/rubocop/cop/style/method_call_with_args_parentheses/require_parentheses.rb +5 -1
 - data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +7 -7
 - data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +11 -6
 - data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +4 -1
 - data/lib/rubocop/cop/style/multiline_block_chain.rb +3 -1
 - data/lib/rubocop/cop/style/multiline_in_pattern_then.rb +1 -1
 - data/lib/rubocop/cop/style/negated_if_else_condition.rb +7 -1
 - data/lib/rubocop/cop/style/next.rb +3 -5
 - data/lib/rubocop/cop/style/nil_lambda.rb +1 -1
 - data/lib/rubocop/cop/style/numeric_literals.rb +16 -1
 - data/lib/rubocop/cop/style/numeric_predicate.rb +28 -8
 - data/lib/rubocop/cop/style/object_then.rb +2 -0
 - data/lib/rubocop/cop/style/operator_method_call.rb +39 -0
 - data/lib/rubocop/cop/style/perl_backrefs.rb +22 -1
 - data/lib/rubocop/cop/style/proc.rb +4 -1
 - data/lib/rubocop/cop/style/redundant_begin.rb +3 -0
 - data/lib/rubocop/cop/style/redundant_condition.rb +24 -6
 - data/lib/rubocop/cop/style/redundant_fetch_block.rb +1 -1
 - data/lib/rubocop/cop/style/redundant_initialize.rb +3 -1
 - data/lib/rubocop/cop/style/redundant_parentheses.rb +19 -22
 - data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +8 -1
 - data/lib/rubocop/cop/style/redundant_self.rb +2 -0
 - data/lib/rubocop/cop/style/redundant_sort.rb +21 -6
 - data/lib/rubocop/cop/style/redundant_sort_by.rb +24 -8
 - data/lib/rubocop/cop/style/redundant_string_escape.rb +173 -0
 - data/lib/rubocop/cop/style/rescue_modifier.rb +1 -1
 - data/lib/rubocop/cop/style/safe_navigation.rb +4 -2
 - data/lib/rubocop/cop/style/single_line_block_params.rb +1 -1
 - data/lib/rubocop/cop/style/sole_nested_conditional.rb +14 -5
 - data/lib/rubocop/cop/style/static_class.rb +32 -1
 - data/lib/rubocop/cop/style/symbol_array.rb +3 -1
 - data/lib/rubocop/cop/style/symbol_proc.rb +38 -12
 - data/lib/rubocop/cop/style/ternary_parentheses.rb +1 -13
 - data/lib/rubocop/cop/style/top_level_method_definition.rb +3 -1
 - data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +1 -1
 - data/lib/rubocop/cop/style/word_array.rb +3 -1
 - data/lib/rubocop/cop/util.rb +1 -1
 - data/lib/rubocop/ext/range.rb +15 -0
 - data/lib/rubocop/feature_loader.rb +94 -0
 - data/lib/rubocop/formatter/clang_style_formatter.rb +1 -1
 - data/lib/rubocop/formatter/disabled_config_formatter.rb +9 -3
 - data/lib/rubocop/formatter/html_formatter.rb +3 -3
 - data/lib/rubocop/formatter/markdown_formatter.rb +1 -1
 - data/lib/rubocop/formatter/tap_formatter.rb +1 -1
 - data/lib/rubocop/options.rb +13 -13
 - data/lib/rubocop/result_cache.rb +22 -20
 - data/lib/rubocop/rspec/shared_contexts.rb +13 -1
 - data/lib/rubocop/runner.rb +4 -0
 - data/lib/rubocop/server/cache.rb +41 -2
 - data/lib/rubocop/server/cli.rb +26 -2
 - data/lib/rubocop/server/client_command/exec.rb +5 -0
 - data/lib/rubocop/server/core.rb +2 -1
 - data/lib/rubocop/server/socket_reader.rb +5 -1
 - data/lib/rubocop/server.rb +1 -1
 - data/lib/rubocop/version.rb +8 -2
 - data/lib/rubocop.rb +8 -3
 - metadata +20 -9
 - data/lib/rubocop/cop/mixin/ignored_methods.rb +0 -52
 
| 
         @@ -0,0 +1,307 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module RuboCop
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Cop
         
     | 
| 
      
 5 
     | 
    
         
            +
                module Style
         
     | 
| 
      
 6 
     | 
    
         
            +
                  # Ensures magic comments are written consistently throughout your code base.
         
     | 
| 
      
 7 
     | 
    
         
            +
                  # Looks for discrepancies in separators (`-` vs `_`) and capitalization for
         
     | 
| 
      
 8 
     | 
    
         
            +
                  # both magic comment directives and values.
         
     | 
| 
      
 9 
     | 
    
         
            +
                  #
         
     | 
| 
      
 10 
     | 
    
         
            +
                  # Required capitalization can be set with the `DirectiveCapitalization` and
         
     | 
| 
      
 11 
     | 
    
         
            +
                  # `ValueCapitalization` configuration keys.
         
     | 
| 
      
 12 
     | 
    
         
            +
                  #
         
     | 
| 
      
 13 
     | 
    
         
            +
                  # NOTE: If one of these configuration is set to nil, any capitalization is allowed.
         
     | 
| 
      
 14 
     | 
    
         
            +
                  #
         
     | 
| 
      
 15 
     | 
    
         
            +
                  # @example EnforcedStyle: snake_case (default)
         
     | 
| 
      
 16 
     | 
    
         
            +
                  #   # The `snake_case` style will enforce that the frozen string literal
         
     | 
| 
      
 17 
     | 
    
         
            +
                  #   # comment is written in snake case. (Words separated by underscores)
         
     | 
| 
      
 18 
     | 
    
         
            +
                  #   # bad
         
     | 
| 
      
 19 
     | 
    
         
            +
                  #   # frozen-string-literal: true
         
     | 
| 
      
 20 
     | 
    
         
            +
                  #
         
     | 
| 
      
 21 
     | 
    
         
            +
                  #   module Bar
         
     | 
| 
      
 22 
     | 
    
         
            +
                  #     # ...
         
     | 
| 
      
 23 
     | 
    
         
            +
                  #   end
         
     | 
| 
      
 24 
     | 
    
         
            +
                  #
         
     | 
| 
      
 25 
     | 
    
         
            +
                  #   # good
         
     | 
| 
      
 26 
     | 
    
         
            +
                  #   # frozen_string_literal: false
         
     | 
| 
      
 27 
     | 
    
         
            +
                  #
         
     | 
| 
      
 28 
     | 
    
         
            +
                  #   module Bar
         
     | 
| 
      
 29 
     | 
    
         
            +
                  #     # ...
         
     | 
| 
      
 30 
     | 
    
         
            +
                  #   end
         
     | 
| 
      
 31 
     | 
    
         
            +
                  #
         
     | 
| 
      
 32 
     | 
    
         
            +
                  # @example EnforcedStyle: kebab_case
         
     | 
| 
      
 33 
     | 
    
         
            +
                  #   # The `kebab_case` style will enforce that the frozen string literal
         
     | 
| 
      
 34 
     | 
    
         
            +
                  #   # comment is written in kebab case. (Words separated by hyphens)
         
     | 
| 
      
 35 
     | 
    
         
            +
                  #   # bad
         
     | 
| 
      
 36 
     | 
    
         
            +
                  #   # frozen_string_literal: true
         
     | 
| 
      
 37 
     | 
    
         
            +
                  #
         
     | 
| 
      
 38 
     | 
    
         
            +
                  #   module Baz
         
     | 
| 
      
 39 
     | 
    
         
            +
                  #     # ...
         
     | 
| 
      
 40 
     | 
    
         
            +
                  #   end
         
     | 
| 
      
 41 
     | 
    
         
            +
                  #
         
     | 
| 
      
 42 
     | 
    
         
            +
                  #   # good
         
     | 
| 
      
 43 
     | 
    
         
            +
                  #   # frozen-string-literal: true
         
     | 
| 
      
 44 
     | 
    
         
            +
                  #
         
     | 
| 
      
 45 
     | 
    
         
            +
                  #   module Baz
         
     | 
| 
      
 46 
     | 
    
         
            +
                  #     # ...
         
     | 
| 
      
 47 
     | 
    
         
            +
                  #   end
         
     | 
| 
      
 48 
     | 
    
         
            +
                  #
         
     | 
| 
      
 49 
     | 
    
         
            +
                  # @example DirectiveCapitalization: lowercase (default)
         
     | 
| 
      
 50 
     | 
    
         
            +
                  #   # bad
         
     | 
| 
      
 51 
     | 
    
         
            +
                  #   # FROZEN-STRING-LITERAL: true
         
     | 
| 
      
 52 
     | 
    
         
            +
                  #
         
     | 
| 
      
 53 
     | 
    
         
            +
                  #   # good
         
     | 
| 
      
 54 
     | 
    
         
            +
                  #   # frozen-string-literal: true
         
     | 
| 
      
 55 
     | 
    
         
            +
                  #
         
     | 
| 
      
 56 
     | 
    
         
            +
                  # @example DirectiveCapitalization: uppercase
         
     | 
| 
      
 57 
     | 
    
         
            +
                  #   # bad
         
     | 
| 
      
 58 
     | 
    
         
            +
                  #   # frozen-string-literal: true
         
     | 
| 
      
 59 
     | 
    
         
            +
                  #
         
     | 
| 
      
 60 
     | 
    
         
            +
                  #   # good
         
     | 
| 
      
 61 
     | 
    
         
            +
                  #   # FROZEN-STRING-LITERAL: true
         
     | 
| 
      
 62 
     | 
    
         
            +
                  #
         
     | 
| 
      
 63 
     | 
    
         
            +
                  # @example DirectiveCapitalization: nil
         
     | 
| 
      
 64 
     | 
    
         
            +
                  #   # any capitalization is accepted
         
     | 
| 
      
 65 
     | 
    
         
            +
                  #
         
     | 
| 
      
 66 
     | 
    
         
            +
                  #   # good
         
     | 
| 
      
 67 
     | 
    
         
            +
                  #   # frozen-string-literal: true
         
     | 
| 
      
 68 
     | 
    
         
            +
                  #
         
     | 
| 
      
 69 
     | 
    
         
            +
                  #   # good
         
     | 
| 
      
 70 
     | 
    
         
            +
                  #   # FROZEN-STRING-LITERAL: true
         
     | 
| 
      
 71 
     | 
    
         
            +
                  #
         
     | 
| 
      
 72 
     | 
    
         
            +
                  # @example ValueCapitalization: nil (default)
         
     | 
| 
      
 73 
     | 
    
         
            +
                  #   # any capitalization is accepted
         
     | 
| 
      
 74 
     | 
    
         
            +
                  #
         
     | 
| 
      
 75 
     | 
    
         
            +
                  #   # good
         
     | 
| 
      
 76 
     | 
    
         
            +
                  #   # frozen-string-literal: true
         
     | 
| 
      
 77 
     | 
    
         
            +
                  #
         
     | 
| 
      
 78 
     | 
    
         
            +
                  #   # good
         
     | 
| 
      
 79 
     | 
    
         
            +
                  #   # frozen-string-literal: TRUE
         
     | 
| 
      
 80 
     | 
    
         
            +
                  #
         
     | 
| 
      
 81 
     | 
    
         
            +
                  # @example ValueCapitalization: lowercase
         
     | 
| 
      
 82 
     | 
    
         
            +
                  #   # when a value is not given, any capitalization is accepted
         
     | 
| 
      
 83 
     | 
    
         
            +
                  #
         
     | 
| 
      
 84 
     | 
    
         
            +
                  #   # bad
         
     | 
| 
      
 85 
     | 
    
         
            +
                  #   # frozen-string-literal: TRUE
         
     | 
| 
      
 86 
     | 
    
         
            +
                  #
         
     | 
| 
      
 87 
     | 
    
         
            +
                  #   # good
         
     | 
| 
      
 88 
     | 
    
         
            +
                  #   # frozen-string-literal: TRUE
         
     | 
| 
      
 89 
     | 
    
         
            +
                  #
         
     | 
| 
      
 90 
     | 
    
         
            +
                  # @example ValueCapitalization: uppercase
         
     | 
| 
      
 91 
     | 
    
         
            +
                  #   # bad
         
     | 
| 
      
 92 
     | 
    
         
            +
                  #   # frozen-string-literal: true
         
     | 
| 
      
 93 
     | 
    
         
            +
                  #
         
     | 
| 
      
 94 
     | 
    
         
            +
                  #   # good
         
     | 
| 
      
 95 
     | 
    
         
            +
                  #   # frozen-string-literal: TRUE
         
     | 
| 
      
 96 
     | 
    
         
            +
                  #
         
     | 
| 
      
 97 
     | 
    
         
            +
                  class MagicCommentFormat < Base
         
     | 
| 
      
 98 
     | 
    
         
            +
                    include ConfigurableEnforcedStyle
         
     | 
| 
      
 99 
     | 
    
         
            +
                    extend AutoCorrector
         
     | 
| 
      
 100 
     | 
    
         
            +
             
     | 
| 
      
 101 
     | 
    
         
            +
                    SNAKE_SEPARATOR = '_'
         
     | 
| 
      
 102 
     | 
    
         
            +
                    KEBAB_SEPARATOR = '-'
         
     | 
| 
      
 103 
     | 
    
         
            +
                    MSG = 'Prefer %<style>s case for magic comments.'
         
     | 
| 
      
 104 
     | 
    
         
            +
                    MSG_VALUE = 'Prefer %<case>s for magic comment values.'
         
     | 
| 
      
 105 
     | 
    
         
            +
             
     | 
| 
      
 106 
     | 
    
         
            +
                    # Value object to extract source ranges for the different parts of a magic comment
         
     | 
| 
      
 107 
     | 
    
         
            +
                    class CommentRange
         
     | 
| 
      
 108 
     | 
    
         
            +
                      extend Forwardable
         
     | 
| 
      
 109 
     | 
    
         
            +
             
     | 
| 
      
 110 
     | 
    
         
            +
                      DIRECTIVE_REGEXP = Regexp.union(MagicComment::KEYWORDS.map do |_, v|
         
     | 
| 
      
 111 
     | 
    
         
            +
                        Regexp.new(v, Regexp::IGNORECASE)
         
     | 
| 
      
 112 
     | 
    
         
            +
                      end).freeze
         
     | 
| 
      
 113 
     | 
    
         
            +
             
     | 
| 
      
 114 
     | 
    
         
            +
                      VALUE_REGEXP = Regexp.new("(?:#{DIRECTIVE_REGEXP}:\s*)(.*?)(?=;|$)")
         
     | 
| 
      
 115 
     | 
    
         
            +
             
     | 
| 
      
 116 
     | 
    
         
            +
                      def_delegators :@comment, :text, :loc
         
     | 
| 
      
 117 
     | 
    
         
            +
                      attr_reader :comment
         
     | 
| 
      
 118 
     | 
    
         
            +
             
     | 
| 
      
 119 
     | 
    
         
            +
                      def initialize(comment)
         
     | 
| 
      
 120 
     | 
    
         
            +
                        @comment = comment
         
     | 
| 
      
 121 
     | 
    
         
            +
                      end
         
     | 
| 
      
 122 
     | 
    
         
            +
             
     | 
| 
      
 123 
     | 
    
         
            +
                      # A magic comment can contain one directive (normal style) or
         
     | 
| 
      
 124 
     | 
    
         
            +
                      # multiple directives (emacs style)
         
     | 
| 
      
 125 
     | 
    
         
            +
                      def directives
         
     | 
| 
      
 126 
     | 
    
         
            +
                        @directives ||= begin
         
     | 
| 
      
 127 
     | 
    
         
            +
                          matches = []
         
     | 
| 
      
 128 
     | 
    
         
            +
             
     | 
| 
      
 129 
     | 
    
         
            +
                          text.scan(DIRECTIVE_REGEXP) do
         
     | 
| 
      
 130 
     | 
    
         
            +
                            offset = Regexp.last_match.offset(0)
         
     | 
| 
      
 131 
     | 
    
         
            +
                            matches << loc.expression.adjust(begin_pos: offset.first)
         
     | 
| 
      
 132 
     | 
    
         
            +
                                          .with(end_pos: loc.expression.begin_pos + offset.last)
         
     | 
| 
      
 133 
     | 
    
         
            +
                          end
         
     | 
| 
      
 134 
     | 
    
         
            +
             
     | 
| 
      
 135 
     | 
    
         
            +
                          matches
         
     | 
| 
      
 136 
     | 
    
         
            +
                        end
         
     | 
| 
      
 137 
     | 
    
         
            +
                      end
         
     | 
| 
      
 138 
     | 
    
         
            +
             
     | 
| 
      
 139 
     | 
    
         
            +
                      # A magic comment can contain one value (normal style) or
         
     | 
| 
      
 140 
     | 
    
         
            +
                      # multiple directives (emacs style)
         
     | 
| 
      
 141 
     | 
    
         
            +
                      def values
         
     | 
| 
      
 142 
     | 
    
         
            +
                        @values ||= begin
         
     | 
| 
      
 143 
     | 
    
         
            +
                          matches = []
         
     | 
| 
      
 144 
     | 
    
         
            +
             
     | 
| 
      
 145 
     | 
    
         
            +
                          text.scan(VALUE_REGEXP) do
         
     | 
| 
      
 146 
     | 
    
         
            +
                            offset = Regexp.last_match.offset(1)
         
     | 
| 
      
 147 
     | 
    
         
            +
                            matches << loc.expression.adjust(begin_pos: offset.first)
         
     | 
| 
      
 148 
     | 
    
         
            +
                                          .with(end_pos: loc.expression.begin_pos + offset.last)
         
     | 
| 
      
 149 
     | 
    
         
            +
                          end
         
     | 
| 
      
 150 
     | 
    
         
            +
             
     | 
| 
      
 151 
     | 
    
         
            +
                          matches
         
     | 
| 
      
 152 
     | 
    
         
            +
                        end
         
     | 
| 
      
 153 
     | 
    
         
            +
                      end
         
     | 
| 
      
 154 
     | 
    
         
            +
                    end
         
     | 
| 
      
 155 
     | 
    
         
            +
             
     | 
| 
      
 156 
     | 
    
         
            +
                    def on_new_investigation
         
     | 
| 
      
 157 
     | 
    
         
            +
                      return unless processed_source.ast
         
     | 
| 
      
 158 
     | 
    
         
            +
             
     | 
| 
      
 159 
     | 
    
         
            +
                      magic_comments.each do |comment|
         
     | 
| 
      
 160 
     | 
    
         
            +
                        issues = find_issues(comment)
         
     | 
| 
      
 161 
     | 
    
         
            +
                        register_offenses(issues) if issues.any?
         
     | 
| 
      
 162 
     | 
    
         
            +
                      end
         
     | 
| 
      
 163 
     | 
    
         
            +
                    end
         
     | 
| 
      
 164 
     | 
    
         
            +
             
     | 
| 
      
 165 
     | 
    
         
            +
                    private
         
     | 
| 
      
 166 
     | 
    
         
            +
             
     | 
| 
      
 167 
     | 
    
         
            +
                    def magic_comments
         
     | 
| 
      
 168 
     | 
    
         
            +
                      processed_source.each_comment_in_lines(leading_comment_lines)
         
     | 
| 
      
 169 
     | 
    
         
            +
                                      .select { |comment| MagicComment.parse(comment.text).valid? }
         
     | 
| 
      
 170 
     | 
    
         
            +
                                      .map { |comment| CommentRange.new(comment) }
         
     | 
| 
      
 171 
     | 
    
         
            +
                    end
         
     | 
| 
      
 172 
     | 
    
         
            +
             
     | 
| 
      
 173 
     | 
    
         
            +
                    def leading_comment_lines
         
     | 
| 
      
 174 
     | 
    
         
            +
                      first_non_comment_token = processed_source.tokens.find { |token| !token.comment? }
         
     | 
| 
      
 175 
     | 
    
         
            +
             
     | 
| 
      
 176 
     | 
    
         
            +
                      if first_non_comment_token
         
     | 
| 
      
 177 
     | 
    
         
            +
                        0...first_non_comment_token.line
         
     | 
| 
      
 178 
     | 
    
         
            +
                      else
         
     | 
| 
      
 179 
     | 
    
         
            +
                        (0..)
         
     | 
| 
      
 180 
     | 
    
         
            +
                      end
         
     | 
| 
      
 181 
     | 
    
         
            +
                    end
         
     | 
| 
      
 182 
     | 
    
         
            +
             
     | 
| 
      
 183 
     | 
    
         
            +
                    def find_issues(comment)
         
     | 
| 
      
 184 
     | 
    
         
            +
                      issues = { directives: [], values: [] }
         
     | 
| 
      
 185 
     | 
    
         
            +
             
     | 
| 
      
 186 
     | 
    
         
            +
                      comment.directives.each do |directive|
         
     | 
| 
      
 187 
     | 
    
         
            +
                        issues[:directives] << directive if directive_offends?(directive)
         
     | 
| 
      
 188 
     | 
    
         
            +
                      end
         
     | 
| 
      
 189 
     | 
    
         
            +
             
     | 
| 
      
 190 
     | 
    
         
            +
                      comment.values.each do |value| # rubocop:disable Style/HashEachMethods
         
     | 
| 
      
 191 
     | 
    
         
            +
                        issues[:values] << value if wrong_capitalization?(value.source, value_capitalization)
         
     | 
| 
      
 192 
     | 
    
         
            +
                      end
         
     | 
| 
      
 193 
     | 
    
         
            +
             
     | 
| 
      
 194 
     | 
    
         
            +
                      issues
         
     | 
| 
      
 195 
     | 
    
         
            +
                    end
         
     | 
| 
      
 196 
     | 
    
         
            +
             
     | 
| 
      
 197 
     | 
    
         
            +
                    def directive_offends?(directive)
         
     | 
| 
      
 198 
     | 
    
         
            +
                      incorrect_separator?(directive.source) ||
         
     | 
| 
      
 199 
     | 
    
         
            +
                        wrong_capitalization?(directive.source, directive_capitalization)
         
     | 
| 
      
 200 
     | 
    
         
            +
                    end
         
     | 
| 
      
 201 
     | 
    
         
            +
             
     | 
| 
      
 202 
     | 
    
         
            +
                    def register_offenses(issues)
         
     | 
| 
      
 203 
     | 
    
         
            +
                      fix_directives(issues[:directives])
         
     | 
| 
      
 204 
     | 
    
         
            +
                      fix_values(issues[:values])
         
     | 
| 
      
 205 
     | 
    
         
            +
                    end
         
     | 
| 
      
 206 
     | 
    
         
            +
             
     | 
| 
      
 207 
     | 
    
         
            +
                    def fix_directives(issues)
         
     | 
| 
      
 208 
     | 
    
         
            +
                      return if issues.empty?
         
     | 
| 
      
 209 
     | 
    
         
            +
             
     | 
| 
      
 210 
     | 
    
         
            +
                      msg = format(MSG, style: expected_style)
         
     | 
| 
      
 211 
     | 
    
         
            +
             
     | 
| 
      
 212 
     | 
    
         
            +
                      issues.each do |directive|
         
     | 
| 
      
 213 
     | 
    
         
            +
                        add_offense(directive, message: msg) do |corrector|
         
     | 
| 
      
 214 
     | 
    
         
            +
                          replacement = replace_separator(replace_capitalization(directive.source,
         
     | 
| 
      
 215 
     | 
    
         
            +
                                                                                 directive_capitalization))
         
     | 
| 
      
 216 
     | 
    
         
            +
                          corrector.replace(directive, replacement)
         
     | 
| 
      
 217 
     | 
    
         
            +
                        end
         
     | 
| 
      
 218 
     | 
    
         
            +
                      end
         
     | 
| 
      
 219 
     | 
    
         
            +
                    end
         
     | 
| 
      
 220 
     | 
    
         
            +
             
     | 
| 
      
 221 
     | 
    
         
            +
                    def fix_values(issues)
         
     | 
| 
      
 222 
     | 
    
         
            +
                      return if issues.empty?
         
     | 
| 
      
 223 
     | 
    
         
            +
             
     | 
| 
      
 224 
     | 
    
         
            +
                      msg = format(MSG_VALUE, case: value_capitalization)
         
     | 
| 
      
 225 
     | 
    
         
            +
             
     | 
| 
      
 226 
     | 
    
         
            +
                      issues.each do |value|
         
     | 
| 
      
 227 
     | 
    
         
            +
                        add_offense(value, message: msg) do |corrector|
         
     | 
| 
      
 228 
     | 
    
         
            +
                          corrector.replace(value, replace_capitalization(value.source, value_capitalization))
         
     | 
| 
      
 229 
     | 
    
         
            +
                        end
         
     | 
| 
      
 230 
     | 
    
         
            +
                      end
         
     | 
| 
      
 231 
     | 
    
         
            +
                    end
         
     | 
| 
      
 232 
     | 
    
         
            +
             
     | 
| 
      
 233 
     | 
    
         
            +
                    def expected_style
         
     | 
| 
      
 234 
     | 
    
         
            +
                      [directive_capitalization, style].compact.join(' ').gsub(/_?case\b/, '')
         
     | 
| 
      
 235 
     | 
    
         
            +
                    end
         
     | 
| 
      
 236 
     | 
    
         
            +
             
     | 
| 
      
 237 
     | 
    
         
            +
                    def wrong_separator
         
     | 
| 
      
 238 
     | 
    
         
            +
                      style == :snake_case ? KEBAB_SEPARATOR : SNAKE_SEPARATOR
         
     | 
| 
      
 239 
     | 
    
         
            +
                    end
         
     | 
| 
      
 240 
     | 
    
         
            +
             
     | 
| 
      
 241 
     | 
    
         
            +
                    def correct_separator
         
     | 
| 
      
 242 
     | 
    
         
            +
                      style == :snake_case ? SNAKE_SEPARATOR : KEBAB_SEPARATOR
         
     | 
| 
      
 243 
     | 
    
         
            +
                    end
         
     | 
| 
      
 244 
     | 
    
         
            +
             
     | 
| 
      
 245 
     | 
    
         
            +
                    def incorrect_separator?(text)
         
     | 
| 
      
 246 
     | 
    
         
            +
                      text[wrong_separator]
         
     | 
| 
      
 247 
     | 
    
         
            +
                    end
         
     | 
| 
      
 248 
     | 
    
         
            +
             
     | 
| 
      
 249 
     | 
    
         
            +
                    def wrong_capitalization?(text, expected_case)
         
     | 
| 
      
 250 
     | 
    
         
            +
                      return false unless expected_case
         
     | 
| 
      
 251 
     | 
    
         
            +
             
     | 
| 
      
 252 
     | 
    
         
            +
                      case expected_case
         
     | 
| 
      
 253 
     | 
    
         
            +
                      when :lowercase
         
     | 
| 
      
 254 
     | 
    
         
            +
                        text != text.downcase
         
     | 
| 
      
 255 
     | 
    
         
            +
                      when :uppercase
         
     | 
| 
      
 256 
     | 
    
         
            +
                        text != text.upcase
         
     | 
| 
      
 257 
     | 
    
         
            +
                      end
         
     | 
| 
      
 258 
     | 
    
         
            +
                    end
         
     | 
| 
      
 259 
     | 
    
         
            +
             
     | 
| 
      
 260 
     | 
    
         
            +
                    def replace_separator(text)
         
     | 
| 
      
 261 
     | 
    
         
            +
                      text.tr(wrong_separator, correct_separator)
         
     | 
| 
      
 262 
     | 
    
         
            +
                    end
         
     | 
| 
      
 263 
     | 
    
         
            +
             
     | 
| 
      
 264 
     | 
    
         
            +
                    def replace_capitalization(text, style)
         
     | 
| 
      
 265 
     | 
    
         
            +
                      return text unless style
         
     | 
| 
      
 266 
     | 
    
         
            +
             
     | 
| 
      
 267 
     | 
    
         
            +
                      case style
         
     | 
| 
      
 268 
     | 
    
         
            +
                      when :lowercase
         
     | 
| 
      
 269 
     | 
    
         
            +
                        text.downcase
         
     | 
| 
      
 270 
     | 
    
         
            +
                      when :uppercase
         
     | 
| 
      
 271 
     | 
    
         
            +
                        text.upcase
         
     | 
| 
      
 272 
     | 
    
         
            +
                      end
         
     | 
| 
      
 273 
     | 
    
         
            +
                    end
         
     | 
| 
      
 274 
     | 
    
         
            +
             
     | 
| 
      
 275 
     | 
    
         
            +
                    def line_range(line)
         
     | 
| 
      
 276 
     | 
    
         
            +
                      processed_source.buffer.line_range(line)
         
     | 
| 
      
 277 
     | 
    
         
            +
                    end
         
     | 
| 
      
 278 
     | 
    
         
            +
             
     | 
| 
      
 279 
     | 
    
         
            +
                    def directive_capitalization
         
     | 
| 
      
 280 
     | 
    
         
            +
                      cop_config['DirectiveCapitalization']&.to_sym.tap do |style|
         
     | 
| 
      
 281 
     | 
    
         
            +
                        unless valid_capitalization?(style)
         
     | 
| 
      
 282 
     | 
    
         
            +
                          raise "Unknown `DirectiveCapitalization` #{style} selected!"
         
     | 
| 
      
 283 
     | 
    
         
            +
                        end
         
     | 
| 
      
 284 
     | 
    
         
            +
                      end
         
     | 
| 
      
 285 
     | 
    
         
            +
                    end
         
     | 
| 
      
 286 
     | 
    
         
            +
             
     | 
| 
      
 287 
     | 
    
         
            +
                    def value_capitalization
         
     | 
| 
      
 288 
     | 
    
         
            +
                      cop_config['ValueCapitalization']&.to_sym.tap do |style|
         
     | 
| 
      
 289 
     | 
    
         
            +
                        unless valid_capitalization?(style)
         
     | 
| 
      
 290 
     | 
    
         
            +
                          raise "Unknown `ValueCapitalization` #{style} selected!"
         
     | 
| 
      
 291 
     | 
    
         
            +
                        end
         
     | 
| 
      
 292 
     | 
    
         
            +
                      end
         
     | 
| 
      
 293 
     | 
    
         
            +
                    end
         
     | 
| 
      
 294 
     | 
    
         
            +
             
     | 
| 
      
 295 
     | 
    
         
            +
                    def valid_capitalization?(style)
         
     | 
| 
      
 296 
     | 
    
         
            +
                      return true unless style
         
     | 
| 
      
 297 
     | 
    
         
            +
             
     | 
| 
      
 298 
     | 
    
         
            +
                      supported_capitalizations.include?(style)
         
     | 
| 
      
 299 
     | 
    
         
            +
                    end
         
     | 
| 
      
 300 
     | 
    
         
            +
             
     | 
| 
      
 301 
     | 
    
         
            +
                    def supported_capitalizations
         
     | 
| 
      
 302 
     | 
    
         
            +
                      cop_config['SupportedCapitalizations'].map(&:to_sym)
         
     | 
| 
      
 303 
     | 
    
         
            +
                    end
         
     | 
| 
      
 304 
     | 
    
         
            +
                  end
         
     | 
| 
      
 305 
     | 
    
         
            +
                end
         
     | 
| 
      
 306 
     | 
    
         
            +
              end
         
     | 
| 
      
 307 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -20,8 +20,8 @@ module RuboCop 
     | 
|
| 
       20 
20 
     | 
    
         
             
                        return if require_parentheses_for_hash_value_omission?(node)
         
     | 
| 
       21 
21 
     | 
    
         
             
                        return if syntax_like_method_call?(node)
         
     | 
| 
       22 
22 
     | 
    
         
             
                        return if super_call_without_arguments?(node)
         
     | 
| 
       23 
     | 
    
         
            -
                        return if allowed_camel_case_method_call?(node)
         
     | 
| 
       24 
23 
     | 
    
         
             
                        return if legitimate_call_with_parentheses?(node)
         
     | 
| 
      
 24 
     | 
    
         
            +
                        return if allowed_camel_case_method_call?(node)
         
     | 
| 
       25 
25 
     | 
    
         
             
                        return if allowed_string_interpolation_method_call?(node)
         
     | 
| 
       26 
26 
     | 
    
         | 
| 
       27 
27 
     | 
    
         
             
                        add_offense(offense_range(node), message: OMIT_MSG) do |corrector|
         
     | 
| 
         @@ -97,7 +97,8 @@ module RuboCop 
     | 
|
| 
       97 
97 
     | 
    
         
             
                          call_in_optional_arguments?(node) ||
         
     | 
| 
       98 
98 
     | 
    
         
             
                          call_in_single_line_inheritance?(node) ||
         
     | 
| 
       99 
99 
     | 
    
         
             
                          allowed_multiline_call_with_parentheses?(node) ||
         
     | 
| 
       100 
     | 
    
         
            -
                          allowed_chained_call_with_parentheses?(node)
         
     | 
| 
      
 100 
     | 
    
         
            +
                          allowed_chained_call_with_parentheses?(node) ||
         
     | 
| 
      
 101 
     | 
    
         
            +
                          assignment_in_condition?(node)
         
     | 
| 
       101 
102 
     | 
    
         
             
                      end
         
     | 
| 
       102 
103 
     | 
    
         | 
| 
       103 
104 
     | 
    
         
             
                      def call_in_literals?(node)
         
     | 
| 
         @@ -130,7 +131,7 @@ module RuboCop 
     | 
|
| 
       130 
131 
     | 
    
         
             
                          call_as_argument_or_chain?(node) ||
         
     | 
| 
       131 
132 
     | 
    
         
             
                          hash_literal_in_arguments?(node) ||
         
     | 
| 
       132 
133 
     | 
    
         
             
                          node.descendants.any? do |n|
         
     | 
| 
       133 
     | 
    
         
            -
                            n.forwarded_args_type? ||  
     | 
| 
      
 134 
     | 
    
         
            +
                            n.forwarded_args_type? || ambiguous_literal?(n) || logical_operator?(n) ||
         
     | 
| 
       134 
135 
     | 
    
         
             
                              call_with_braced_block?(n)
         
     | 
| 
       135 
136 
     | 
    
         
             
                          end
         
     | 
| 
       136 
137 
     | 
    
         
             
                      end
         
     | 
| 
         @@ -166,7 +167,7 @@ module RuboCop 
     | 
|
| 
       166 
167 
     | 
    
         
             
                        previous.parenthesized? || allowed_chained_call_with_parentheses?(previous)
         
     | 
| 
       167 
168 
     | 
    
         
             
                      end
         
     | 
| 
       168 
169 
     | 
    
         | 
| 
       169 
     | 
    
         
            -
                      def  
     | 
| 
      
 170 
     | 
    
         
            +
                      def ambiguous_literal?(node)
         
     | 
| 
       170 
171 
     | 
    
         
             
                        splat?(node) || ternary_if?(node) || regexp_slash_literal?(node) || unary_literal?(node)
         
     | 
| 
       171 
172 
     | 
    
         
             
                      end
         
     | 
| 
       172 
173 
     | 
    
         | 
| 
         @@ -202,6 +203,16 @@ module RuboCop 
     | 
|
| 
       202 
203 
     | 
    
         
             
                      def inside_string_interpolation?(node)
         
     | 
| 
       203 
204 
     | 
    
         
             
                        node.ancestors.drop_while { |a| !a.begin_type? }.any?(&:dstr_type?)
         
     | 
| 
       204 
205 
     | 
    
         
             
                      end
         
     | 
| 
      
 206 
     | 
    
         
            +
             
     | 
| 
      
 207 
     | 
    
         
            +
                      def assignment_in_condition?(node)
         
     | 
| 
      
 208 
     | 
    
         
            +
                        parent = node.parent
         
     | 
| 
      
 209 
     | 
    
         
            +
                        return false unless parent
         
     | 
| 
      
 210 
     | 
    
         
            +
             
     | 
| 
      
 211 
     | 
    
         
            +
                        grandparent = parent.parent
         
     | 
| 
      
 212 
     | 
    
         
            +
                        return false unless grandparent
         
     | 
| 
      
 213 
     | 
    
         
            +
             
     | 
| 
      
 214 
     | 
    
         
            +
                        parent.assignment? && (grandparent.conditional? || grandparent.when_type?)
         
     | 
| 
      
 215 
     | 
    
         
            +
                      end
         
     | 
| 
       205 
216 
     | 
    
         
             
                    end
         
     | 
| 
       206 
217 
     | 
    
         
             
                    # rubocop:enable Metrics/ModuleLength, Metrics/CyclomaticComplexity
         
     | 
| 
       207 
218 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -12,7 +12,7 @@ module RuboCop 
     | 
|
| 
       12 
12 
     | 
    
         
             
                      private
         
     | 
| 
       13 
13 
     | 
    
         | 
| 
       14 
14 
     | 
    
         
             
                      def require_parentheses(node)
         
     | 
| 
       15 
     | 
    
         
            -
                        return if  
     | 
| 
      
 15 
     | 
    
         
            +
                        return if allowed_method_name?(node.method_name)
         
     | 
| 
       16 
16 
     | 
    
         
             
                        return if matches_allowed_pattern?(node.method_name)
         
     | 
| 
       17 
17 
     | 
    
         
             
                        return if eligible_for_parentheses_omission?(node)
         
     | 
| 
       18 
18 
     | 
    
         
             
                        return unless node.arguments? && !node.parenthesized?
         
     | 
| 
         @@ -24,6 +24,10 @@ module RuboCop 
     | 
|
| 
       24 
24 
     | 
    
         
             
                        end
         
     | 
| 
       25 
25 
     | 
    
         
             
                      end
         
     | 
| 
       26 
26 
     | 
    
         | 
| 
      
 27 
     | 
    
         
            +
                      def allowed_method_name?(name)
         
     | 
| 
      
 28 
     | 
    
         
            +
                        allowed_method?(name) || matches_allowed_pattern?(name)
         
     | 
| 
      
 29 
     | 
    
         
            +
                      end
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
       27 
31 
     | 
    
         
             
                      def eligible_for_parentheses_omission?(node)
         
     | 
| 
       28 
32 
     | 
    
         
             
                        node.operator_method? || node.setter_method? || ignored_macro?(node)
         
     | 
| 
       29 
33 
     | 
    
         
             
                      end
         
     | 
| 
         @@ -6,8 +6,8 @@ module RuboCop 
     | 
|
| 
       6 
6 
     | 
    
         
             
                  # Enforces the presence (default) or absence of parentheses in
         
     | 
| 
       7 
7 
     | 
    
         
             
                  # method calls containing parameters.
         
     | 
| 
       8 
8 
     | 
    
         
             
                  #
         
     | 
| 
       9 
     | 
    
         
            -
                  # In the default style (require_parentheses), macro methods are  
     | 
| 
       10 
     | 
    
         
            -
                  # Additional methods can be added to the ` 
     | 
| 
      
 9 
     | 
    
         
            +
                  # In the default style (require_parentheses), macro methods are allowed.
         
     | 
| 
      
 10 
     | 
    
         
            +
                  # Additional methods can be added to the `AllowedMethods`
         
     | 
| 
       11 
11 
     | 
    
         
             
                  # or `AllowedPatterns` list. These options are
         
     | 
| 
       12 
12 
     | 
    
         
             
                  # valid only in the default style. Macros can be included by
         
     | 
| 
       13 
13 
     | 
    
         
             
                  # either setting `IgnoreMacros` to false or adding specific macros to
         
     | 
| 
         @@ -15,13 +15,13 @@ module RuboCop 
     | 
|
| 
       15 
15 
     | 
    
         
             
                  #
         
     | 
| 
       16 
16 
     | 
    
         
             
                  # Precedence of options is all follows:
         
     | 
| 
       17 
17 
     | 
    
         
             
                  #
         
     | 
| 
       18 
     | 
    
         
            -
                  # 1. ` 
     | 
| 
      
 18 
     | 
    
         
            +
                  # 1. `AllowedMethods`
         
     | 
| 
       19 
19 
     | 
    
         
             
                  # 2. `AllowedPatterns`
         
     | 
| 
       20 
20 
     | 
    
         
             
                  # 3. `IncludedMacros`
         
     | 
| 
       21 
21 
     | 
    
         
             
                  #
         
     | 
| 
       22 
22 
     | 
    
         
             
                  # eg. If a method is listed in both
         
     | 
| 
       23 
     | 
    
         
            -
                  # `IncludedMacros` and ` 
     | 
| 
       24 
     | 
    
         
            -
                  # precedence (that is, the method is  
     | 
| 
      
 23 
     | 
    
         
            +
                  # `IncludedMacros` and `AllowedMethods`, then the latter takes
         
     | 
| 
      
 24 
     | 
    
         
            +
                  # precedence (that is, the method is allowed).
         
     | 
| 
       25 
25 
     | 
    
         
             
                  #
         
     | 
| 
       26 
26 
     | 
    
         
             
                  # In the alternative style (omit_parentheses), there are three additional
         
     | 
| 
       27 
27 
     | 
    
         
             
                  # options.
         
     | 
| 
         @@ -65,7 +65,7 @@ module RuboCop 
     | 
|
| 
       65 
65 
     | 
    
         
             
                  #   # Setter methods don't need parens
         
     | 
| 
       66 
66 
     | 
    
         
             
                  #   foo.bar = baz
         
     | 
| 
       67 
67 
     | 
    
         
             
                  #
         
     | 
| 
       68 
     | 
    
         
            -
                  #   # okay with `puts` listed in ` 
     | 
| 
      
 68 
     | 
    
         
            +
                  #   # okay with `puts` listed in `AllowedMethods`
         
     | 
| 
       69 
69 
     | 
    
         
             
                  #   puts 'test'
         
     | 
| 
       70 
70 
     | 
    
         
             
                  #
         
     | 
| 
       71 
71 
     | 
    
         
             
                  #   # okay with `^assert` listed in `AllowedPatterns`
         
     | 
| 
         @@ -197,7 +197,7 @@ module RuboCop 
     | 
|
| 
       197 
197 
     | 
    
         
             
                    require_relative 'method_call_with_args_parentheses/require_parentheses'
         
     | 
| 
       198 
198 
     | 
    
         | 
| 
       199 
199 
     | 
    
         
             
                    include ConfigurableEnforcedStyle
         
     | 
| 
       200 
     | 
    
         
            -
                    include  
     | 
| 
      
 200 
     | 
    
         
            +
                    include AllowedMethods
         
     | 
| 
       201 
201 
     | 
    
         
             
                    include AllowedPattern
         
     | 
| 
       202 
202 
     | 
    
         
             
                    include RequireParentheses
         
     | 
| 
       203 
203 
     | 
    
         
             
                    include OmitParentheses
         
     | 
| 
         @@ -5,8 +5,8 @@ module RuboCop 
     | 
|
| 
       5 
5 
     | 
    
         
             
                module Style
         
     | 
| 
       6 
6 
     | 
    
         
             
                  # Checks for unwanted parentheses in parameterless method calls.
         
     | 
| 
       7 
7 
     | 
    
         
             
                  #
         
     | 
| 
       8 
     | 
    
         
            -
                  # This cop can be customized  
     | 
| 
       9 
     | 
    
         
            -
                  # By default, there are no methods to  
     | 
| 
      
 8 
     | 
    
         
            +
                  # This cop can be customized allowed methods with `AllowedMethods`.
         
     | 
| 
      
 9 
     | 
    
         
            +
                  # By default, there are no methods to allowed.
         
     | 
| 
       10 
10 
     | 
    
         
             
                  #
         
     | 
| 
       11 
11 
     | 
    
         
             
                  # @example
         
     | 
| 
       12 
12 
     | 
    
         
             
                  #   # bad
         
     | 
| 
         @@ -15,16 +15,17 @@ module RuboCop 
     | 
|
| 
       15 
15 
     | 
    
         
             
                  #   # good
         
     | 
| 
       16 
16 
     | 
    
         
             
                  #   object.some_method
         
     | 
| 
       17 
17 
     | 
    
         
             
                  #
         
     | 
| 
       18 
     | 
    
         
            -
                  # @example  
     | 
| 
      
 18 
     | 
    
         
            +
                  # @example AllowedMethods: [] (default)
         
     | 
| 
       19 
19 
     | 
    
         
             
                  #   # bad
         
     | 
| 
       20 
20 
     | 
    
         
             
                  #   object.foo()
         
     | 
| 
       21 
21 
     | 
    
         
             
                  #
         
     | 
| 
       22 
     | 
    
         
            -
                  # @example  
     | 
| 
      
 22 
     | 
    
         
            +
                  # @example AllowedMethods: [foo]
         
     | 
| 
       23 
23 
     | 
    
         
             
                  #   # good
         
     | 
| 
       24 
24 
     | 
    
         
             
                  #   object.foo()
         
     | 
| 
       25 
25 
     | 
    
         
             
                  #
         
     | 
| 
       26 
26 
     | 
    
         
             
                  class MethodCallWithoutArgsParentheses < Base
         
     | 
| 
       27 
     | 
    
         
            -
                    include  
     | 
| 
      
 27 
     | 
    
         
            +
                    include AllowedMethods
         
     | 
| 
      
 28 
     | 
    
         
            +
                    include AllowedPattern
         
     | 
| 
       28 
29 
     | 
    
         
             
                    extend AutoCorrector
         
     | 
| 
       29 
30 
     | 
    
         | 
| 
       30 
31 
     | 
    
         
             
                    MSG = 'Do not use parentheses for method calls with no arguments.'
         
     | 
| 
         @@ -33,7 +34,7 @@ module RuboCop 
     | 
|
| 
       33 
34 
     | 
    
         
             
                      return unless !node.arguments? && node.parenthesized?
         
     | 
| 
       34 
35 
     | 
    
         
             
                      return if ineligible_node?(node)
         
     | 
| 
       35 
36 
     | 
    
         
             
                      return if default_argument?(node)
         
     | 
| 
       36 
     | 
    
         
            -
                      return if  
     | 
| 
      
 37 
     | 
    
         
            +
                      return if allowed_method_name?(node.method_name)
         
     | 
| 
       37 
38 
     | 
    
         
             
                      return if same_name_assignment?(node)
         
     | 
| 
       38 
39 
     | 
    
         | 
| 
       39 
40 
     | 
    
         
             
                      register_offense(node)
         
     | 
| 
         @@ -56,6 +57,10 @@ module RuboCop 
     | 
|
| 
       56 
57 
     | 
    
         
             
                      node.parent&.optarg_type?
         
     | 
| 
       57 
58 
     | 
    
         
             
                    end
         
     | 
| 
       58 
59 
     | 
    
         | 
| 
      
 60 
     | 
    
         
            +
                    def allowed_method_name?(name)
         
     | 
| 
      
 61 
     | 
    
         
            +
                      allowed_method?(name) || matches_allowed_pattern?(name)
         
     | 
| 
      
 62 
     | 
    
         
            +
                    end
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
       59 
64 
     | 
    
         
             
                    def same_name_assignment?(node)
         
     | 
| 
       60 
65 
     | 
    
         
             
                      any_assignment?(node) do |asgn_node|
         
     | 
| 
       61 
66 
     | 
    
         
             
                        next variable_in_mass_assignment?(node.method_name, asgn_node) if asgn_node.masgn_type?
         
     | 
| 
         @@ -35,12 +35,15 @@ module RuboCop 
     | 
|
| 
       35 
35 
     | 
    
         
             
                      ignore_node(node.send_node)
         
     | 
| 
       36 
36 
     | 
    
         
             
                    end
         
     | 
| 
       37 
37 
     | 
    
         | 
| 
      
 38 
     | 
    
         
            +
                    alias on_numblock on_block
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
       38 
40 
     | 
    
         
             
                    def on_send(node)
         
     | 
| 
       39 
41 
     | 
    
         
             
                      return if ignored_node?(node)
         
     | 
| 
       40 
42 
     | 
    
         | 
| 
       41 
43 
     | 
    
         
             
                      receiver = node.receiver
         
     | 
| 
       42 
44 
     | 
    
         | 
| 
       43 
     | 
    
         
            -
                      return unless receiver&.block_type?  
     | 
| 
      
 45 
     | 
    
         
            +
                      return unless (receiver&.block_type? || receiver&.numblock_type?) &&
         
     | 
| 
      
 46 
     | 
    
         
            +
                                    receiver.loc.end.is?('end')
         
     | 
| 
       44 
47 
     | 
    
         | 
| 
       45 
48 
     | 
    
         
             
                      range = range_between(receiver.loc.end.begin_pos, node.source_range.end_pos)
         
     | 
| 
       46 
49 
     | 
    
         | 
| 
         @@ -31,7 +31,7 @@ module RuboCop 
     | 
|
| 
       31 
31 
     | 
    
         
             
                      node.send_node.each_node(:send) do |send_node|
         
     | 
| 
       32 
32 
     | 
    
         
             
                        receiver = send_node.receiver
         
     | 
| 
       33 
33 
     | 
    
         | 
| 
       34 
     | 
    
         
            -
                        next unless receiver&.block_type? && receiver&.multiline?
         
     | 
| 
      
 34 
     | 
    
         
            +
                        next unless (receiver&.block_type? || receiver&.numblock_type?) && receiver&.multiline?
         
     | 
| 
       35 
35 
     | 
    
         | 
| 
       36 
36 
     | 
    
         
             
                        range = range_between(receiver.loc.end.begin_pos, node.send_node.source_range.end_pos)
         
     | 
| 
       37 
37 
     | 
    
         | 
| 
         @@ -42,6 +42,8 @@ module RuboCop 
     | 
|
| 
       42 
42 
     | 
    
         
             
                        break
         
     | 
| 
       43 
43 
     | 
    
         
             
                      end
         
     | 
| 
       44 
44 
     | 
    
         
             
                    end
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
                    alias on_numblock on_block
         
     | 
| 
       45 
47 
     | 
    
         
             
                  end
         
     | 
| 
       46 
48 
     | 
    
         
             
                end
         
     | 
| 
       47 
49 
     | 
    
         
             
              end
         
     | 
| 
         @@ -49,7 +49,7 @@ module RuboCop 
     | 
|
| 
       49 
49 
     | 
    
         | 
| 
       50 
50 
     | 
    
         
             
                    # Requires `then` for write `in` and its body on the same line.
         
     | 
| 
       51 
51 
     | 
    
         
             
                    def require_then?(in_pattern_node)
         
     | 
| 
       52 
     | 
    
         
            -
                      return true  
     | 
| 
      
 52 
     | 
    
         
            +
                      return true unless in_pattern_node.pattern.single_line?
         
     | 
| 
       53 
53 
     | 
    
         
             
                      return false unless in_pattern_node.body
         
     | 
| 
       54 
54 
     | 
    
         | 
| 
       55 
55 
     | 
    
         
             
                      same_line?(in_pattern_node, in_pattern_node.body)
         
     | 
| 
         @@ -49,7 +49,8 @@ module RuboCop 
     | 
|
| 
       49 
49 
     | 
    
         
             
                    def on_if(node)
         
     | 
| 
       50 
50 
     | 
    
         
             
                      return unless if_else?(node)
         
     | 
| 
       51 
51 
     | 
    
         | 
| 
       52 
     | 
    
         
            -
                      condition = node.condition
         
     | 
| 
      
 52 
     | 
    
         
            +
                      condition = unwrap_begin_nodes(node.condition)
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
       53 
54 
     | 
    
         
             
                      return if double_negation?(condition) || !negated_condition?(condition)
         
     | 
| 
       54 
55 
     | 
    
         | 
| 
       55 
56 
     | 
    
         
             
                      type = node.ternary? ? 'ternary' : 'if-else'
         
     | 
| 
         @@ -71,6 +72,11 @@ module RuboCop 
     | 
|
| 
       71 
72 
     | 
    
         
             
                      !node.elsif? && else_branch && (!else_branch.if_type? || !else_branch.elsif?)
         
     | 
| 
       72 
73 
     | 
    
         
             
                    end
         
     | 
| 
       73 
74 
     | 
    
         | 
| 
      
 75 
     | 
    
         
            +
                    def unwrap_begin_nodes(node)
         
     | 
| 
      
 76 
     | 
    
         
            +
                      node = node.children.first while node.begin_type? || node.kwbegin_type?
         
     | 
| 
      
 77 
     | 
    
         
            +
                      node
         
     | 
| 
      
 78 
     | 
    
         
            +
                    end
         
     | 
| 
      
 79 
     | 
    
         
            +
             
     | 
| 
       74 
80 
     | 
    
         
             
                    def negated_condition?(node)
         
     | 
| 
       75 
81 
     | 
    
         
             
                      node.send_type? &&
         
     | 
| 
       76 
82 
     | 
    
         
             
                        (node.negation_method? || NEGATED_EQUALITY_METHODS.include?(node.method_name))
         
     | 
| 
         @@ -71,6 +71,8 @@ module RuboCop 
     | 
|
| 
       71 
71 
     | 
    
         
             
                      check(node)
         
     | 
| 
       72 
72 
     | 
    
         
             
                    end
         
     | 
| 
       73 
73 
     | 
    
         | 
| 
      
 74 
     | 
    
         
            +
                    alias on_numblock on_block
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
       74 
76 
     | 
    
         
             
                    def on_while(node)
         
     | 
| 
       75 
77 
     | 
    
         
             
                      check(node)
         
     | 
| 
       76 
78 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -223,11 +225,7 @@ module RuboCop 
     | 
|
| 
       223 
225 
     | 
    
         
             
                      adjustment = delta + @reindented_lines[lineno]
         
     | 
| 
       224 
226 
     | 
    
         
             
                      @reindented_lines[lineno] = adjustment
         
     | 
| 
       225 
227 
     | 
    
         | 
| 
       226 
     | 
    
         
            -
                      if adjustment.positive?
         
     | 
| 
       227 
     | 
    
         
            -
                        corrector.remove_leading(buffer.line_range(lineno), adjustment)
         
     | 
| 
       228 
     | 
    
         
            -
                      elsif adjustment.negative?
         
     | 
| 
       229 
     | 
    
         
            -
                        corrector.insert_before(buffer.line_range(lineno), ' ' * -adjustment)
         
     | 
| 
       230 
     | 
    
         
            -
                      end
         
     | 
| 
      
 228 
     | 
    
         
            +
                      corrector.remove_leading(buffer.line_range(lineno), adjustment) if adjustment.positive?
         
     | 
| 
       231 
229 
     | 
    
         
             
                    end
         
     | 
| 
       232 
230 
     | 
    
         
             
                  end
         
     | 
| 
       233 
231 
     | 
    
         
             
                end
         
     | 
| 
         @@ -3,9 +3,17 @@ 
     | 
|
| 
       3 
3 
     | 
    
         
             
            module RuboCop
         
     | 
| 
       4 
4 
     | 
    
         
             
              module Cop
         
     | 
| 
       5 
5 
     | 
    
         
             
                module Style
         
     | 
| 
       6 
     | 
    
         
            -
                  # Checks for big numeric literals without _ between groups
         
     | 
| 
      
 6 
     | 
    
         
            +
                  # Checks for big numeric literals without `_` between groups
         
     | 
| 
       7 
7 
     | 
    
         
             
                  # of digits in them.
         
     | 
| 
       8 
8 
     | 
    
         
             
                  #
         
     | 
| 
      
 9 
     | 
    
         
            +
                  # Additional allowed patterns can be added by adding regexps to
         
     | 
| 
      
 10 
     | 
    
         
            +
                  # the `AllowedPatterns` configuration. All regexps are treated
         
     | 
| 
      
 11 
     | 
    
         
            +
                  # as anchored even if the patterns do not contain anchors (so
         
     | 
| 
      
 12 
     | 
    
         
            +
                  # `\d{4}_\d{4}` will allow `1234_5678` but not `1234_5678_9012`).
         
     | 
| 
      
 13 
     | 
    
         
            +
                  #
         
     | 
| 
      
 14 
     | 
    
         
            +
                  # NOTE: Even if `AllowedPatterns` are given, autocorrection will
         
     | 
| 
      
 15 
     | 
    
         
            +
                  # only correct to the standard pattern of an `_` every 3 digits.
         
     | 
| 
      
 16 
     | 
    
         
            +
                  #
         
     | 
| 
       9 
17 
     | 
    
         
             
                  # @example
         
     | 
| 
       10 
18 
     | 
    
         
             
                  #
         
     | 
| 
       11 
19 
     | 
    
         
             
                  #   # bad
         
     | 
| 
         @@ -34,6 +42,7 @@ module RuboCop 
     | 
|
| 
       34 
42 
     | 
    
         
             
                  #
         
     | 
| 
       35 
43 
     | 
    
         
             
                  class NumericLiterals < Base
         
     | 
| 
       36 
44 
     | 
    
         
             
                    include IntegerNode
         
     | 
| 
      
 45 
     | 
    
         
            +
                    include AllowedPattern
         
     | 
| 
       37 
46 
     | 
    
         
             
                    extend AutoCorrector
         
     | 
| 
       38 
47 
     | 
    
         | 
| 
       39 
48 
     | 
    
         
             
                    MSG = 'Use underscores(_) as thousands separator and separate every 3 digits with them.'
         
     | 
| 
         @@ -59,6 +68,7 @@ module RuboCop 
     | 
|
| 
       59 
68 
     | 
    
         
             
                      # TODO: handle non-decimal literals as well
         
     | 
| 
       60 
69 
     | 
    
         
             
                      return if int.start_with?('0')
         
     | 
| 
       61 
70 
     | 
    
         
             
                      return if allowed_numbers.include?(int)
         
     | 
| 
      
 71 
     | 
    
         
            +
                      return if matches_allowed_pattern?(int)
         
     | 
| 
       62 
72 
     | 
    
         
             
                      return unless int.size >= min_digits
         
     | 
| 
       63 
73 
     | 
    
         | 
| 
       64 
74 
     | 
    
         
             
                      case int
         
     | 
| 
         @@ -108,6 +118,11 @@ module RuboCop 
     | 
|
| 
       108 
118 
     | 
    
         
             
                    def allowed_numbers
         
     | 
| 
       109 
119 
     | 
    
         
             
                      cop_config.fetch('AllowedNumbers', []).map(&:to_s)
         
     | 
| 
       110 
120 
     | 
    
         
             
                    end
         
     | 
| 
      
 121 
     | 
    
         
            +
             
     | 
| 
      
 122 
     | 
    
         
            +
                    def allowed_patterns
         
     | 
| 
      
 123 
     | 
    
         
            +
                      # Convert the patterns to be anchored
         
     | 
| 
      
 124 
     | 
    
         
            +
                      super.map { |regexp| Regexp.new(/\A#{regexp}\z/) }
         
     | 
| 
      
 125 
     | 
    
         
            +
                    end
         
     | 
| 
       111 
126 
     | 
    
         
             
                  end
         
     | 
| 
       112 
127 
     | 
    
         
             
                end
         
     | 
| 
       113 
128 
     | 
    
         
             
              end
         
     |