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)
-
(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)
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)
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