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!
This commit is contained in:
Aleksey Kladov 2021-08-22 13:32:00 +03:00
parent 5cef007bff
commit 881d71a489
9 changed files with 44 additions and 41 deletions

2
Cargo.lock generated
View file

@ -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",

View file

@ -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" }

View file

@ -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),

View file

@ -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))
}

View file

@ -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<ProcMacro>,
load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
) -> 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<CfgFlag>,
proc_macro_loader: &mut dyn FnMut(&AbsPath) -> Vec<ProcMacro>,
load_proc_macro: &mut dyn FnMut(&AbsPath) -> Vec<ProcMacro>,
load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
project: &ProjectJson,
sysroot: &Option<Sysroot>,
@ -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<CfgFlag>,
override_cfg: &CfgOverrides,
proc_macro_loader: &mut dyn FnMut(&AbsPath) -> Vec<ProcMacro>,
load_proc_macro: &mut dyn FnMut(&AbsPath) -> Vec<ProcMacro>,
load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
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<FileId>,
crate_graph: &mut CrateGraph,
cfg_options: &CfgOptions,
proc_macro_loader: &mut dyn FnMut(&AbsPath) -> Vec<ProcMacro>,
load_proc_macro: &mut dyn FnMut(&AbsPath) -> Vec<ProcMacro>,
pkg_to_lib_crate: &mut FxHashMap<la_arena::Idx<crate::PackageData>, 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<ProcMacro>,
load_proc_macro: &mut dyn FnMut(&AbsPath) -> Vec<ProcMacro>,
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());

View file

@ -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" }

View file

@ -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 {

View file

@ -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;

View file

@ -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);