From 881d71a48941b716c9887c1335de58dc0e1fbe6b Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 22 Aug 2021 13:32:00 +0300 Subject: [PATCH] internal: reduce crate interdependence I don't think there's anything wrong with project_model depending on proc_macro_api directly -- fundamentally, both are about gluing our pure data model to the messy outside world. However, it's easy enough to avoid the dependency, so why not. As an additional consideration, `proc_macro_api` now pulls in `base_db`. project_model should definitely not depend on that! --- Cargo.lock | 2 +- crates/project_model/Cargo.toml | 1 - crates/project_model/src/lib.rs | 2 -- crates/project_model/src/tests.rs | 4 +-- crates/project_model/src/workspace.rs | 29 +++++++++------------- crates/rust-analyzer/Cargo.toml | 2 ++ crates/rust-analyzer/src/cli/load_cargo.rs | 22 +++++++++------- crates/rust-analyzer/src/global_state.rs | 5 ++-- crates/rust-analyzer/src/reload.rs | 18 +++++++++----- 9 files changed, 44 insertions(+), 41 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cb154973fa..67119b892d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1192,7 +1192,6 @@ dependencies = [ "la-arena", "log", "paths", - "proc_macro_api", "profile", "rustc-hash", "semver", @@ -1329,6 +1328,7 @@ dependencies = [ "mimalloc", "oorandom", "parking_lot", + "proc_macro_api", "proc_macro_srv", "profile", "project_model", diff --git a/crates/project_model/Cargo.toml b/crates/project_model/Cargo.toml index 36ca83333d..732e4952fa 100644 --- a/crates/project_model/Cargo.toml +++ b/crates/project_model/Cargo.toml @@ -22,7 +22,6 @@ la-arena = { version = "0.2.0", path = "../../lib/arena" } cfg = { path = "../cfg", version = "0.0.0" } base_db = { path = "../base_db", version = "0.0.0" } toolchain = { path = "../toolchain", version = "0.0.0" } -proc_macro_api = { path = "../proc_macro_api", version = "0.0.0" } paths = { path = "../paths", version = "0.0.0" } stdx = { path = "../stdx", version = "0.0.0" } profile = { path = "../profile", version = "0.0.0" } diff --git a/crates/project_model/src/lib.rs b/crates/project_model/src/lib.rs index 09bf8bce69..e0fd75fcdc 100644 --- a/crates/project_model/src/lib.rs +++ b/crates/project_model/src/lib.rs @@ -50,8 +50,6 @@ pub use crate::{ workspace::{CfgOverrides, PackageRoot, ProjectWorkspace}, }; -pub use proc_macro_api::ProcMacroClient; - #[derive(Debug, Clone, PartialEq, Eq, Hash, Ord, PartialOrd)] pub enum ProjectManifest { ProjectJson(ManifestPath), diff --git a/crates/project_model/src/tests.rs b/crates/project_model/src/tests.rs index d13b968cc1..f2c998308f 100644 --- a/crates/project_model/src/tests.rs +++ b/crates/project_model/src/tests.rs @@ -84,9 +84,9 @@ fn rooted_project_json(data: ProjectJsonData) -> ProjectJson { } fn to_crate_graph(project_workspace: ProjectWorkspace) -> CrateGraph { - project_workspace.to_crate_graph(None, { + project_workspace.to_crate_graph(&mut |_| Vec::new(), &mut { let mut counter = 0; - &mut move |_path| { + move |_path| { counter += 1; Some(FileId(counter)) } diff --git a/crates/project_model/src/workspace.rs b/crates/project_model/src/workspace.rs index bf216342b3..d911209b07 100644 --- a/crates/project_model/src/workspace.rs +++ b/crates/project_model/src/workspace.rs @@ -8,7 +8,6 @@ use anyhow::{format_err, Context, Result}; use base_db::{CrateDisplayName, CrateGraph, CrateId, CrateName, Edition, Env, FileId, ProcMacro}; use cfg::{CfgDiff, CfgOptions}; use paths::{AbsPath, AbsPathBuf}; -use proc_macro_api::ProcMacroClient; use rustc_hash::{FxHashMap, FxHashSet}; use stdx::always; @@ -350,19 +349,15 @@ impl ProjectWorkspace { pub fn to_crate_graph( &self, - proc_macro_client: Option<&ProcMacroClient>, + load_proc_macro: &mut dyn FnMut(&AbsPath) -> Vec, load: &mut dyn FnMut(&AbsPath) -> Option, ) -> CrateGraph { let _p = profile::span("ProjectWorkspace::to_crate_graph"); - let proc_macro_loader = &mut |path: &AbsPath| match proc_macro_client { - Some(client) => client.by_dylib_path(path), - None => Vec::new(), - }; let mut crate_graph = match self { ProjectWorkspace::Json { project, sysroot, rustc_cfg } => project_json_to_crate_graph( rustc_cfg.clone(), - proc_macro_loader, + load_proc_macro, load, project, sysroot, @@ -377,7 +372,7 @@ impl ProjectWorkspace { } => cargo_to_crate_graph( rustc_cfg.clone(), cfg_overrides, - proc_macro_loader, + load_proc_macro, load, cargo, build_scripts, @@ -399,7 +394,7 @@ impl ProjectWorkspace { fn project_json_to_crate_graph( rustc_cfg: Vec, - proc_macro_loader: &mut dyn FnMut(&AbsPath) -> Vec, + load_proc_macro: &mut dyn FnMut(&AbsPath) -> Vec, load: &mut dyn FnMut(&AbsPath) -> Option, project: &ProjectJson, sysroot: &Option, @@ -419,7 +414,7 @@ fn project_json_to_crate_graph( }) .map(|(crate_id, krate, file_id)| { let env = krate.env.clone().into_iter().collect(); - let proc_macro = krate.proc_macro_dylib_path.clone().map(|it| proc_macro_loader(&it)); + let proc_macro = krate.proc_macro_dylib_path.clone().map(|it| load_proc_macro(&it)); let target_cfgs = match krate.target.as_deref() { Some(target) => { @@ -476,7 +471,7 @@ fn project_json_to_crate_graph( fn cargo_to_crate_graph( rustc_cfg: Vec, override_cfg: &CfgOverrides, - proc_macro_loader: &mut dyn FnMut(&AbsPath) -> Vec, + load_proc_macro: &mut dyn FnMut(&AbsPath) -> Vec, load: &mut dyn FnMut(&AbsPath) -> Option, cargo: &CargoWorkspace, build_scripts: &WorkspaceBuildScripts, @@ -528,7 +523,7 @@ fn cargo_to_crate_graph( &cargo[pkg], build_scripts.outputs.get(pkg), &cfg_options, - proc_macro_loader, + load_proc_macro, file_id, &cargo[tgt].name, ); @@ -599,7 +594,7 @@ fn cargo_to_crate_graph( load, &mut crate_graph, &cfg_options, - proc_macro_loader, + load_proc_macro, &mut pkg_to_lib_crate, &public_deps, cargo, @@ -658,7 +653,7 @@ fn handle_rustc_crates( load: &mut dyn FnMut(&AbsPath) -> Option, crate_graph: &mut CrateGraph, cfg_options: &CfgOptions, - proc_macro_loader: &mut dyn FnMut(&AbsPath) -> Vec, + load_proc_macro: &mut dyn FnMut(&AbsPath) -> Vec, pkg_to_lib_crate: &mut FxHashMap, CrateId>, public_deps: &[(CrateName, CrateId)], cargo: &CargoWorkspace, @@ -694,7 +689,7 @@ fn handle_rustc_crates( &rustc_workspace[pkg], None, cfg_options, - proc_macro_loader, + load_proc_macro, file_id, &rustc_workspace[tgt].name, ); @@ -750,7 +745,7 @@ fn add_target_crate_root( pkg: &PackageData, build_data: Option<&BuildScriptOutput>, cfg_options: &CfgOptions, - proc_macro_loader: &mut dyn FnMut(&AbsPath) -> Vec, + load_proc_macro: &mut dyn FnMut(&AbsPath) -> Vec, file_id: FileId, cargo_name: &str, ) -> CrateId { @@ -778,7 +773,7 @@ fn add_target_crate_root( let proc_macro = build_data .as_ref() .and_then(|it| it.proc_macro_dylib_path.as_ref()) - .map(|it| proc_macro_loader(it)) + .map(|it| load_proc_macro(it)) .unwrap_or_default(); let display_name = CrateDisplayName::from_canonical_name(cargo_name.to_string()); diff --git a/crates/rust-analyzer/Cargo.toml b/crates/rust-analyzer/Cargo.toml index b835500561..3c9e052a69 100644 --- a/crates/rust-analyzer/Cargo.toml +++ b/crates/rust-analyzer/Cargo.toml @@ -39,6 +39,7 @@ tracing = "0.1" tracing-subscriber = { version = "0.2", default-features = false, features = ["env-filter", "registry"] } tracing-tree = { version = "0.1.4" } always-assert = "0.1" + stdx = { path = "../stdx", version = "0.0.0" } flycheck = { path = "../flycheck", version = "0.0.0" } ide = { path = "../ide", version = "0.0.0" } @@ -51,6 +52,7 @@ vfs = { path = "../vfs", version = "0.0.0" } vfs-notify = { path = "../vfs-notify", version = "0.0.0" } cfg = { path = "../cfg", version = "0.0.0" } toolchain = { path = "../toolchain", version = "0.0.0" } +proc_macro_api = { path = "../proc_macro_api", version = "0.0.0" } # This should only be used in CLI ide_ssr = { path = "../ide_ssr", version = "0.0.0" } diff --git a/crates/rust-analyzer/src/cli/load_cargo.rs b/crates/rust-analyzer/src/cli/load_cargo.rs index dee92911e3..9fe81cc8f6 100644 --- a/crates/rust-analyzer/src/cli/load_cargo.rs +++ b/crates/rust-analyzer/src/cli/load_cargo.rs @@ -7,9 +7,8 @@ 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, WorkspaceBuildScripts, -}; +use proc_macro_api::ProcMacroClient; +use project_model::{CargoConfig, ProjectManifest, ProjectWorkspace, WorkspaceBuildScripts}; use vfs::{loader::Handle, AbsPath, AbsPathBuf}; use crate::reload::{ProjectFolders, SourceRootConfig}; @@ -69,12 +68,17 @@ pub fn load_workspace( WorkspaceBuildScripts::default() }); - 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 crate_graph = ws.to_crate_graph( + &mut |path: &AbsPath| { + proc_macro_client.as_ref().map(|it| it.by_dylib_path(path)).unwrap_or_default() + }, + &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], &[]); loader.set_config(vfs::loader::Config { diff --git a/crates/rust-analyzer/src/global_state.rs b/crates/rust-analyzer/src/global_state.rs index a7ebbcd28b..da224ed588 100644 --- a/crates/rust-analyzer/src/global_state.rs +++ b/crates/rust-analyzer/src/global_state.rs @@ -11,9 +11,8 @@ use ide::{Analysis, AnalysisHost, Cancellable, Change, FileId}; use ide_db::base_db::CrateId; use lsp_types::{SemanticTokens, Url}; use parking_lot::{Mutex, RwLock}; -use project_model::{ - CargoWorkspace, ProcMacroClient, ProjectWorkspace, Target, WorkspaceBuildScripts, -}; +use proc_macro_api::ProcMacroClient; +use project_model::{CargoWorkspace, ProjectWorkspace, Target, WorkspaceBuildScripts}; use rustc_hash::FxHashMap; use vfs::AnchoredPathBuf; diff --git a/crates/rust-analyzer/src/reload.rs b/crates/rust-analyzer/src/reload.rs index 0530bf14fc..f8c770ccf4 100644 --- a/crates/rust-analyzer/src/reload.rs +++ b/crates/rust-analyzer/src/reload.rs @@ -5,7 +5,8 @@ use flycheck::{FlycheckConfig, FlycheckHandle}; use hir::db::DefDatabase; use ide::Change; use ide_db::base_db::{CrateGraph, SourceRoot, VfsPath}; -use project_model::{ProcMacroClient, ProjectWorkspace, WorkspaceBuildScripts}; +use proc_macro_api::ProcMacroClient; +use project_model::{ProjectWorkspace, WorkspaceBuildScripts}; use vfs::{file_set::FileSetConfig, AbsPath, AbsPathBuf, ChangeKind}; use crate::{ @@ -396,11 +397,15 @@ impl GlobalState { // Create crate graph from all the workspaces let crate_graph = { - let mut crate_graph = CrateGraph::default(); + let proc_macro_client = self.proc_macro_client.as_ref(); + let mut load_proc_macro = move |path: &AbsPath| { + proc_macro_client.map(|it| it.by_dylib_path(path)).unwrap_or_default() + }; + let vfs = &mut self.vfs.write().0; let loader = &mut self.loader; let mem_docs = &self.mem_docs; - let mut load = |path: &AbsPath| { + let mut load = move |path: &AbsPath| { let _p = profile::span("GlobalState::load"); let vfs_path = vfs::VfsPath::from(path.to_path_buf()); if !mem_docs.contains(&vfs_path) { @@ -413,10 +418,11 @@ impl GlobalState { } res }; - for ws in self.workspaces.iter() { - crate_graph.extend(ws.to_crate_graph(self.proc_macro_client.as_ref(), &mut load)); - } + let mut crate_graph = CrateGraph::default(); + for ws in self.workspaces.iter() { + crate_graph.extend(ws.to_crate_graph(&mut load_proc_macro, &mut load)); + } crate_graph }; change.set_crate_graph(crate_graph);