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