rubocop 0.57.2 → 0.58.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 +12 -9
 - data/bin/setup +7 -0
 - data/config/default.yml +18 -2
 - data/config/disabled.yml +4 -0
 - data/lib/rubocop.rb +1 -0
 - data/lib/rubocop/ast/node.rb +5 -0
 - data/lib/rubocop/ast/node/str_node.rb +2 -0
 - data/lib/rubocop/cli.rb +4 -7
 - data/lib/rubocop/config.rb +4 -4
 - data/lib/rubocop/config_loader.rb +4 -8
 - data/lib/rubocop/cop/corrector.rb +25 -0
 - data/lib/rubocop/cop/layout/closing_heredoc_indentation.rb +3 -7
 - data/lib/rubocop/cop/layout/end_alignment.rb +1 -1
 - data/lib/rubocop/cop/layout/indentation_width.rb +9 -1
 - data/lib/rubocop/cop/layout/leading_blank_lines.rb +1 -1
 - data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +28 -51
 - data/lib/rubocop/cop/lint/redundant_with_object.rb +1 -1
 - data/lib/rubocop/cop/lint/shadowed_argument.rb +7 -3
 - data/lib/rubocop/cop/lint/unneeded_splat_expansion.rb +1 -1
 - data/lib/rubocop/cop/lint/useless_access_modifier.rb +17 -4
 - data/lib/rubocop/cop/metrics/line_length.rb +28 -6
 - data/lib/rubocop/cop/mixin/check_assignment.rb +0 -2
 - data/lib/rubocop/cop/mixin/statement_modifier.rb +6 -1
 - data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +79 -4
 - data/lib/rubocop/cop/performance/inefficient_hash_search.rb +9 -5
 - data/lib/rubocop/cop/performance/range_include.rb +9 -3
 - data/lib/rubocop/cop/performance/sample.rb +6 -4
 - data/lib/rubocop/cop/rails/bulk_change_table.rb +11 -7
 - data/lib/rubocop/cop/rails/create_table_with_timestamps.rb +3 -1
 - data/lib/rubocop/cop/registry.rb +11 -2
 - data/lib/rubocop/cop/style/encoding.rb +5 -0
 - data/lib/rubocop/cop/style/end_block.rb +8 -0
 - data/lib/rubocop/cop/style/if_unless_modifier.rb +2 -1
 - data/lib/rubocop/cop/style/ip_addresses.rb +76 -0
 - data/lib/rubocop/cop/style/multiple_comparison.rb +16 -2
 - data/lib/rubocop/cop/style/symbol_proc.rb +4 -2
 - data/lib/rubocop/cop/style/unneeded_condition.rb +19 -2
 - data/lib/rubocop/formatter/disabled_config_formatter.rb +3 -3
 - data/lib/rubocop/options.rb +20 -12
 - data/lib/rubocop/processed_source.rb +2 -5
 - data/lib/rubocop/rspec/cop_helper.rb +0 -4
 - data/lib/rubocop/rspec/shared_contexts.rb +0 -4
 - data/lib/rubocop/rspec/shared_examples.rb +0 -23
 - data/lib/rubocop/version.rb +1 -1
 - metadata +7 -11
 
| 
         @@ -59,7 +59,9 @@ module RuboCop 
     | 
|
| 
       59 
59 
     | 
    
         
             
                    PATTERN
         
     | 
| 
       60 
60 
     | 
    
         | 
| 
       61 
61 
     | 
    
         
             
                    def_node_search :created_at_or_updated_at_included?, <<-PATTERN
         
     | 
