class RuboCop::Cop::Commissioner

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

Constants

InvestigationReport

How a Commissioner returns the results of the investigation as a list of Cop::InvestigationReport and any errors caught during the investigation. Immutable Consider creation API private

RESTRICTED_CALLBACKS

Attributes

errors[R]

Public Class Methods

new(cops, forces = [], options = {}) click to toggle source
# File lib/rubocop/cop/commissioner.rb, line 44
def initialize(cops, forces = [], options = {})
  @cops = cops
  @forces = forces
  @options = options
  initialize_callbacks

  reset
end

Public Instance Methods

investigate(processed_source) click to toggle source

@return [InvestigationReport]

# File lib/rubocop/cop/commissioner.rb, line 79
def investigate(processed_source)
  reset

  @cops.each { |cop| cop.send :begin_investigation, processed_source }
  if processed_source.valid_syntax?
    invoke(:on_new_investigation, @cops)
    invoke(: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

Private Instance Methods

build_callbacks(cops) click to toggle source
# File lib/rubocop/cop/commissioner.rb, line 114
def build_callbacks(cops)
  callbacks = {}
  cops.each do |cop|
    cop.callbacks_needed.each do |callback|
      (callbacks[callback] ||= []) << cop
    end
  end
  callbacks
end
initialize_callbacks() click to toggle source
# File lib/rubocop/cop/commissioner.rb, line 109
def initialize_callbacks
  @callbacks = build_callbacks(@cops)
  @restricted_map = restrict_callbacks(@callbacks)
end
invoke(callback, cops, *args) click to toggle source
# File lib/rubocop/cop/commissioner.rb, line 152
def invoke(callback, cops, *args)
  cops.each { |cop| with_cop_error_handling(cop) { cop.send(callback, *args) } }
end
reset() click to toggle source
# File lib/rubocop/cop/commissioner.rb, line 105
def reset
  @errors = []
end
restrict_callbacks(callbacks) click to toggle source
# File lib/rubocop/cop/commissioner.rb, line 124
def restrict_callbacks(callbacks)
  restricted = {}
  RESTRICTED_CALLBACKS.each do |callback|
    restricted[callback] = restricted_map(callbacks[callback])
  end
  restricted
end
restricted_map(callbacks) click to toggle source

NOTE: mutates ‘callbacks` in place

# File lib/rubocop/cop/commissioner.rb, line 142
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) click to toggle source
# File lib/rubocop/cop/commissioner.rb, line 97
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) click to toggle source
# File lib/rubocop/cop/commissioner.rb, line 132
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) { || ... } click to toggle source

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.

# File lib/rubocop/cop/commissioner.rb, line 159
def with_cop_error_handling(cop, node = nil)
  yield
rescue StandardError => e
  raise e if @options[:raise_error]

  err = ErrorWithAnalyzedFileLocation.new(cause: e, node: node, cop: cop)
  @errors << err
end