rubocop 0.91.0 → 0.91.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/config/default.yml +9 -1
- data/lib/rubocop.rb +1 -1
- data/lib/rubocop/comment_config.rb +9 -5
- data/lib/rubocop/cop/correctors/line_break_corrector.rb +1 -1
- data/lib/rubocop/cop/layout/case_indentation.rb +4 -7
- data/lib/rubocop/cop/layout/class_structure.rb +1 -1
- data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +2 -2
- data/lib/rubocop/cop/layout/empty_line_after_multiline_condition.rb +4 -13
- data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +14 -8
- data/lib/rubocop/cop/layout/empty_lines_around_attribute_accessor.rb +1 -1
- data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +1 -2
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +10 -1
- data/lib/rubocop/cop/layout/space_around_equals_in_parameter_default.rb +2 -2
- data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +7 -7
- data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +4 -18
- data/lib/rubocop/cop/layout/space_inside_reference_brackets.rb +2 -2
- data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +2 -2
- data/lib/rubocop/cop/lint/constant_definition_in_block.rb +23 -3
- data/lib/rubocop/cop/lint/duplicate_rescue_exception.rb +2 -4
- data/lib/rubocop/cop/lint/identity_comparison.rb +5 -3
- data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +2 -5
- data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +22 -12
- data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +14 -4
- data/lib/rubocop/cop/lint/rescue_type.rb +0 -1
- data/lib/rubocop/cop/lint/shadowed_exception.rb +6 -6
- data/lib/rubocop/cop/lint/unreachable_loop.rb +1 -5
- data/lib/rubocop/cop/lint/useless_access_modifier.rb +3 -9
- data/lib/rubocop/cop/lint/useless_times.rb +11 -2
- data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +25 -16
- data/lib/rubocop/cop/mixin/configurable_numbering.rb +3 -3
- data/lib/rubocop/cop/mixin/rescue_node.rb +1 -0
- data/lib/rubocop/cop/mixin/statement_modifier.rb +9 -3
- data/lib/rubocop/cop/mixin/visibility_help.rb +4 -16
- data/lib/rubocop/cop/style/combinable_loops.rb +5 -10
- data/lib/rubocop/cop/style/commented_keyword.rb +7 -8
- data/lib/rubocop/cop/style/hash_as_last_array_item.rb +15 -6
- data/lib/rubocop/cop/style/if_unless_modifier.rb +0 -4
- data/lib/rubocop/cop/style/keyword_parameters_order.rb +1 -6
- data/lib/rubocop/cop/style/multiline_block_chain.rb +2 -2
- data/lib/rubocop/cop/style/multiline_when_then.rb +1 -0
- data/lib/rubocop/cop/style/one_line_conditional.rb +3 -1
- data/lib/rubocop/cop/style/optional_boolean_parameter.rb +3 -0
- data/lib/rubocop/cop/style/random_with_offset.rb +3 -3
- data/lib/rubocop/cop/style/redundant_assignment.rb +1 -9
- data/lib/rubocop/cop/style/redundant_conditional.rb +4 -5
- data/lib/rubocop/cop/style/redundant_parentheses.rb +2 -3
- data/lib/rubocop/cop/style/redundant_percent_q.rb +9 -11
- data/lib/rubocop/cop/style/redundant_return.rb +17 -17
- data/lib/rubocop/cop/style/redundant_self.rb +7 -9
- data/lib/rubocop/cop/style/redundant_sort.rb +13 -24
- data/lib/rubocop/cop/style/redundant_sort_by.rb +5 -9
- data/lib/rubocop/cop/style/rescue_standard_error.rb +20 -16
- data/lib/rubocop/cop/style/ternary_parentheses.rb +1 -2
- data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +4 -3
- data/lib/rubocop/cop/util.rb +0 -1
- data/lib/rubocop/directive_comment.rb +32 -0
- data/lib/rubocop/version.rb +1 -1
- metadata +3 -3
- data/lib/rubocop/cop/tokens_util.rb +0 -84
| @@ -33,10 +33,8 @@ module RuboCop | |
| 33 33 | 
             
                    def on_rescue(node)
         | 
| 34 34 | 
             
                      return if rescue_modifier?(node)
         | 
| 35 35 |  | 
| 36 | 
            -
                       | 
| 37 | 
            -
             | 