| 
       62 
     | 
    
         
            -
                      (send _var :datetime 
     | 
| 
      
 62 
     | 
    
         
            +
                      (send _var :datetime
         
     | 
| 
      
 63 
     | 
    
         
            +
                        {(sym {:created_at :updated_at})(str {"created_at" "updated_at"})}
         
     | 
| 
      
 64 
     | 
    
         
            +
                        ...)
         
     | 
| 
       63 
65 
     | 
    
         
             
                    PATTERN
         
     | 
| 
       64 
66 
     | 
    
         | 
| 
       65 
67 
     | 
    
         
             
                    def on_send(node)
         
     | 
    
        data/lib/rubocop/cop/registry.rb
    CHANGED
    
    | 
         @@ -23,8 +23,9 @@ module RuboCop 
     | 
|
| 
       23 
23 
     | 
    
         
             
                # Registry that tracks all cops by their badge and department.
         
     | 
| 
       24 
24 
     | 
    
         
             
                class Registry
         
     | 
| 
       25 
25 
     | 
    
         
             
                  def initialize(cops = [])
         
     | 
| 
       26 
     | 
    
         
            -
                    @registry 
     | 
| 
      
 26 
     | 
    
         
            +
                    @registry = {}
         
     | 
| 
       27 
27 
     | 
    
         
             
                    @departments = {}
         
     | 
| 
      
 28 
     | 
    
         
            +
                    @cops_by_cop_name = Hash.new { |hash, key| hash[key] = [] }
         
     | 
| 
       28 
29 
     | 
    
         | 
| 
       29 
30 
     | 
    
         
             
                    cops.each { |cop| enlist(cop) }
         
     | 
| 
       30 
31 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -33,6 +34,7 @@ module RuboCop 
     | 
|
| 
       33 
34 
     | 
    
         
             
                    @registry[cop.badge] = cop
         
     | 
| 
       34 
35 
     | 
    
         
             
                    @departments[cop.department] ||= []
         
     | 
| 
       35 
36 
     | 
    
         
             
                    @departments[cop.department] << cop
         
     | 
| 
      
 37 
     | 
    
         
            +
                    @cops_by_cop_name[cop.cop_name] << cop
         
     | 
| 
       36 
38 
     | 
    
         
             
                  end
         
     | 
| 
       37 
39 
     | 
    
         | 
| 
       38 
40 
     | 
    
         
             
                  # @return [Array<Symbol>] list of departments for current cops.
         
     | 
| 
         @@ -102,8 +104,9 @@ module RuboCop 
     | 
|
| 
       102 
104 
     | 
    
         
             
                    end
         
     | 
| 
       103 
105 
     | 
    
         
             
                  end
         
     | 
| 
       104 
106 
     | 
    
         | 
| 
      
 107 
     | 
    
         
            +
                  # @return [Hash{String => Array<Class>}]
         
     | 
| 
       105 
108 
     | 
    
         
             
                  def to_h
         
     | 
| 
       106 
     | 
    
         
            -
                     
     | 
| 
      
 109 
     | 
    
         
            +
                    @cops_by_cop_name
         
     | 
| 
       107 
110 
     | 
    
         
             
                  end
         
     | 
| 
       108 
111 
     | 
    
         | 
| 
       109 
112 
     | 
    
         
             
                  def cops
         
     | 
| 
         @@ -142,6 +145,12 @@ module RuboCop 
     | 
|
| 
       142 
145 
     | 
    
         
             
                    cops.each(&block)
         
     | 
| 
       143 
146 
     | 
    
         
             
                  end
         
     | 
| 
       144 
147 
     | 
    
         | 
| 
      
 148 
     | 
    
         
            +
                  # @param [String] cop_name
         
     | 
| 
      
 149 
     | 
    
         
            +
                  # @return [Class, nil]
         
     | 
| 
      
 150 
     | 
    
         
            +
                  def find_by_cop_name(cop_name)
         
     | 
| 
      
 151 
     | 
    
         
            +
                    @cops_by_cop_name[cop_name].first
         
     | 
| 
      
 152 
     | 
    
         
            +
                  end
         
     | 
| 
      
 153 
     | 
    
         
            +
             
     | 
| 
       145 
154 
     | 
    
         
             
                  private
         
     | 
| 
       146 
155 
     | 
    
         | 
| 
       147 
156 
     | 
    
         
             
                  def with(cops)
         
     | 
| 
         @@ -4,6 +4,14 @@ module RuboCop 
     | 
|
| 
       4 
4 
     | 
    
         
             
              module Cop
         
     | 
| 
       5 
5 
     | 
    
         
             
                module Style
         
     | 
| 
       6 
6 
     | 
    
         
             
                  # This cop checks for END blocks.
         
     | 
| 
      
 7 
     | 
    
         
            +
                  #
         
     | 
| 
      
 8 
     | 
    
         
            +
                  # @example
         
     | 
| 
      
 9 
     | 
    
         
            +
                  #   # bad
         
     | 
| 
      
 10 
     | 
    
         
            +
                  #   END { puts 'Goodbye!' }
         
     | 
| 
      
 11 
     | 
    
         
            +
                  #
         
     | 
| 
      
 12 
     | 
    
         
            +
                  #   # good
         
     | 
| 
      
 13 
     | 
    
         
            +
                  #   at_exit { puts 'Goodbye!' }
         
     | 
| 
      
 14 
     | 
    
         
            +
                  #
         
     | 
| 
       7 
15 
     | 
    
         
             
                  class EndBlock < Cop
         
     | 
| 
       8 
16 
     | 
    
         
             
                    MSG = 'Avoid the use of `END` blocks. ' \
         
     | 
| 
       9 
17 
     | 
    
         
             
                          'Use `Kernel#at_exit` instead.'.freeze
         
     | 
| 
         @@ -5,7 +5,8 @@ module RuboCop 
     | 
|
| 
       5 
5 
     | 
    
         
             
                module Style
         
     | 
| 
       6 
6 
     | 
    
         
             
                  # Checks for if and unless statements that would fit on one line
         
     | 
| 
       7 
7 
     | 
    
         
             
                  # if written as a modifier if/unless. The maximum line length is
         
     | 
| 
       8 
     | 
    
         
            -
                  # configured in the `Metrics/LineLength` cop.
         
     | 
| 
      
 8 
     | 
    
         
            +
                  # configured in the `Metrics/LineLength` cop. The tab size is configured
         
     | 
| 
      
 9 
     | 
    
         
            +
                  # in the `IndentationWidth` of the `Layout/Tab` cop.
         
     | 
| 
       9 
10 
     | 
    
         
             
                  #
         
     | 
| 
       10 
11 
     | 
    
         
             
                  # @example
         
     | 
| 
       11 
12 
     | 
    
         
             
                  #   # bad
         
     | 
| 
         @@ -0,0 +1,76 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require 'resolv'
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            module RuboCop
         
     | 
| 
      
 6 
     | 
    
         
            +
              module Cop
         
     | 
| 
      
 7 
     | 
    
         
            +
                module Style
         
     | 
| 
      
 8 
     | 
    
         
            +
                  # This cop checks for hardcoded IP addresses, which can make code
         
     | 
| 
      
 9 
     | 
    
         
            +
                  # brittle. IP addresses are likely to need to be changed when code
         
     | 
| 
      
 10 
     | 
    
         
            +
                  # is deployed to a different server or environment, which may break
         
     | 
| 
      
 11 
     | 
    
         
            +
                  # a deployment if forgotten. Prefer setting IP addresses in ENV or
         
     | 
| 
      
 12 
     | 
    
         
            +
                  # other configuration.
         
     | 
| 
      
 13 
     | 
    
         
            +
                  #
         
     | 
| 
      
 14 
     | 
    
         
            +
                  # @example
         
     | 
| 
      
 15 
     | 
    
         
            +
                  #
         
     | 
| 
      
 16 
     | 
    
         
            +
                  #   # bad
         
     | 
| 
      
 17 
     | 
    
         
            +
                  #   ip_address = '127.59.241.29'
         
     | 
| 
      
 18 
     | 
    
         
            +
                  #
         
     | 
| 
      
 19 
     | 
    
         
            +
                  #   # good
         
     | 
| 
      
 20 
     | 
    
         
            +
                  #   ip_address = ENV['DEPLOYMENT_IP_ADDRESS']
         
     | 
| 
      
 21 
     | 
    
         
            +
                  class IpAddresses < Cop
         
     | 
| 
      
 22 
     | 
    
         
            +
                    include StringHelp
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                    IPV6_MAX_SIZE = 45 # IPv4-mapped IPv6 is the longest
         
     | 
| 
      
 25 
     | 
    
         
            +
                    MSG = 'Do not hardcode IP addresses.'.freeze
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                    def offense?(node)
         
     | 
| 
      
 28 
     | 
    
         
            +
                      contents = node.source[1...-1]
         
     | 
| 
      
 29 
     | 
    
         
            +
                      return false if contents.empty?
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                      return false if whitelist.include?(contents.downcase)
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                      # To try to avoid doing two regex checks on every string,
         
     | 
| 
      
 34 
     | 
    
         
            +
                      # shortcut out if the string does not look like an IP address
         
     | 
| 
      
 35 
     | 
    
         
            +
                      return false unless could_be_ip?(contents)
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                      contents =~ ::Resolv::IPv4::Regex || contents =~ ::Resolv::IPv6::Regex
         
     | 
| 
      
 38 
     | 
    
         
            +
                    end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                    # Dummy implementation of method in ConfigurableEnforcedStyle that is
         
     | 
| 
      
 41 
     | 
    
         
            +
                    # called from StringHelp.
         
     | 
| 
      
 42 
     | 
    
         
            +
                    def opposite_style_detected; end
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                    # Dummy implementation of method in ConfigurableEnforcedStyle that is
         
     | 
| 
      
 45 
     | 
    
         
            +
                    # called from StringHelp.
         
     | 
| 
      
 46 
     | 
    
         
            +
                    def correct_style_detected; end
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
                    private
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
                    def whitelist
         
     | 
| 
      
 51 
     | 
    
         
            +
                      whitelist = cop_config['Whitelist']
         
     | 
| 
      
 52 
     | 
    
         
            +
                      Array(whitelist).map(&:downcase)
         
     | 
| 
      
 53 
     | 
    
         
            +
                    end
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
                    def could_be_ip?(str)
         
     | 
| 
      
 56 
     | 
    
         
            +
                      # If the string is too long, it can't be an IP
         
     | 
| 
      
 57 
     | 
    
         
            +
                      return false if too_long?(str)
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
                      # If the string doesn't start with a colon or hexadecimal char,
         
     | 
| 
      
 60 
     | 
    
         
            +
                      # we know it's not an IP address
         
     | 
| 
      
 61 
     | 
    
         
            +
                      starts_with_hex_or_colon?(str)
         
     | 
| 
      
 62 
     | 
    
         
            +
                    end
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
                    def too_long?(str)
         
     | 
| 
      
 65 
     | 
    
         
            +
                      str.size > IPV6_MAX_SIZE
         
     | 
| 
      
 66 
     | 
    
         
            +
                    end
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
                    def starts_with_hex_or_colon?(str)
         
     | 
| 
      
 69 
     | 
    
         
            +
                      first_char = str[0].ord
         
     | 
| 
      
 70 
     | 
    
         
            +
                      (48..58).cover?(first_char) || (65..70).cover?(first_char) ||
         
     | 
| 
      
 71 
     | 
    
         
            +
                        (97..102).cover?(first_char)
         
     | 
| 
      
 72 
     | 
    
         
            +
                    end
         
     | 
| 
      
 73 
     | 
    
         
            +
                  end
         
     | 
| 
      
 74 
     | 
    
         
            +
                end
         
     | 
| 
      
 75 
     | 
    
         
            +
              end
         
     | 
| 
      
 76 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -18,8 +18,12 @@ module RuboCop 
     | 
|
| 
       18 
18 
     | 
    
         
             
                    MSG = 'Avoid comparing a variable with multiple items ' \
         
     | 
| 
       19 
19 
     | 
    
         
             
                      'in a conditional, use `Array#include?` instead.'.freeze
         
     | 
| 
       20 
20 
     | 
    
         | 
| 
       21 
     | 
    
         
            -
                    def  
     | 
| 
       22 
     | 
    
         
            -
                       
     | 
| 
      
 21 
     | 
    
         
            +
                    def on_or(node)
         
     | 
| 
      
 22 
     | 
    
         
            +
                      root_of_or_node = root_of_or_node(node)
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                      return unless node == root_of_or_node
         
     | 
| 
      
 25 
     | 
    
         
            +
                      return unless nested_variable_comparison?(root_of_or_node)
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
       23 
27 
     | 
    
         
             
                      add_offense(node)
         
     | 
| 
       24 
28 
     | 
    
         
             
                    end
         
     | 
| 
       25 
29 
     | 
    
         | 
| 
         @@ -71,6 +75,16 @@ module RuboCop 
     | 
|
| 
       71 
75 
     | 
    
         
             
                    def comparison?(node)
         
     | 
| 
       72 
76 
     | 
    
         
             
                      simple_comparison?(node) || nested_comparison?(node)
         
     | 
| 
       73 
77 
     | 
    
         
             
                    end
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
                    def root_of_or_node(or_node)
         
     | 
| 
      
 80 
     | 
    
         
            +
                      return or_node unless or_node.parent
         
     | 
| 
      
 81 
     | 
    
         
            +
             
     | 
| 
      
 82 
     | 
    
         
            +
                      if or_node.parent.or_type?
         
     | 
| 
      
 83 
     | 
    
         
            +
                        root_of_or_node(or_node.parent)
         
     | 
| 
      
 84 
     | 
    
         
            +
                      else
         
     | 
| 
      
 85 
     | 
    
         
            +
                        or_node
         
     | 
| 
      
 86 
     | 
    
         
            +
                      end
         
     | 
| 
      
 87 
     | 
    
         
            +
                    end
         
     | 
| 
       74 
88 
     | 
    
         
             
                  end
         
     | 
| 
       75 
89 
     | 
    
         
             
                end
         
     | 
| 
       76 
90 
     | 
    
         
             
              end
         
     | 
| 
         @@ -22,7 +22,7 @@ module RuboCop 
     | 
|
| 
       22 
22 
     | 
    
         
             
                    def_node_matcher :symbol_proc?, <<-PATTERN
         
     | 
| 
       23 
23 
     | 
    
         
             
                      (block
         
     | 
| 
       24 
24 
     | 
    
         
             
                        ${(send ...) (super ...) zsuper}
         
     | 
| 
       25 
     | 
    
         
            -
                        (args (arg _var))
         
     | 
| 
      
 25 
     | 
    
         
            +
                        $(args (arg _var))
         
     | 
| 
       26 
26 
     | 
    
         
             
                        (send (lvar _var) $_))
         
     | 
| 
       27 
27 
     | 
    
         
             
                    PATTERN
         
     | 
| 
       28 
28 
     | 
    
         | 
| 
         @@ -31,7 +31,7 @@ module RuboCop 
     | 
|
| 
       31 
31 
     | 
    
         
             
                    end
         
     | 
| 
       32 
32 
     | 
    
         | 
| 
       33 
33 
     | 
    
         
             
                    def on_block(node)
         
     | 
| 
       34 
     | 
    
         
            -
                      symbol_proc?(node) do |send_or_super, method|
         
     | 
| 
      
 34 
     | 
    
         
            +
                      symbol_proc?(node) do |send_or_super, block_args, method|
         
     | 
| 
       35 
35 
     | 
    
         
             
                        block_method_name = resolve_block_method_name(send_or_super)
         
     | 
| 
       36 
36 
     | 
    
         | 
| 
       37 
37 
     | 
    
         
             
                        # TODO: Rails-specific handling that we should probably make
         
     | 
| 
         @@ -40,6 +40,8 @@ module RuboCop 
     | 
|
| 
       40 
40 
     | 
    
         
             
                        return if proc_node?(send_or_super)
         
     | 
| 
       41 
41 
     | 
    
         
             
                        return if %i[lambda proc].include?(block_method_name)
         
     | 
| 
       42 
42 
     | 
    
         
             
                        return if ignored_method?(block_method_name)
         
     | 
| 
      
 43 
     | 
    
         
            +
                        return if block_args.children.size == 1 &&
         
     | 
| 
      
 44 
     | 
    
         
            +
                                  block_args.source.include?(',')
         
     | 
| 
       43 
45 
     | 
    
         | 
| 
       44 
46 
     | 
    
         
             
                        offense(node, method, block_method_name)
         
     | 
| 
       45 
47 
     | 
    
         
             
                      end
         
     | 
| 
         @@ -34,9 +34,12 @@ module RuboCop 
     | 
|
| 
       34 
34 
     | 
    
         
             
                    include RangeHelp
         
     | 
| 
       35 
35 
     | 
    
         | 
| 
       36 
36 
     | 
    
         
             
                    MSG = 'Use double pipes `||` instead.'.freeze
         
     | 
| 
      
 37 
     | 
    
         
            +
                    UNNEEDED_CONDITION = 'This condition is not needed.'.freeze
         
     | 
| 
       37 
38 
     | 
    
         | 
| 
       38 
39 
     | 
    
         
             
                    def on_if(node)
         
     | 
| 
      
 40 
     | 
    
         
            +
                      return if node.elsif_conditional?
         
     | 
| 
       39 
41 
     | 
    
         
             
                      return unless offense?(node)
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
       40 
43 
     | 
    
         
             
                      add_offense(node, location: range_of_offense(node))
         
     | 
| 
       41 
44 
     | 
    
         
             
                    end
         
     | 
| 
       42 
45 
     | 
    
         | 
| 
         @@ -44,6 +47,8 @@ module RuboCop 
     | 
|
| 
       44 
47 
     | 
    
         
             
                      lambda do |corrector|
         
     | 
| 
       45 
48 
     | 
    
         
             
                        if node.ternary?
         
     | 
| 
       46 
49 
     | 
    
         
             
                          corrector.replace(range_of_offense(node), '||')
         
     | 
| 
      
 50 
     | 
    
         
            +
                        elsif node.modifier_form?
         
     | 
| 
      
 51 
     | 
    
         
            +
                          corrector.replace(node.source_range, node.if_branch.source)
         
     | 
| 
       47 
52 
     | 
    
         
             
                        else
         
     | 
| 
       48 
53 
     | 
    
         
             
                          corrected = [node.if_branch.source,
         
     | 
| 
       49 
54 
     | 
    
         
             
                                       else_source(node.else_branch)].join(' || ')
         
     | 
| 
         @@ -55,16 +60,24 @@ module RuboCop 
     | 
|
| 
       55 
60 
     | 
    
         | 
| 
       56 
61 
     | 
    
         
             
                    private
         
     | 
| 
       57 
62 
     | 
    
         | 
| 
      
 63 
     | 
    
         
            +
                    def message(node)
         
     | 
| 
      
 64 
     | 
    
         
            +
                      if node.modifier_form?
         
     | 
| 
      
 65 
     | 
    
         
            +
                        UNNEEDED_CONDITION
         
     | 
| 
      
 66 
     | 
    
         
            +
                      else
         
     | 
| 
      
 67 
     | 
    
         
            +
                        MSG
         
     | 
| 
      
 68 
     | 
    
         
            +
                      end
         
     | 
| 
      
 69 
     | 
    
         
            +
                    end
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
       58 
71 
     | 
    
         
             
                    def range_of_offense(node)
         
     | 
| 
       59 
72 
     | 
    
         
             
                      return :expression unless node.ternary?
         
     | 
| 
       60 
73 
     | 
    
         
             
                      range_between(node.loc.question.begin_pos, node.loc.colon.end_pos)
         
     | 
| 
       61 
74 
     | 
    
         
             
                    end
         
     | 
| 
       62 
75 
     | 
    
         | 
| 
       63 
76 
     | 
    
         
             
                    def offense?(node)
         
     | 
| 
       64 
     | 
    
         
            -
                      return false if node.elsif_conditional?
         
     | 
| 
       65 
     | 
    
         
            -
             
     | 
| 
       66 
77 
     | 
    
         
             
                      condition, if_branch, else_branch = *node
         
     | 
| 
       67 
78 
     | 
    
         | 
| 
      
 79 
     | 
    
         
            +
                      return false if use_if_branch?(else_branch)
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
       68 
81 
     | 
    
         
             
                      condition == if_branch && !node.elsif? && (
         
     | 
| 
       69 
82 
     | 
    
         
             
                        node.ternary? ||
         
     | 
| 
       70 
83 
     | 
    
         
             
                        !else_branch.instance_of?(AST::Node) ||
         
     | 
| 
         @@ -72,6 +85,10 @@ module RuboCop 
     | 
|
| 
       72 
85 
     | 
    
         
             
                      )
         
     | 
| 
       73 
86 
     | 
    
         
             
                    end
         
     | 
| 
       74 
87 
     | 
    
         | 
| 
      
 88 
     | 
    
         
            +
                    def use_if_branch?(else_branch)
         
     | 
| 
      
 89 
     | 
    
         
            +
                      else_branch && else_branch.if_type?
         
     | 
| 
      
 90 
     | 
    
         
            +
                    end
         
     | 
| 
      
 91 
     | 
    
         
            +
             
     | 
| 
       75 
92 
     | 
    
         
             
                    def else_source(else_branch)
         
     | 
| 
       76 
93 
     | 
    
         
             
                      wrap_else = MODIFIER_NODES.include?(else_branch.type) &&
         
     | 
| 
       77 
94 
     | 
    
         
             
                                  else_branch.modifier_form?
         
     | 
| 
         @@ -18,8 +18,6 @@ module RuboCop 
     | 
|
| 
       18 
18 
     | 
    
         
             
                  @config_to_allow_offenses = {}
         
     | 
| 
       19 
19 
     | 
    
         
             
                  @detected_styles = {}
         
     | 
| 
       20 
20 
     | 
    
         | 
| 
       21 
     | 
    
         
            -
                  COPS = Cop::Cop.registry.to_h
         
     | 
| 
       22 
     | 
    
         
            -
             
     | 
| 
       23 
21 
     | 
    
         
             
                  class << self
         
     | 
| 
       24 
22 
     | 
    
         
             
                    attr_accessor :config_to_allow_offenses, :detected_styles
         
     | 
| 
       25 
23 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -101,7 +99,9 @@ module RuboCop 
     | 
|
| 
       101 
99 
     | 
    
         
             
                    if @show_offense_counts
         
     | 
| 
       102 
100 
     | 
    
         
             
                      output_buffer.puts "# Offense count: #{offense_count}"
         
     | 
| 
       103 
101 
     | 
    
         
             
                    end
         
     | 
| 
       104 
     | 
    
         
            -
             
     | 
| 
      
 102 
     | 
    
         
            +
             
     | 
| 
      
 103 
     | 
    
         
            +
                    cop_class = Cop::Cop.registry.find_by_cop_name(cop_name)
         
     | 
| 
      
 104 
     | 
    
         
            +
                    if cop_class && cop_class.new.support_autocorrect?
         
     | 
| 
       105 
105 
     | 
    
         
             
                      output_buffer.puts '# Cop supports --auto-correct.'
         
     | 
| 
       106 
106 
     | 
    
         
             
                    end
         
     | 
| 
       107 
107 
     | 
    
         | 
    
        data/lib/rubocop/options.rb
    CHANGED
    
    | 
         @@ -5,6 +5,7 @@ require 'shellwords' 
     | 
|
| 
       5 
5 
     | 
    
         | 
| 
       6 
6 
     | 
    
         
             
            module RuboCop
         
     | 
| 
       7 
7 
     | 
    
         
             
              class IncorrectCopNameError < StandardError; end
         
     | 
| 
      
 8 
     | 
    
         
            +
              class OptionArgumentError < StandardError; end
         
     | 
| 
       8 
9 
     | 
    
         | 
| 
       9 
10 
     | 
    
         
             
              # This class handles command line options.
         
     | 
| 
       10 
11 
     | 
    
         
             
              class Options
         
     | 
| 
         @@ -26,7 +27,7 @@ module RuboCop 
     | 
|
| 
       26 
27 
     | 
    
         
             
                    # The parser has put the file name given after --stdin into
         
     | 
| 
       27 
28 
     | 
    
         
             
                    # @options[:stdin]. The args array should be empty.
         
     | 
| 
       28 
29 
     | 
    
         
             
                    if args.any?
         
     | 
| 
       29 
     | 
    
         
            -
                      raise  
     | 
| 
      
 30 
     | 
    
         
            +
                      raise OptionArgumentError, '-s/--stdin requires exactly one path.'
         
     | 
| 
       30 
31 
     | 
    
         
             
                    end
         
     | 
| 
       31 
32 
     | 
    
         
             
                    # We want the STDIN contents in @options[:stdin] and the file name in
         
     | 
| 
       32 
33 
     | 
    
         
             
                    # args to simplify the rest of the processing.
         
     | 
| 
         @@ -241,21 +242,21 @@ module RuboCop 
     | 
|
| 
       241 
242 
     | 
    
         | 
| 
       242 
243 
     | 
    
         
             
                def validate_compatibility # rubocop:disable Metrics/MethodLength
         
     | 
| 
       243 
244 
     | 
    
         
             
                  if only_includes_unneeded_disable?
         
     | 
| 
       244 
     | 
    
         
            -
                    raise  
     | 
| 
       245 
     | 
    
         
            -
             
     | 
| 
      
 245 
     | 
    
         
            +
                    raise OptionArgumentError, 'Lint/UnneededCopDisableDirective can not ' \
         
     | 
| 
      
 246 
     | 
    
         
            +
                                               'be used with --only.'
         
     | 
| 
       246 
247 
     | 
    
         
             
                  end
         
     | 
| 
       247 
248 
     | 
    
         
             
                  if except_syntax?
         
     | 
| 
       248 
     | 
    
         
            -
                    raise  
     | 
| 
      
 249 
     | 
    
         
            +
                    raise OptionArgumentError, 'Syntax checking can not be turned off.'
         
     | 
| 
       249 
250 
     | 
    
         
             
                  end
         
     | 
| 
       250 
251 
     | 
    
         
             
                  unless boolean_or_empty_cache?
         
     | 
| 
       251 
     | 
    
         
            -
                    raise  
     | 
| 
      
 252 
     | 
    
         
            +
                    raise OptionArgumentError, '-C/--cache argument must be true or false'
         
     | 
| 
       252 
253 
     | 
    
         
             
                  end
         
     | 
| 
       253 
254 
     | 
    
         
             
                  validate_auto_gen_config
         
     | 
| 
       254 
255 
     | 
    
         
             
                  validate_parallel
         
     | 
| 
       255 
256 
     | 
    
         | 
| 
       256 
257 
     | 
    
         
             
                  return if incompatible_options.size <= 1
         
     | 
| 
       257 
     | 
    
         
            -
                  raise  
     | 
| 
       258 
     | 
    
         
            -
             
     | 
| 
      
 258 
     | 
    
         
            +
                  raise OptionArgumentError, 'Incompatible cli options: ' \
         
     | 
| 
      
 259 
     | 
    
         
            +
                                             "#{incompatible_options.inspect}"
         
     | 
| 
       259 
260 
     | 
    
         
             
                end
         
     | 
| 
       260 
261 
     | 
    
         | 
| 
       261 
262 
     | 
    
         
             
                def validate_auto_gen_config
         
     | 
| 
         @@ -265,7 +266,8 @@ module RuboCop 
     | 
|
| 
       265 
266 
     | 
    
         | 
| 
       266 
267 
     | 
    
         
             
                  %i[exclude_limit no_offense_counts no_auto_gen_timestamp].each do |option|
         
     | 
| 
       267 
268 
     | 
    
         
             
                    if @options.key?(option)
         
     | 
| 
       268 
     | 
    
         
            -
                      raise  
     | 
| 
      
 269 
     | 
    
         
            +
                      raise OptionArgumentError,
         
     | 
| 
      
 270 
     | 
    
         
            +
                            format(message, flag: option.to_s.tr('_', '-'))
         
     | 
| 
       269 
271 
     | 
    
         
             
                    end
         
     | 
| 
       270 
272 
     | 
    
         
             
                  end
         
     | 
| 
       271 
273 
     | 
    
         
             
                end
         
     | 
| 
         @@ -274,11 +276,15 @@ module RuboCop 
     | 
|
| 
       274 
276 
     | 
    
         
             
                  return unless @options.key?(:parallel)
         
     | 
| 
       275 
277 
     | 
    
         | 
| 
       276 
278 
     | 
    
         
             
                  if @options[:cache] == 'false'
         
     | 
| 
       277 
     | 
    
         
            -
                    raise  
     | 
| 
       278 
     | 
    
         
            -
             
     | 
| 
       279 
     | 
    
         
            -
             
     | 
| 
      
 279 
     | 
    
         
            +
                    raise OptionArgumentError, '-P/--parallel uses caching to speed up ' \
         
     | 
| 
      
 280 
     | 
    
         
            +
                                               'execution, so combining with --cache ' \
         
     | 
| 
      
 281 
     | 
    
         
            +
                                               'false is not allowed.'
         
     | 
| 
       280 
282 
     | 
    
         
             
                  end
         
     | 
| 
       281 
283 
     | 
    
         | 
| 
      
 284 
     | 
    
         
            +
                  validate_parallel_with_combo_option
         
     | 
| 
      
 285 
     | 
    
         
            +
                end
         
     | 
| 
      
 286 
     | 
    
         
            +
             
     | 
| 
      
 287 
     | 
    
         
            +
                def validate_parallel_with_combo_option
         
     | 
| 
       282 
288 
     | 
    
         
             
                  combos = {
         
     | 
| 
       283 
289 
     | 
    
         
             
                    auto_gen_config: '-P/--parallel uses caching to speed up execution, ' \
         
     | 
| 
       284 
290 
     | 
    
         
             
                                     'while --auto-gen-config needs a non-cached run, ' \
         
     | 
| 
         @@ -287,7 +293,9 @@ module RuboCop 
     | 
|
| 
       287 
293 
     | 
    
         
             
                    auto_correct: '-P/--parallel can not be combined with --auto-correct.'
         
     | 
| 
       288 
294 
     | 
    
         
             
                  }
         
     | 
| 
       289 
295 
     | 
    
         | 
| 
       290 
     | 
    
         
            -
                  combos.each  
     | 
| 
      
 296 
     | 
    
         
            +
                  combos.each do |key, msg|
         
     | 
| 
      
 297 
     | 
    
         
            +
                    raise OptionArgumentError, msg if @options.key?(key)
         
     | 
| 
      
 298 
     | 
    
         
            +
                  end
         
     | 
| 
       291 
299 
     | 
    
         
             
                end
         
     | 
| 
       292 
300 
     | 
    
         | 
| 
       293 
301 
     | 
    
         
             
                def only_includes_unneeded_disable?
         
     | 
| 
         @@ -163,12 +163,9 @@ module RuboCop 
     | 
|
| 
       163 
163 
     | 
    
         
             
                  [ast, comments, tokens]
         
     | 
| 
       164 
164 
     | 
    
         
             
                end
         
     | 
| 
       165 
165 
     | 
    
         | 
| 
       166 
     | 
    
         
            -
                # rubocop:disable Metrics/ 
     | 
| 
      
 166 
     | 
    
         
            +
                # rubocop:disable Metrics/MethodLength
         
     | 
| 
       167 
167 
     | 
    
         
             
                def parser_class(ruby_version)
         
     | 
| 
       168 
168 
     | 
    
         
             
                  case ruby_version
         
     | 
| 
       169 
     | 
    
         
            -
                  when 2.1
         
     | 
| 
       170 
     | 
    
         
            -
                    require 'parser/ruby21'
         
     | 
| 
       171 
     | 
    
         
            -
                    Parser::Ruby21
         
     | 
| 
       172 
169 
     | 
    
         
             
                  when 2.2
         
     | 
| 
       173 
170 
     | 
    
         
             
                    require 'parser/ruby22'
         
     | 
| 
       174 
171 
     | 
    
         
             
                    Parser::Ruby22
         
     | 
| 
         @@ -188,7 +185,7 @@ module RuboCop 
     | 
|
| 
       188 
185 
     | 
    
         
             
                    raise ArgumentError, "Unknown Ruby version: #{ruby_version.inspect}"
         
     | 
| 
       189 
186 
     | 
    
         
             
                  end
         
     | 
| 
       190 
187 
     | 
    
         
             
                end
         
     | 
| 
       191 
     | 
    
         
            -
                # rubocop:enable Metrics/ 
     | 
| 
      
 188 
     | 
    
         
            +
                # rubocop:enable Metrics/MethodLength
         
     | 
| 
       192 
189 
     | 
    
         | 
| 
       193 
190 
     | 
    
         
             
                def create_parser(ruby_version)
         
     | 
| 
       194 
191 
     | 
    
         
             
                  builder = RuboCop::AST::Builder.new
         
     | 
| 
         @@ -14,10 +14,6 @@ module CopHelper 
     | 
|
| 
       14 
14 
     | 
    
         
             
                Tempfile.open('tmp') { |f| inspect_source(source, f) }
         
     | 
| 
       15 
15 
     | 
    
         
             
              end
         
     | 
| 
       16 
16 
     | 
    
         | 
| 
       17 
     | 
    
         
            -
              def inspect_gemfile(source)
         
     | 
| 
       18 
     | 
    
         
            -
                inspect_source(source, 'Gemfile')
         
     | 
| 
       19 
     | 
    
         
            -
              end
         
     | 
| 
       20 
     | 
    
         
            -
             
     | 
| 
       21 
17 
     | 
    
         
             
              def inspect_source(source, file = nil)
         
     | 
| 
       22 
18 
     | 
    
         
             
                if source.is_a?(Array) && source.size == 1
         
     | 
| 
       23 
19 
     | 
    
         
             
                  raise "Don't use an array for a single line of code: #{source}"
         
     | 
| 
         @@ -9,29 +9,6 @@ shared_examples_for 'accepts' do 
     | 
|
| 
       9 
9 
     | 
    
         
             
              end
         
     | 
| 
       10 
10 
     | 
    
         
             
            end
         
     | 
| 
       11 
11 
     | 
    
         | 
| 
       12 
     | 
    
         
            -
            shared_examples_for 'mimics MRI 2.1' do |grep_mri_warning|
         
     | 
| 
       13 
     | 
    
         
            -
              if RUBY_ENGINE == 'ruby' && RUBY_VERSION.start_with?('2.1')
         
     | 
| 
       14 
     | 
    
         
            -
                it "mimics MRI #{RUBY_VERSION} built-in syntax checking" do
         
     | 
| 
       15 
     | 
    
         
            -
                  inspect_source(source)
         
     | 
| 
       16 
     | 
    
         
            -
                  offenses_by_mri = MRISyntaxChecker.offenses_for_source(
         
     | 
| 
       17 
     | 
    
         
            -
                    source, cop.name, grep_mri_warning
         
     | 
| 
       18 
     | 
    
         
            -
                  )
         
     | 
| 
       19 
     | 
    
         
            -
             
     | 
| 
       20 
     | 
    
         
            -
                  # Compare objects before comparing counts for clear failure output.
         
     | 
| 
       21 
     | 
    
         
            -
                  cop.offenses.each_with_index do |offense_by_cop, index|
         
     | 
| 
       22 
     | 
    
         
            -
                    offense_by_mri = offenses_by_mri[index]
         
     | 
| 
       23 
     | 
    
         
            -
                    # Exclude column attribute since MRI does not
         
     | 
| 
       24 
     | 
    
         
            -
                    # output column number.
         
     | 
| 
       25 
     | 
    
         
            -
                    %i[severity line cop_name].each do |a|
         
     | 
| 
       26 
     | 
    
         
            -
                      expect(offense_by_cop.send(a)).to eq(offense_by_mri.send(a))
         
     | 
| 
       27 
     | 
    
         
            -
                    end
         
     | 
| 
       28 
     | 
    
         
            -
                  end
         
     | 
| 
       29 
     | 
    
         
            -
             
     | 
| 
       30 
     | 
    
         
            -
                  expect(cop.offenses.count).to eq(offenses_by_mri.count)
         
     | 
| 
       31 
     | 
    
         
            -
                end
         
     | 
| 
       32 
     | 
    
         
            -
              end
         
     | 
| 
       33 
     | 
    
         
            -
            end
         
     | 
| 
       34 
     | 
    
         
            -
             
     | 
| 
       35 
12 
     | 
    
         
             
            shared_examples_for 'misaligned' do |annotated_source, used_style|
         
     | 
| 
       36 
13 
     | 
    
         
             
              config_to_allow_offenses = if used_style
         
     | 
| 
       37 
14 
     | 
    
         
             
                                           { 'EnforcedStyleAlignWith' => used_style.to_s }
         
     |