X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;ds=sidebyside;f=crates%2Frust-analyzer%2Fsrc%2Fcli%2Fload_cargo.rs;h=b5f5519b43ef2b856fec20c3f5548cec07c04b64;hb=c9b4ac5be4daaabc062ab1ee663eba8594750003;hp=16ccab7817f14d577378ec1caecddd5dc38926d9;hpb=0e760a6ad20f023590147115fc8ca5d8d2559521;p=rust.git diff --git a/crates/rust-analyzer/src/cli/load_cargo.rs b/crates/rust-analyzer/src/cli/load_cargo.rs index 16ccab7817f..b5f5519b43e 100644 --- a/crates/rust-analyzer/src/cli/load_cargo.rs +++ b/crates/rust-analyzer/src/cli/load_cargo.rs @@ -4,26 +4,41 @@ use anyhow::Result; use crossbeam_channel::{unbounded, Receiver}; +use hir::db::DefDatabase; use ide::{AnalysisHost, Change}; use ide_db::base_db::CrateGraph; -use project_model::{CargoConfig, ProcMacroClient, ProjectManifest, ProjectWorkspace}; +use project_model::{ + BuildDataCollector, CargoConfig, ProcMacroClient, ProjectManifest, ProjectWorkspace, +}; use vfs::{loader::Handle, AbsPath, AbsPathBuf}; use crate::reload::{ProjectFolders, SourceRootConfig}; -pub fn load_cargo( +pub(crate) struct LoadCargoConfig { + pub(crate) load_out_dirs_from_check: bool, + pub(crate) wrap_rustc: bool, + pub(crate) with_proc_macro: bool, + pub(crate) prefill_caches: bool, +} + +pub(crate) fn load_workspace_at( root: &Path, - load_out_dirs_from_check: bool, - with_proc_macro: bool, -) -> Result<(AnalysisHost, vfs::Vfs)> { + cargo_config: &CargoConfig, + load_config: &LoadCargoConfig, + progress: &dyn Fn(String), +) -> Result<(AnalysisHost, vfs::Vfs, Option)> { let root = AbsPathBuf::assert(std::env::current_dir()?.join(root)); let root = ProjectManifest::discover_single(&root)?; - let ws = ProjectWorkspace::load( - root, - &CargoConfig { load_out_dirs_from_check, ..Default::default() }, - &|_| {}, - )?; + let workspace = ProjectWorkspace::load(root, cargo_config, progress)?; + + load_workspace(workspace, load_config, progress) +} +fn load_workspace( + ws: ProjectWorkspace, + config: &LoadCargoConfig, + progress: &dyn Fn(String), +) -> Result<(AnalysisHost, vfs::Vfs, Option)> { let (sender, receiver) = unbounded(); let mut vfs = vfs::Vfs::default(); let mut loader = { @@ -32,29 +47,50 @@ pub fn load_cargo( Box::new(loader) }; - let proc_macro_client = if with_proc_macro { + let proc_macro_client = if config.with_proc_macro { let path = std::env::current_exe()?; Some(ProcMacroClient::extern_process(path, &["proc-macro"]).unwrap()) } else { None }; - let crate_graph = ws.to_crate_graph(proc_macro_client.as_ref(), &mut |path: &AbsPath| { - let contents = loader.load_sync(path); - let path = vfs::VfsPath::from(path.to_path_buf()); - vfs.set_file_contents(path.clone(), contents); - vfs.file_id(&path) - }); + let build_data = if config.load_out_dirs_from_check { + let mut collector = BuildDataCollector::new(config.wrap_rustc); + ws.collect_build_data_configs(&mut collector); + Some(collector.collect(progress)?) + } else { + None + }; - let project_folders = ProjectFolders::new(&[ws]); - loader.set_config(vfs::loader::Config { load: project_folders.load, watch: vec![] }); + let crate_graph = ws.to_crate_graph( + build_data.as_ref(), + proc_macro_client.as_ref(), + &mut |path: &AbsPath| { + let contents = loader.load_sync(path); + let path = vfs::VfsPath::from(path.to_path_buf()); + vfs.set_file_contents(path.clone(), contents); + vfs.file_id(&path) + }, + ); + + let project_folders = ProjectFolders::new(&[ws], &[], build_data.as_ref()); + loader.set_config(vfs::loader::Config { + load: project_folders.load, + watch: vec![], + version: 0, + }); log::debug!("crate graph: {:?}", crate_graph); - let host = load(crate_graph, project_folders.source_root_config, &mut vfs, &receiver); - Ok((host, vfs)) + let host = + load_crate_graph(crate_graph, project_folders.source_root_config, &mut vfs, &receiver); + + if config.prefill_caches { + host.analysis().prime_caches(|_| {})?; + } + Ok((host, vfs, proc_macro_client)) } -fn load( +fn load_crate_graph( crate_graph: CrateGraph, source_root_config: SourceRootConfig, vfs: &mut vfs::Vfs, @@ -64,10 +100,12 @@ fn load( let mut host = AnalysisHost::new(lru_cap); let mut analysis_change = Change::new(); + host.raw_database_mut().set_enable_proc_attr_macros(true); + // wait until Vfs has loaded all roots for task in receiver { match task { - vfs::loader::Message::Progress { n_done, n_total } => { + vfs::loader::Message::Progress { n_done, n_total, config_version: _ } => { if n_done == n_total { break; } @@ -88,7 +126,7 @@ fn load( } } } - let source_roots = source_root_config.partition(&vfs); + let source_roots = source_root_config.partition(vfs); analysis_change.set_roots(source_roots); analysis_change.set_crate_graph(crate_graph); @@ -104,11 +142,22 @@ mod tests { use hir::Crate; #[test] - fn test_loading_rust_analyzer() { + fn test_loading_rust_analyzer() -> Result<()> { let path = Path::new(env!("CARGO_MANIFEST_DIR")).parent().unwrap().parent().unwrap(); - let (host, _vfs) = load_cargo(path, false, false).unwrap(); + let cargo_config = Default::default(); + let load_cargo_config = LoadCargoConfig { + load_out_dirs_from_check: false, + wrap_rustc: false, + with_proc_macro: false, + prefill_caches: false, + }; + let (host, _vfs, _proc_macro) = + load_workspace_at(path, &cargo_config, &load_cargo_config, &|_| {})?; + let n_crates = Crate::all(host.raw_database()).len(); // RA has quite a few crates, but the exact count doesn't matter assert!(n_crates > 20); + + Ok(()) } }