Class: RuboCop::Cop::Style::MethodOrder

Inherits:
RuboCop::Cop show all
Includes:
RangeHelp
Defined in:
lib/rubocop/cop/style/method_order.rb

Overview

This cop enforces methods to be sorted alphabetically within the context of their scope and permission level such as private or protected. The method initialize is given special treatment by being required to be listed first in the context of a class if it's a public method.

Examples:


# bad

# `bar` should be listed before `foo`. The method `bar` will show
# a linter error with a message indicating which method is should show
# before. The private method `another_method` will also an error
# saying it should be before `private_method`.
class ExampleClass
  def foo
  end

  def bar
  end

  private

  def private_method
  end

  def another_method
  end
end

# bad

# Works on modules too.
module ExampleModule
  def foo
  end

  def bar
  end
end

# bad

# As well as top level ruby methods in a file.
def foo
end

def bar
end

# good

class ExampleClass
  def bar
  end

  def foo
  end

  private

  def another_method
  end

  def private_method
  end
end

# good

module ExampleModule
  def bar
  end

  def foo
  end
end

# good

def bar
end

def foo
end

Constant Summary collapse

MSG =
'Methods should be sorted in alphabetical order within their section' \
' of the code. Method `%<method>s` should come before `%<previous_method>s`.'

Instance Method Summary collapse

Instance Method Details

#autocorrect(_node) ⇒ Object

rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, rubocop:disable Metrics/MethodLength, Metrics/PerceivedComplexity



111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/rubocop/cop/style/method_order.rb', line 111

def autocorrect(_node)
  lambda do |corrector|
    @method_collector.nodes_by_scope.values.each do |method_collection|
      next if @autocorrected_method_collections.include?(method_collection)

      @autocorrected_method_collections << method_collection
      method_collection.replacements.values.each do |replacement_collection|
        replacement_collection.each do |node_to_move, node_to_replace|
          next if @autocorrected_nodes.include?(node_to_move)

          @autocorrected_nodes << node_to_move
          node_source = range_with_method_comments(node_to_move).source
          replacement_range = range_with_method_comments(node_to_replace)

          if node_source.end_with?("\n") && !replacement_range.source.end_with?("\n")
            corrector.replace(replacement_range, node_source.chomp("\n"))
          elsif !node_source.end_with?("\n") && replacement_range.source.end_with?("\n")
            corrector.replace(replacement_range, node_source + "\n")
          else
            corrector.replace(replacement_range, node_source)
          end
        end
      end
    end
  end
end

#investigate(_processed_source) ⇒ Object

rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, rubocop:enable Metrics/MethodLength, Metrics/PerceivedComplexity



140
141
142
143
144
145
146
147
# File 'lib/rubocop/cop/style/method_order.rb', line 140

def investigate(_processed_source)
  @autocorrected_method_collections = []
  @autocorrected_nodes = []
  @method_collector = RuboCopMethodOrder::MethodCollector.new(
    should_skip_method: ->(node) { !cop_enabled_for_node?(node) }
  )
  @offenses_checked = false
end

#offenses(*args) ⇒ Object

NOTE: Change this if cops get a callback method for running validations after the on_* methods have been executed.



151
152
153
154
155
156
157
158
# File 'lib/rubocop/cop/style/method_order.rb', line 151

def offenses(*args)
  unless @offenses_checked
    @offenses_checked = true
    check_nodes
  end

  super(*args)
end

#on_class(node) ⇒ Object



160
161
162
# File 'lib/rubocop/cop/style/method_order.rb', line 160

def on_class(node)
  @method_collector.collect_nodes_from_class(node)
end

#on_def(node) ⇒ Object Also known as: on_defs



164
165
166
# File 'lib/rubocop/cop/style/method_order.rb', line 164

def on_def(node)
  @method_collector.collect(node)
end

#on_module(node) ⇒ Object



169
170
171
# File 'lib/rubocop/cop/style/method_order.rb', line 169

def on_module(node)
  @method_collector.collect_nodes_from_module(node)
end