| 38 | 
            -
                      resbodies.each_with_object(Set.new) do |resbody, previous|
         | 
| 39 | 
            -
                        rescued_exceptions = rescued_exceptions(resbody)
         | 
| 36 | 
            +
                      node.resbody_branches.each_with_object(Set.new) do |resbody, previous|
         | 
| 37 | 
            +
                        rescued_exceptions = resbody.exceptions
         | 
| 40 38 |  | 
| 41 39 | 
             
                        rescued_exceptions.each do |exception|
         | 
| 42 40 | 
             
                          add_offense(exception) unless previous.add?(exception)
         | 
| @@ -26,9 +26,11 @@ module RuboCop | |
| 26 26 | 
             
                      return unless compare_between_object_id_by_double_equal?(node)
         | 
| 27 27 |  | 
| 28 28 | 
             
                      add_offense(node) do |corrector|
         | 
| 29 | 
            -
                        receiver = node.receiver.receiver | 
| 30 | 
            -
                        argument = node.first_argument.receiver | 
| 31 | 
            -
                         | 
| 29 | 
            +
                        receiver = node.receiver.receiver
         | 
| 30 | 
            +
                        argument = node.first_argument.receiver
         | 
| 31 | 
            +
                        return unless receiver && argument
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                        replacement = "#{receiver.source}.equal?(#{argument.source})"
         | 
| 32 34 |  | 
| 33 35 | 
             
                        corrector.replace(node, replacement)
         | 
| 34 36 | 
             
                      end
         | 
| @@ -58,12 +58,9 @@ module RuboCop | |
| 58 58 | 
             
                    PATTERN
         | 
| 59 59 |  | 
| 60 60 | 
             
                    def on_class(node)
         | 
