123456789_123456789_123456789_123456789_123456789_

Class: RuboCop::Cop::Commissioner

Relationships & Source Files
Namespace Children
Classes:
Super Chains via Extension / Inclusion / Inheritance
Instance Chain:
self, RuboCop::AST::Traversal
Inherits: Object
Defined in: lib/rubocop/cop/commissioner.rb

Overview

Commissioner class is responsible for processing the AST and delegating work to the specified cops.

Constant Summary

Class Method Summary

Instance Attribute Summary

Instance Method Summary

Constructor Details

.new(cops, forces = [], options = {}) ⇒ Commissioner

[ GitHub ]

  
# File 'lib/rubocop/cop/commissioner.rb', line 44

def initialize(cops, forces = [], options = {})
  @cops = cops
  @forces = forces
  @options = options
  initialize_callbacks

  reset
end

Instance Attribute Details

#errors (readonly)

[ GitHub ]

  
# File 'lib/rubocop/cop/commissioner.rb', line 42

attr_reader :errors

Instance Method Details

#begin_investigation(processed_source, offset:, original:) (private)

[ GitHub ]

  
# File 'lib/rubocop/cop/commissioner.rb', line 100

def begin_investigation(processed_source, offset:, original:)
  @cops.each do |cop|
    cop.begin_investigation(processed_source, offset: offset, original: original)
  end
end

#build_callbacks(cops) (private)

[ GitHub ]

  
# File 'lib/rubocop/cop/commissioner.rb', line 123

def build_callbacks(cops)
  callbacks = {}
  cops.each do |cop|
    cop.callbacks_needed.each do |callback|
      (callbacks[callback] ||= []) << cop
    end
  end
  callbacks
end

#initialize_callbacks (private)

[ GitHub ]

  
# File 'lib/rubocop/cop/commissioner.rb', line 118

def initialize_callbacks
  @callbacks = build_callbacks(@cops)
  @restricted_map = restrict_callbacks(@callbacks)
end

#investigate(processed_source, offset: 0, original: processed_source) ⇒ InvestigationReport

[ GitHub ]

  
# File 'lib/rubocop/cop/commissioner.rb', line 81

def investigate(processed_source, offset: 0, original: processed_source)
  reset

  begin_investigation(processed_source, offset: offset, original: original)
  if processed_source.valid_syntax?
    invoke(:on_new_investigation, @callbacks[:on_new_investigation])
    invoke_with_argument(:investigate, @forces, processed_source)

    walk(processed_source.ast) unless @cops.empty?
    invoke(:on_investigation_end, @callbacks[:on_investigation_end])
  else
    invoke(:on_other_file, @callbacks[:on_other_file])
  end
  reports = @cops.map { |cop| cop.send(:complete_investigation) }
  InvestigationReport.new(processed_source, reports, @errors)
end

#invoke(callback, cops) (private)

[ GitHub ]

  
# File 'lib/rubocop/cop/commissioner.rb', line 161

def invoke(callback, cops)
  cops&.each { |cop| with_cop_error_handling(cop) { cop.send(callback) } }
end

#invoke_with_argument(callback, cops, arg) (private)

[ GitHub ]

  
# File 'lib/rubocop/cop/commissioner.rb', line 165

def invoke_with_argument(callback, cops, arg)
  cops.each { |cop| with_cop_error_handling(cop) { cop.send(callback, arg) } }
end

#reset (private)

[ GitHub ]

  
# File 'lib/rubocop/cop/commissioner.rb', line 114

def reset
  @errors = []
end

#restrict_callbacks(callbacks) (private)

[ GitHub ]

  
# File 'lib/rubocop/cop/commissioner.rb', line 133

def restrict_callbacks(callbacks)
  restricted = {}
  RESTRICTED_CALLBACKS.each do |callback|
    restricted[callback] = restricted_map(callbacks[callback])
  end
  restricted
end

#restricted_map(callbacks) (private)

Note
mutates callbacks in place
[ GitHub ]

  
# File 'lib/rubocop/cop/commissioner.rb', line 151

def restricted_map(callbacks)
  map = {}
  callbacks&.select! do |cop|
    restrictions = cop.class.send :restrict_on_send
    restrictions.each { |name| (map[name] ||= []) << cop }
    restrictions.empty?
  end
  map
end

#trigger_responding_cops(callback, node) (private)

[ GitHub ]

  
# File 'lib/rubocop/cop/commissioner.rb', line 106

def trigger_responding_cops(callback, node)
  @callbacks[callback]&.each do |cop|
    with_cop_error_handling(cop, node) do
      cop.public_send(callback, node)
    end
  end
end

#trigger_restricted_cops(event, node) (private)

[ GitHub ]

  
# File 'lib/rubocop/cop/commissioner.rb', line 141

def trigger_restricted_cops(event, node)
  name = node.method_name
  @restricted_map[event][name]&.each do |cop|
    with_cop_error_handling(cop, node) do
      cop.public_send(event, node)
    end
  end
end

#with_cop_error_handling(cop, node = nil) (private)

Allow blind rescues here, since we’re absorbing and packaging or re-raising exceptions that can be raised from within the individual cops' #investigate methods.

[ GitHub ]

  
# File 'lib/rubocop/cop/commissioner.rb', line 172

def with_cop_error_handling(cop, node = nil)
  yield
rescue StandardError => e
  raise e if @options[:raise_error] # For internal testing

  err = ErrorWithAnalyzedFileLocation.new(cause: e, node: node, cop: cop)
  raise err if @options[:raise_cop_error] # From user-input option

  @errors << err
end