Class: RuboCop::Cop::SortedMethodsByCall::Waterfall

Inherits:
Base
  • Object
show all
Extended by:
AutoCorrector
Includes:
RangeHelp
Defined in:
lib/rubocop/cop/sorted_methods_by_call/waterfall.rb

Overview

Enforces “waterfall” ordering: define a method after any method that calls it within the same scope. Produces a top-down reading flow where orchestration appears before implementation details.

  • Scopes: class/module/sclass (top-level can be analyzed via on_begin)

  • Offense: when a callee is defined above its caller

  • Autocorrect: UNSAFE; reorders methods within a contiguous visibility section (does not cross other statements or nested scopes). Preserves leading doc comments on each method. Skips cycles and non-contiguous groups.

Configuration

  • AllowedRecursion [Boolean] (default: true)

    If true, the cop ignores violations that are part of a recursion cycle
    detectable in the direct call graph (callee → … → caller). If false,
    such cycles are reported.
    
  • SafeAutoCorrect [Boolean] (default: false)

    Autocorrection is unsafe and only runs under -A, never under -a.
    
  • SkipCyclicSiblingEdges [Boolean] (default: false)

    If true, the cop will not add "called together" sibling-order edges
    that would introduce a cycle with existing constraints (direct edges +
    already accepted sibling edges).
    

Examples:

Good (waterfall order)

class Service
  def call
    foo
    bar
  end

  private

  def bar
    method123
  end

  def method123
    foo
  end

  def foo
    123
  end
end

Bad (violates waterfall order)

class Service
  def call
    foo
    bar
  end

  private

  def foo
    123
  end

  def bar
    method123
  end

  def method123
    foo
  end
end

See Also:

  • #analyze_scope
  • #try_autocorrect

Constant Summary collapse

VISIBILITY_METHODS =
%i[private protected public].freeze
MSG =

Template message for offenses where a callee appears before its caller.

'Define %<callee>s after its caller %<caller>s (waterfall order).'
SIBLING_MSG =
'Define %<callee>s after %<caller>s to match the order they are called together.'
MSG_CROSS_VISIBILITY_NOTE =
'%<base>s (Autocorrect not supported across visibility boundaries: ' \
'%<caller_visibility>s vs %<callee_visibility>s.)'
MSG_SIBLING_CYCLE_NOTE =
'%<base>s (Possible sibling cycle detected; autocorrect may be skipped.)'

Instance Method Summary collapse

Instance Method Details

#on_begin(node) ⇒ void

This method returns an undefined value.

Entry point for root :begin nodes (top-level).

Whether top-level is analyzed depends on how the code is structured; by default we only analyze class/module/sclass scopes, but top-level is supported through this hook.

Parameters:

  • node (RuboCop::AST::Node)

    root :begin node



100
101
102
# File 'lib/rubocop/cop/sorted_methods_by_call/waterfall.rb', line 100

def on_begin(node)
  analyze_scope(node)
end

#on_class(node) ⇒ void

This method returns an undefined value.

Entry point for class scopes.

Parameters:

  • node (RuboCop::AST::Node)

    :class node



108
109
110
# File 'lib/rubocop/cop/sorted_methods_by_call/waterfall.rb', line 108

def on_class(node)
  analyze_scope(node)
end

#on_module(node) ⇒ void

This method returns an undefined value.

Entry point for module scopes.

Parameters:

  • node (RuboCop::AST::Node)

    :module node



116
117
118
# File 'lib/rubocop/cop/sorted_methods_by_call/waterfall.rb', line 116

def on_module(node)
  analyze_scope(node)
end

#on_sclass(node) ⇒ void

This method returns an undefined value.

Entry point for singleton class scopes (class << self).

Parameters:

  • node (RuboCop::AST::Node)

    :sclass node



124
125
126
# File 'lib/rubocop/cop/sorted_methods_by_call/waterfall.rb', line 124

def on_sclass(node)
  analyze_scope(node)
end