class RubyLsp::Addon

def load_addons(global_state, outgoing_queue, include_project_addons: true)

: (GlobalState global_state, Thread::Queue outgoing_queue, ?include_project_addons: bool) -> Array[StandardError]
Discovers and loads all add-ons. Returns a list of errors when trying to require add-ons
def load_addons(global_state, outgoing_queue, include_project_addons: true)
  # Require all add-ons entry points, which should be placed under
  # `some_gem/lib/ruby_lsp/your_gem_name/addon.rb` or in the workspace under
  # `your_project/ruby_lsp/project_name/addon.rb`
  addon_files = Gem.find_files("ruby_lsp/**/addon.rb")
  if include_project_addons
    project_addons = Dir.glob("#{global_state.workspace_path}/**/ruby_lsp/**/addon.rb")
    bundle_path = Bundler.bundle_path.to_s
    gems_dir = Bundler.bundle_path.join("gems")
    # Create an array of rejection glob patterns to ignore add-ons already discovered through Gem.find_files if
    # they are also copied inside the workspace for whatever reason. We received reports of projects having gems
    # installed in vendor/bundle despite BUNDLE_PATH pointing elsewhere. Without this mechanism, we will
    # double-require the same add-on, potentially for different versions of the same gem, which leads to incorrect
    # behavior
    reject_glob_patterns = addon_files.map do |path|
      relative_gem_path = Pathname.new(path).relative_path_from(gems_dir)
      first_part, *parts = relative_gem_path.to_s.split(File::SEPARATOR)
      first_part&.gsub!(/-([0-9.]+)$/, "*")
      "**/#{first_part}/#{parts.join("/")}"
    end
    project_addons.reject! do |path|
      path.start_with?(bundle_path) ||
        reject_glob_patterns.any? { |pattern| File.fnmatch?(pattern, path, File::Constants::FNM_PATHNAME) }
    end
    addon_files.concat(project_addons)
  end
  errors = addon_files.filter_map do |addon_path|
    # Avoid requiring this file twice. This may happen if you're working on the Ruby LSP itself and at the same
    # time have `ruby-lsp` installed as a vendored gem
    next if File.basename(File.dirname(addon_path)) == "ruby_lsp"
    require File.expand_path(addon_path)
    nil
  rescue => e
    e
  end
  # Instantiate all discovered add-on classes
  self.addons = addon_classes.map(&:new)
  self.file_watcher_addons = addons.select { |addon| addon.respond_to?(:workspace_did_change_watched_files) }
  # Activate each one of the discovered add-ons. If any problems occur in the add-ons, we don't want to
  # fail to boot the server
  addons.each do |addon|
    addon.activate(global_state, outgoing_queue)
  rescue => e
    addon.add_error(e)
  end
  errors
end