analyzed-ra 0.4.0

Patched rust-analyzer bridge crate for analyzed
Documentation
use std::time::Duration;

use hir::ChangeWithProcMacros;
use ide_db::base_db::ProcMacroPaths;
use project_model::WorkspaceBuildScripts;
use stdx::thread::ThreadIntent;
use triomphe::Arc;
use vfs::AbsPathBuf;

use crate::{
    config::Config,
    global_state::{FetchBuildDataResponse, FetchWorkspaceRequest, FetchWorkspaceResponse, GlobalState},
    main_loop::Task,
    op_queue::Cause,
    reload::ProjectWorkspaceProgress,
};

impl GlobalState {
    pub(crate) fn update_configuration(&mut self, config: Config) {
        let _p = tracing::info_span!("GlobalState::update_configuration").entered();
        let old_config = std::mem::replace(&mut self.config, Arc::new(config));
        if self.config.linked_or_discovered_projects() != old_config.linked_or_discovered_projects()
        {
            let req = FetchWorkspaceRequest { path: None, force_crate_graph_reload: false };
            self.fetch_workspaces_queue.request_op("discovered projects changed".to_owned(), req)
        } else if self.config.flycheck(None) != old_config.flycheck(None) {
            self.reload_flycheck();
        }

        if self.config.cargo(None) != old_config.cargo(None) {
            let req = FetchWorkspaceRequest { path: None, force_crate_graph_reload: false };
            self.fetch_workspaces_queue.request_op("cargo config changed".to_owned(), req)
        }

        if self.config.cfg_set_test(None) != old_config.cfg_set_test(None) {
            let req = FetchWorkspaceRequest { path: None, force_crate_graph_reload: false };
            self.fetch_workspaces_queue.request_op("cfg_set_test config changed".to_owned(), req)
        }
    }

    pub(crate) fn fetch_workspaces(
        &mut self,
        cause: Cause,
        path: Option<AbsPathBuf>,
        force_crate_graph_reload: bool,
    ) {
        tracing::info!(%cause, "will fetch workspaces");
        let reload_path = path.clone();

        let provider = self.provider.clone();
        let shared_context = crate::shared_analyzer::shared_analyzer_context_from_config(&self.config);
        let current_shared = self.shared.clone();
        self.task_pool.handle.spawn_with_sender(ThreadIntent::Worker, move |sender| {
            if sender.send(Task::FetchWorkspace(ProjectWorkspaceProgress::Begin)).is_err() {
                return;
            }
            let response = match shared_context {
                Ok((key, config)) => provider
                    .resolve_reloading(key, config, reload_path)
                    .and_then(|session| {
                        let shared = session.runtime();
                        let workspaces = session.workspaces()?;
                        Ok(FetchWorkspaceResponse {
                            workspaces: workspaces.into_iter().map(Ok).collect(),
                            force_crate_graph_reload,
                            shared,
                        })
                    })
                    .unwrap_or_else(|error| FetchWorkspaceResponse {
                        workspaces: vec![Err(error)],
                        force_crate_graph_reload,
                        shared: current_shared.clone(),
                    }),
                Err(error) => FetchWorkspaceResponse {
                    workspaces: vec![Err(error)],
                    force_crate_graph_reload,
                    shared: current_shared.clone(),
                },
            };
            _ = sender.send(Task::FetchedWorkspace(response));
        });
    }

    pub(crate) fn recreate_crate_graph_from_shared(
        &mut self,
        cause: String,
        switching_from_empty_workspace: bool,
    ) -> Option<Duration> {
        if let Some(FetchWorkspaceResponse { shared, .. }) =
            self.fetch_workspaces_queue.last_op_result()
        {
            self.shared = shared.clone();
        }
        self.reload_config_from_shared();
        self.recreate_crate_graph(cause, switching_from_empty_workspace)
    }

    pub(crate) fn recreate_crate_graph(
        &mut self,
        cause: String,
        initial_build: bool,
    ) -> Option<Duration> {
        let _ = (cause, initial_build);
        self.detached_files = self
            .workspaces
            .iter()
            .filter_map(|ws| match &ws.kind {
                project_model::ProjectWorkspaceKind::DetachedFile { file, .. } => Some(file.clone()),
                _ => None,
            })
            .collect();
        self.incomplete_crate_graph = false;
        self.finish_loading_crate_graph()
    }

    pub(crate) fn fetch_build_data(&mut self, cause: Cause) {
        let _ = cause;
        let workspaces = Arc::new(self.workspaces.as_ref().clone());
        let response = FetchBuildDataResponse {
            build_scripts: workspaces.iter().map(|_| Ok(WorkspaceBuildScripts::default())).collect(),
            workspaces,
        };
        self.fetch_build_data_queue.op_completed(response);
    }

    pub(crate) fn fetch_proc_macros(
        &mut self,
        cause: Cause,
        change: ChangeWithProcMacros,
        paths: Vec<ProcMacroPaths>,
    ) {
        let _ = (cause, change, paths);
        self.fetch_proc_macros_queue.op_completed(true);
    }
}