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 98

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 121

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 116

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 79

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

#invoke(callback, cops) (private)

[ GitHub ]

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

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 163

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 112

def reset
  @errors = []
end

#restrict_callbacks(callbacks) (private)

[ GitHub ]

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

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 149

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 104

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 139

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 170

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