use crossbeam_channel::{unbounded, Receiver, Sender};
use flycheck::FlycheckHandle;
use ide::{Analysis, AnalysisHost, Cancellable, Change, FileId};
-use ide_db::base_db::{CrateId, VfsPath};
+use ide_db::base_db::CrateId;
use lsp_types::{SemanticTokens, Url};
use parking_lot::{Mutex, RwLock};
use project_model::{
- BuildDataCollector, BuildDataResult, CargoWorkspace, ProcMacroClient, ProjectWorkspace, Target,
+ CargoWorkspace, ProcMacroClient, ProjectWorkspace, Target, WorkspaceBuildScripts,
};
use rustc_hash::FxHashMap;
use vfs::AnchoredPathBuf;
use crate::{
config::Config,
diagnostics::{CheckFixes, DiagnosticCollection},
- document::DocumentData,
from_proto,
line_index::{LineEndings, LineIndex},
lsp_ext,
main_loop::Task,
+ mem_docs::MemDocs,
op_queue::OpQueue,
reload::SourceRootConfig,
request_metrics::{LatestRequests, RequestMetrics},
pub(crate) config: Arc<Config>,
pub(crate) analysis_host: AnalysisHost,
pub(crate) diagnostics: DiagnosticCollection,
- pub(crate) mem_docs: FxHashMap<VfsPath, DocumentData>,
+ pub(crate) mem_docs: MemDocs,
pub(crate) semantic_tokens_cache: Arc<Mutex<FxHashMap<Url, SemanticTokens>>>,
pub(crate) shutdown_requested: bool,
pub(crate) last_reported_status: Option<lsp_ext::ServerStatusParams>,
pub(crate) vfs_progress_n_total: usize,
pub(crate) vfs_progress_n_done: usize,
- /// For both `workspaces` and `workspace_build_data`, the field stores the
- /// data we actually use, while the `OpQueue` stores the result of the last
- /// fetch.
+ /// `workspaces` field stores the data we actually use, while the `OpQueue`
+ /// stores the result of the last fetch.
///
- /// If the fetch (partially) fails, we do not update the values.
+ /// If the fetch (partially) fails, we do not update the current value.
+ ///
+ /// The handling of build data is subtle. We fetch workspace in two phases:
+ ///
+ /// *First*, we run `cargo metadata`, which gives us fast results for
+ /// initial analysis.
+ ///
+ /// *Second*, we run `cargo check` which runs build scripts and compiles
+ /// proc macros.
+ ///
+ /// We need both for the precise analysis, but we want rust-analyzer to be
+ /// at least partially available just after the first phase. That's because
+ /// first phase is much faster, and is much less likely to fail.
+ ///
+ /// This creates a complication -- by the time the second phase completes,
+ /// the results of the fist phase could be invalid. That is, while we run
+ /// `cargo check`, the user edits `Cargo.toml`, we notice this, and the new
+ /// `cargo metadata` completes before `cargo check`.
+ ///
+ /// An additional complication is that we want to avoid needless work. When
+ /// the user just adds comments or whitespace to Cargo.toml, we do not want
+ /// to invalidate any salsa caches.
pub(crate) workspaces: Arc<Vec<ProjectWorkspace>>,
- pub(crate) fetch_workspaces_queue: OpQueue<(), Vec<anyhow::Result<ProjectWorkspace>>>,
- pub(crate) workspace_build_data: Option<BuildDataResult>,
+ pub(crate) fetch_workspaces_queue: OpQueue<Vec<anyhow::Result<ProjectWorkspace>>>,
pub(crate) fetch_build_data_queue:
- OpQueue<BuildDataCollector, Option<anyhow::Result<BuildDataResult>>>,
- pub(crate) prime_caches_queue: OpQueue<(), ()>,
+ OpQueue<(Arc<Vec<ProjectWorkspace>>, Vec<anyhow::Result<WorkspaceBuildScripts>>)>,
+
+ pub(crate) prime_caches_queue: OpQueue<()>,
latest_requests: Arc<RwLock<LatestRequests>>,
}
pub(crate) analysis: Analysis,
pub(crate) check_fixes: CheckFixes,
pub(crate) latest_requests: Arc<RwLock<LatestRequests>>,
- mem_docs: FxHashMap<VfsPath, DocumentData>,
+ mem_docs: MemDocs,
pub(crate) semantic_tokens_cache: Arc<Mutex<FxHashMap<Url, SemanticTokens>>>,
vfs: Arc<RwLock<(vfs::Vfs, FxHashMap<FileId, LineEndings>)>>,
pub(crate) workspaces: Arc<Vec<ProjectWorkspace>>,
config: Arc::new(config.clone()),
analysis_host,
diagnostics: Default::default(),
- mem_docs: FxHashMap::default(),
+ mem_docs: MemDocs::default(),
semantic_tokens_cache: Arc::new(Default::default()),
shutdown_requested: false,
last_reported_status: None,
workspaces: Arc::new(Vec::new()),
fetch_workspaces_queue: OpQueue::default(),
- workspace_build_data: None,
prime_caches_queue: OpQueue::default(),
fetch_build_data_queue: OpQueue::default(),