| 61 | 
            -
                      check_node(node. | 
| 62 | 
            -
                    end
         | 
| 63 | 
            -
             | 
| 64 | 
            -
                    def on_module(node)
         | 
| 65 | 
            -
                      check_node(node.children[1]) # module body
         | 
| 61 | 
            +
                      check_node(node.body)
         | 
| 66 62 | 
             
                    end
         | 
| 63 | 
            +
                    alias on_module on_class
         | 
| 67 64 |  | 
| 68 65 | 
             
                    private
         | 
| 69 66 |  | 
| @@ -56,19 +56,29 @@ module RuboCop | |
| 56 56 |  | 
| 57 57 | 
             
                    private
         | 
| 58 58 |  | 
| 59 | 
            +
                    def previous_line_blank?(range)
         | 
| 60 | 
            +
                      processed_source.buffer.source_line(range.line - 1).blank?
         | 
| 61 | 
            +
                    end
         | 
| 62 | 
            +
             | 
| 59 63 | 
             
                    def comment_range_with_surrounding_space(range)
         | 
| 60 | 
            -
                       | 
| 61 | 
            -
             | 
| 62 | 
            -
             | 
| 63 | 
            -
                       | 
| 64 | 
            -
             | 
| 65 | 
            -
             | 
| 66 | 
            -
             | 
| 67 | 
            -
             | 
| 68 | 
            -
             | 
| 69 | 
            -
             | 
| 70 | 
            -
             | 
| 71 | 
            -
             | 
| 64 | 
            +
                      if previous_line_blank?(range)
         | 
| 65 | 
            +
                        # When the previous line is blank, it should be retained
         | 
| 66 | 
            +
                        range_with_surrounding_space(range: range, side: :right)
         | 
| 67 | 
            +
                      else
         | 
| 68 | 
            +
                        # Eat the entire comment, the preceding space, and the preceding
         | 
| 69 | 
            +
                        # newline if there is one.
         | 
| 70 | 
            +
                        original_begin = range.begin_pos
         | 
| 71 | 
            +
                        range = range_with_surrounding_space(range: range,
         | 
| 72 | 
            +
                                                             side: :left,
         | 
| 73 | 
            +
                                                             newlines: true)
         | 
| 74 | 
            +
             | 
| 75 | 
            +
                        range_with_surrounding_space(range: range,
         | 
| 76 | 
            +
                                                     side: :right,
         | 
| 77 | 
            +
                                                     # Special for a comment that
         | 
| 78 | 
            +
                                                     # begins the file: remove
         | 
| 79 | 
            +
                                                     # the newline at the end.
         | 
| 80 | 
            +
                                                     newlines: original_begin.zero?)
         | 
| 81 | 
            +
                      end
         | 
| 72 82 | 
             
                    end
         | 
| 73 83 |  | 
| 74 84 | 
             
                    def directive_range_in_list(range, ranges)
         | 
| @@ -45,18 +45,28 @@ module RuboCop | |
| 45 45 | 
             
                      return if processed_source.blank?
         | 
| 46 46 |  | 
| 47 47 | 
             
                      offenses = processed_source.comment_config.extra_enabled_comments
         | 
| 48 | 
            -
                      offenses.each  | 
| 48 | 
            +
                      offenses.each { |comment, cop_names| register_offense(comment, cop_names) }
         | 
| 49 | 
            +
                    end
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                    private
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                    def register_offense(comment, cop_names)
         | 
| 54 | 
            +
                      directive = DirectiveComment.new(comment)
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                      cop_names.each do |name|
         | 
| 49 57 | 
             
                        add_offense(
         | 
| 50 58 | 
             
                          range_of_offense(comment, name),
         | 
| 51 59 | 
             
                          message: format(MSG, cop: all_or_name(name))
         | 
| 52 60 | 
             
                        ) do |corrector|
         | 
| 53 | 
            -
                           | 
| 61 | 
            +
                          if directive.match?(cop_names)
         | 
| 62 | 
            +
                            corrector.remove(range_with_surrounding_space(range: directive.range, side: :right))
         | 
| 63 | 
            +
                          else
         | 
| 64 | 
            +
                            corrector.remove(range_with_comma(comment, name))
         | 
| 65 | 
            +
                          end
         | 
| 54 66 | 
             
                        end
         | 
| 55 67 | 
             
                      end
         | 
| 56 68 | 
             
                    end
         | 
| 57 69 |  | 
| 58 | 
            -
                    private
         | 
| 59 | 
            -
             | 
| 60 70 | 
             
                    def range_of_offense(comment, name)
         | 
| 61 71 | 
             
                      start_pos = comment_start(comment) + cop_name_indention(comment, name)
         | 
| 62 72 | 
             
                      range_between(start_pos, start_pos + name.size)
         | 
| @@ -75,8 +75,7 @@ module RuboCop | |
| 75 75 |  | 
| 76 76 | 
             
                    def rescued_groups_for(rescues)
         | 
| 77 77 | 
             
                      rescues.map do |group|
         | 
| 78 | 
            -
                         | 
| 79 | 
            -
                        evaluate_exceptions(rescue_group)
         | 
| 78 | 
            +
                        evaluate_exceptions(group)
         | 
| 80 79 | 
             
                      end
         | 
| 81 80 | 
             
                    end
         | 
| 82 81 |  | 
| @@ -117,14 +116,15 @@ module RuboCop | |
| 117 116 | 
             
                      $VERBOSE = old_verbose
         | 
| 118 117 | 
             
                    end
         | 
| 119 118 |  | 
| 120 | 
            -
                    def evaluate_exceptions( | 
| 121 | 
            -
                       | 
| 122 | 
            -
             | 
| 119 | 
            +
                    def evaluate_exceptions(group)
         | 
| 120 | 
            +
                      rescued_exceptions = group.exceptions
         | 
| 121 | 
            +
             | 
| 122 | 
            +
                      if rescued_exceptions.any?
         | 
| 123 123 | 
             
                        rescued_exceptions.each_with_object([]) do |exception, converted|
         | 
| 124 124 | 
             
                          begin
         | 
| 125 125 | 
             
                            silence_warnings do
         | 
| 126 126 | 
             
                              # Avoid printing deprecation warnings about constants
         | 
| 127 | 
            -
                              converted << Kernel.const_get(exception)
         | 
| 127 | 
            +
                              converted << Kernel.const_get(exception.source)
         | 
| 128 128 | 
             
                            end
         | 
| 129 129 | 
             
                          rescue NameError
         | 
| 130 130 | 
             
                            converted << nil
         | 
| @@ -159,16 +159,12 @@ module RuboCop | |
| 159 159 | 
             
                    end
         | 
| 160 160 |  | 
| 161 161 | 
             
                    def preceded_by_continue_statement?(break_statement)
         | 
| 162 | 
            -
                       | 
| 162 | 
            +
                      break_statement.left_siblings.any? do |sibling|
         | 
| 163 163 | 
             
                        next if sibling.loop_keyword? || loop_method?(sibling)
         | 
| 164 164 |  | 
| 165 165 | 
             
                        sibling.each_descendant(:next, :redo).any?
         | 
| 166 166 | 
             
                      end
         | 
| 167 167 | 
             
                    end
         | 
| 168 | 
            -
             | 
| 169 | 
            -
                    def left_siblings_of(node)
         | 
| 170 | 
            -
                      node.parent.children[0, node.sibling_index]
         | 
| 171 | 
            -
                    end
         | 
| 172 168 | 
             
                  end
         | 
| 173 169 | 
             
                end
         | 
| 174 170 | 
             
              end
         | 
| @@ -131,12 +131,10 @@ module RuboCop | |
| 131 131 | 
             
                    MSG = 'Useless `%<current>s` access modifier.'
         | 
| 132 132 |  | 
| 133 133 | 
             
                    def on_class(node)
         | 
| 134 | 
            -
                      check_node(node. | 
| 135 | 
            -
                    end
         | 
| 136 | 
            -
             | 
| 137 | 
            -
                    def on_module(node)
         | 
| 138 | 
            -
                      check_node(node.children[1]) # module body
         | 
| 134 | 
            +
                      check_node(node.body)
         | 
| 139 135 | 
             
                    end
         | 
| 136 | 
            +
                    alias on_module on_class
         | 
| 137 | 
            +
                    alias on_sclass on_class
         | 
| 140 138 |  | 
| 141 139 | 
             
                    def on_block(node)
         | 
| 142 140 | 
             
                      return unless eval_call?(node)
         | 
| @@ -144,10 +142,6 @@ module RuboCop | |
| 144 142 | 
             
                      check_node(node.body)
         | 
| 145 143 | 
             
                    end
         | 
| 146 144 |  | 
| 147 | 
            -
                    def on_sclass(node)
         | 
| 148 | 
            -
                      check_node(node.children[1]) # singleton class body
         | 
| 149 | 
            -
                    end
         | 
| 150 | 
            -
             | 
| 151 145 | 
             
                    private
         | 
| 152 146 |  | 
| 153 147 | 
             
                    def autocorrect(corrector, node)
         | 
| @@ -49,7 +49,7 @@ module RuboCop | |
| 49 49 | 
             
                      add_offense(node, message: format(MSG, count: count)) do |corrector|
         | 
| 50 50 | 
             
                        next unless own_line?(node)
         | 
| 51 51 |  | 
| 52 | 
            -
                        if count  | 
| 52 | 
            +
                        if never_process?(count, node)
         | 
| 53 53 | 
             
                          remove_node(corrector, node)
         | 
| 54 54 | 
             
                        elsif !proc_name.empty?
         | 
| 55 55 | 
             
                          autocorrect_block_pass(corrector, node, proc_name)
         | 
| @@ -61,6 +61,10 @@ module RuboCop | |
| 61 61 |  | 
| 62 62 | 
             
                    private
         | 
| 63 63 |  | 
| 64 | 
            +
                    def never_process?(count, node)
         | 
| 65 | 
            +
                      count < 1 || node.block_type? && node.body.nil?
         | 
| 66 | 
            +
                    end
         | 
| 67 | 
            +
             | 
| 64 68 | 
             
                    def remove_node(corrector, node)
         | 
| 65 69 | 
             
                      corrector.remove(range_by_whole_lines(node.loc.expression, include_final_newline: true))
         | 
| 66 70 | 
             
                    end
         | 
| @@ -82,7 +86,12 @@ module RuboCop | |
| 82 86 | 
             
                    def fix_indentation(source, range)
         | 
| 83 87 | 
             
                      # Cleanup indentation in a multiline block
         | 
| 84 88 | 
             
                      source_lines = source.split("\n")
         | 
| 85 | 
            -
             | 
| 89 | 
            +
             | 
| 90 | 
            +
                      source_lines[1..-1].each do |line|
         | 
| 91 | 
            +
                        next if line.empty?
         | 
| 92 | 
            +
             | 
| 93 | 
            +
                        line[range] = ''
         | 
| 94 | 
            +
                      end
         | 
| 86 95 | 
             
                      source_lines.join("\n")
         | 
| 87 96 | 
             
                    end
         | 
| 88 97 |  | 
| @@ -81,40 +81,49 @@ module RuboCop | |
| 81 81 | 
             
                      private
         | 
| 82 82 |  | 
| 83 83 | 
             
                      def assignment?(node)
         | 
| 84 | 
            +
                        return compound_assignment(node) if node.masgn_type? || node.shorthand_asgn?
         | 
| 85 | 
            +
             | 
| 84 86 | 
             
                        node.for_type? ||
         | 
| 85 | 
            -
                          node.op_asgn_type? ||
         | 
| 86 87 | 
             
                          (node.respond_to?(:setter_method?) && node.setter_method?) ||
         | 
| 87 | 
            -
                           | 
| 88 | 
            +
                          simple_assignment?(node) ||
         | 
| 89 | 
            +
                          argument?(node)
         | 
| 88 90 | 
             
                      end
         | 
| 89 91 |  | 
| 90 | 
            -
                      def  | 
| 91 | 
            -
                         | 
| 92 | 
            +
                      def compound_assignment(node)
         | 
| 93 | 
            +
                        # Methods setter can not be detected for multiple assignments
         | 
| 94 | 
            +
                        # and shorthand assigns, so we'll count them here instead
         | 
| 95 | 
            +
                        children = node.masgn_type? ? node.children[0].children : node.children
         | 
| 92 96 |  | 
| 93 | 
            -
                         | 
| 94 | 
            -
                           | 
| 95 | 
            -
             | 
| 97 | 
            +
                        will_be_miscounted = children.count do |child|
         | 
| 98 | 
            +
                          child.respond_to?(:setter_method?) &&
         | 
| 99 | 
            +
                            !child.setter_method?
         | 
| 96 100 | 
             
                        end
         | 
| 101 | 
            +
                        @assignment += will_be_miscounted
         | 
| 97 102 |  | 
| 98 | 
            -
                         | 
| 103 | 
            +
                        false
         | 
| 99 104 | 
             
                      end
         | 
| 100 105 |  | 
| 101 | 
            -
                      def  | 
| 102 | 
            -
                         | 
| 106 | 
            +
                      def simple_assignment?(node)
         | 
| 107 | 
            +
                        if !node.equals_asgn?
         | 
| 108 | 
            +
                          false
         | 
| 109 | 
            +
                        elsif node.lvasgn_type?
         | 
| 110 | 
            +
                          reset_on_lvasgn(node)
         | 
| 111 | 
            +
                          capturing_variable?(node.children.first)
         | 
| 112 | 
            +
                        else
         | 
| 113 | 
            +
                          true
         | 
| 114 | 
            +
                        end
         | 
| 103 115 | 
             
                      end
         | 
| 104 116 |  | 
| 105 | 
            -
                       | 
| 106 | 
            -
             | 
| 107 | 
            -
                      def assignment_doubled_in_ast?(node)
         | 
| 108 | 
            -
                        node.masgn_type? || node.or_asgn_type? || node.and_asgn_type?
         | 
| 117 | 
            +
                      def capturing_variable?(name)
         | 
| 118 | 
            +
                        name && !/^_/.match?(name)
         | 
| 109 119 | 
             
                      end
         | 
| 110 120 |  | 
| 111 121 | 
             
                      def branch?(node)
         | 
| 112 122 | 
             
                        BRANCH_NODES.include?(node.type)
         | 
| 113 123 | 
             
                      end
         | 
| 114 124 |  | 
| 115 | 
            -
                      # TODO: move to rubocop-ast
         | 
| 116 125 | 
             
                      def argument?(node)
         | 
| 117 | 
            -
                        ARGUMENT_TYPES.include?(node.type)
         | 
| 126 | 
            +
                        ARGUMENT_TYPES.include?(node.type) && capturing_variable?(node.children.first)
         | 
| 118 127 | 
             
                      end
         | 
| 119 128 |  | 
| 120 129 | 
             
                      def condition?(node)
         | 
| @@ -8,9 +8,9 @@ module RuboCop | |
| 8 8 | 
             
                  include ConfigurableFormatting
         | 
| 9 9 |  | 
| 10 10 | 
             
                  FORMATS = {
         | 
| 11 | 
            -
                    snake_case:  /(?:[ | 
| 12 | 
            -
                    normalcase:  /(?:_\D*|[ | 
| 13 | 
            -
                    non_integer: /[ | 
| 11 | 
            +
                    snake_case:  /(?:[[[:lower:]]_]|_\d+)$/,
         | 
| 12 | 
            +
                    normalcase:  /(?:_\D*|[[[:upper:]][[:lower:]]]\d*)$/,
         | 
| 13 | 
            +
                    non_integer: /[[[:upper:]][[:lower:]]_]$/
         | 
| 14 14 | 
             
                  }.freeze
         | 
| 15 15 | 
             
                end
         | 
| 16 16 | 
             
              end
         | 
| @@ -57,10 +57,11 @@ module RuboCop | |
| 57 57 | 
             
                  end
         | 
| 58 58 |  | 
| 59 59 | 
             
                  def first_line_comment(node)
         | 
| 60 | 
            -
                    comment =
         | 
| 61 | 
            -
             | 
| 60 | 
            +
                    comment = processed_source.find_comment { |c| c.loc.line == node.loc.line }
         | 
| 61 | 
            +
                    return unless comment
         | 
| 62 62 |  | 
| 63 | 
            -
                     | 
| 63 | 
            +
                    comment_source = comment.loc.expression.source
         | 
| 64 | 
            +
                    comment_source unless comment_disables_cop?(comment_source)
         | 
| 64 65 | 
             
                  end
         | 
| 65 66 |  | 
| 66 67 | 
             
                  def parenthesize?(node)
         | 
| @@ -80,6 +81,11 @@ module RuboCop | |
| 80 81 |  | 
| 81 82 | 
             
                    config.for_cop('Layout/LineLength')['Max']
         | 
| 82 83 | 
             
                  end
         | 
| 84 | 
            +
             | 
| 85 | 
            +
                  def comment_disables_cop?(comment)
         | 
| 86 | 
            +
                    regexp_pattern = "# rubocop : (disable|todo) ([^,],)* (all|#{cop_name})"
         | 
| 87 | 
            +
                    Regexp.new(regexp_pattern.gsub(' ', '\s*')).match?(comment)
         | 
| 88 | 
            +
                  end
         | 
| 83 89 | 
             
                end
         | 
| 84 90 | 
             
              end
         | 
| 85 91 | 
             
            end
         | 
| @@ -16,32 +16,20 @@ module RuboCop | |
| 16 16 | 
             
                  end
         | 
| 17 17 |  | 
| 18 18 | 
             
                  def find_visibility_start(node)
         | 
| 19 | 
            -
                     | 
| 20 | 
            -
             | 
| 21 | 
            -
             | 
| 19 | 
            +
                    node.left_siblings
         | 
| 20 | 
            +
                        .reverse
         | 
| 21 | 
            +
                        .find(&method(:visibility_block?))
         | 
| 22 22 | 
             
                  end
         | 
| 23 23 |  | 
| 24 24 | 
             
                  # Navigate to find the last protected method
         | 
| 25 25 | 
             
                  def find_visibility_end(node)
         | 
| 26 26 | 
             
                    possible_visibilities = VISIBILITY_SCOPES - [node_visibility(node)]
         | 
| 27 | 
            -
                    right =  | 
| 27 | 
            +
                    right = node.right_siblings
         | 
| 28 28 | 
             
                    right.find do |child_node|
         | 
| 29 29 | 
             
                      possible_visibilities.include?(node_visibility(child_node))
         | 
| 30 30 | 
             
                    end || right.last
         | 
| 31 31 | 
             
                  end
         | 
| 32 32 |  | 
| 33 | 
            -
                  def left_siblings_of(node)
         | 
| 34 | 
            -
                    siblings_of(node)[0, node.sibling_index]
         | 
| 35 | 
            -
                  end
         | 
| 36 | 
            -
             | 
| 37 | 
            -
                  def right_siblings_of(node)
         | 
| 38 | 
            -
                    siblings_of(node)[node.sibling_index..-1]
         | 
| 39 | 
            -
                  end
         | 
| 40 | 
            -
             | 
| 41 | 
            -
                  def siblings_of(node)
         | 
| 42 | 
            -
                    node.parent.children
         | 
| 43 | 
            -
                  end
         | 
| 44 | 
            -
             | 
| 45 33 | 
             
                  def_node_matcher :visibility_block?, <<~PATTERN
         | 
| 46 34 | 
             
                    (send nil? { :private :protected :public })
         | 
| 47 35 | 
             
                  PATTERN
         | 
| @@ -53,14 +53,16 @@ module RuboCop | |
| 53 53 | 
             
                    MSG = 'Combine this loop with the previous loop.'
         | 
| 54 54 |  | 
| 55 55 | 
             
                    def on_block(node)
         | 
| 56 | 
            +
                      return unless node.parent&.begin_type?
         | 
| 56 57 | 
             
                      return unless collection_looping_method?(node)
         | 
| 57 58 |  | 
| 58 | 
            -
                       | 
| 59 | 
            -
                      add_offense(node) if same_collection_looping?(node, sibling)
         | 
| 59 | 
            +
                      add_offense(node) if same_collection_looping?(node, node.left_sibling)
         | 
| 60 60 | 
             
                    end
         | 
| 61 61 |  | 
| 62 62 | 
             
                    def on_for(node)
         | 
| 63 | 
            -
                       | 
| 63 | 
            +
                      return unless node.parent&.begin_type?
         | 
| 64 | 
            +
             | 
| 65 | 
            +
                      sibling = node.left_sibling
         | 
| 64 66 | 
             
                      add_offense(node) if sibling&.for_type? && node.collection == sibling.collection
         | 
| 65 67 | 
             
                    end
         | 
| 66 68 |  | 
| @@ -71,13 +73,6 @@ module RuboCop | |
| 71 73 | 
             
                      method_name.match?(/^each/) || method_name.match?(/_each$/)
         | 
| 72 74 | 
             
                    end
         | 
| 73 75 |  | 
| 74 | 
            -
                    def left_sibling_of(node)
         | 
| 75 | 
            -
                      return unless node.parent&.begin_type?
         | 
| 76 | 
            -
             | 
| 77 | 
            -
                      index = node.sibling_index - 1
         | 
| 78 | 
            -
                      node.parent.children[index] if index >= 0
         | 
| 79 | 
            -
                    end
         | 
| 80 | 
            -
             | 
| 81 76 | 
             
                    def same_collection_looping?(node, sibling)
         | 
| 82 77 | 
             
                      sibling&.block_type? &&
         | 
| 83 78 | 
             
                        sibling.send_node.method?(node.method_name) &&
         | 
| @@ -33,13 +33,17 @@ module RuboCop | |
| 33 33 | 
             
                  #   class X # :nodoc:
         | 
| 34 34 | 
             
                  #     y
         | 
| 35 35 | 
             
                  #   end
         | 
| 36 | 
            -
                  class CommentedKeyword <  | 
| 36 | 
            +
                  class CommentedKeyword < Base
         | 
| 37 37 | 
             
                    MSG = 'Do not place comments on the same line as the ' \
         | 
| 38 38 | 
             
                          '`%<keyword>s` keyword.'
         | 
| 39 39 |  | 
| 40 | 
            -
                    def  | 
| 40 | 
            +
                    def on_new_investigation
         | 
| 41 41 | 
             
                      processed_source.comments.each do |comment|
         | 
| 42 | 
            -
                         | 
| 42 | 
            +
                        next unless (match = line(comment).match(/(?<keyword>\S+).*#/))
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                        if offensive?(comment)
         | 
| 45 | 
            +
                          add_offense(comment, message: format(MSG, keyword: match[:keyword]))
         | 
| 46 | 
            +
                        end
         | 
| 43 47 | 
             
                      end
         | 
| 44 48 | 
             
                    end
         | 
| 45 49 |  | 
| @@ -62,11 +66,6 @@ module RuboCop | |
| 62 66 | 
             
                        ALLOWED_COMMENT_REGEXES.none? { |r| r.match?(line) }
         | 
| 63 67 | 
             
                    end
         | 
| 64 68 |  | 
| 65 | 
            -
                    def message(comment)
         | 
| 66 | 
            -
                      keyword = line(comment).match(/(\S+).*#/)[1]
         | 
| 67 | 
            -
                      format(MSG, keyword: keyword)
         | 
| 68 | 
            -
                    end
         | 
| 69 | 
            -
             | 
| 70 69 | 
             
                    def line(comment)
         | 
| 71 70 | 
             
                      comment.location.expression.source_line
         | 
| 72 71 | 
             
                    end
         |