class RuboCop::Cop::Commissioner

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

def begin_investigation(processed_source, offset:, original:)

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

def build_callbacks(cops)

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

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

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

def initialize_callbacks

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

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

Returns:
  • (InvestigationReport) -
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, @cops)
    invoke_with_argument(:investigate, @forces, processed_source)
    walk(processed_source.ast) unless @cops.empty?
    invoke(:on_investigation_end, @cops)
  else
    invoke(:on_other_file, @cops)
  end
  reports = @cops.map { |cop| cop.send(:complete_investigation) }
  InvestigationReport.new(processed_source, reports, @errors)
end

def invoke(callback, cops)

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

def invoke_with_argument(callback, cops, arg)

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

def reset

def reset
  @errors = []
end

def restrict_callbacks(callbacks)

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

def restricted_map(callbacks)

NOTE: mutates `callbacks` in place
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

def trigger_responding_cops(callback, node)

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

def trigger_restricted_cops(event, node)

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

def with_cop_error_handling(cop, node = nil)

cops' `#investigate` methods.
re-raising exceptions that can be raised from within the individual
Allow blind rescues here, since we're absorbing and packaging or
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