From 32c067f8c9aec56bb502c5a569884679bae27af3 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 8 Dec 2018 21:54:00 +0300 Subject: track deps in project model --- crates/ra_lsp_server/src/project_model.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'crates/ra_lsp_server') diff --git a/crates/ra_lsp_server/src/project_model.rs b/crates/ra_lsp_server/src/project_model.rs index 3305d468a..22495f49c 100644 --- a/crates/ra_lsp_server/src/project_model.rs +++ b/crates/ra_lsp_server/src/project_model.rs @@ -28,6 +28,7 @@ struct PackageData { manifest: PathBuf, targets: Vec, is_member: bool, + dependencies: Vec, } #[derive(Debug, Clone)] @@ -106,6 +107,7 @@ impl CargoWorkspace { manifest: PathBuf::from(meta_pkg.manifest_path), targets: Vec::new(), is_member, + dependencies: Vec::new(), }; for meta_tgt in meta_pkg.targets { let tgt = Target(targets.len()); @@ -119,6 +121,14 @@ impl CargoWorkspace { } packages.push(pkg_data) } + let resolve = meta.resolve.expect("metadata executed with deps"); + for node in resolve.nodes { + let source = pkg_by_id[&node.id]; + for id in node.dependencies { + let target = pkg_by_id[&id]; + packages[source.0].dependencies.push(target); + } + } Ok(CargoWorkspace { packages, targets }) } -- cgit v1.2.3 From 9b1356464a834e0b9a88dd3eeabc50bf1d734f35 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 8 Dec 2018 23:16:11 +0300 Subject: propagate deps to CrateGraph --- crates/ra_lsp_server/src/project_model.rs | 15 +++++++++--- crates/ra_lsp_server/src/server_world.rs | 39 ++++++++++++++++++++++--------- 2 files changed, 40 insertions(+), 14 deletions(-) (limited to 'crates/ra_lsp_server') diff --git a/crates/ra_lsp_server/src/project_model.rs b/crates/ra_lsp_server/src/project_model.rs index 22495f49c..5da71b9f5 100644 --- a/crates/ra_lsp_server/src/project_model.rs +++ b/crates/ra_lsp_server/src/project_model.rs @@ -1,6 +1,5 @@ use std::path::{Path, PathBuf}; -use serde_derive::Serialize; use cargo_metadata::{metadata_run, CargoOpt}; use ra_syntax::SmolStr; use rustc_hash::{FxHashMap, FxHashSet}; @@ -11,15 +10,22 @@ use crate::{ thread_watcher::{ThreadWatcher, Worker}, }; +/// `CargoWorksapce` represents the logical structure of, well, a Cargo +/// workspace. It pretty closely mirrors `cargo metadata` output. +/// +/// Note that internally, rust analyzer uses a differnet structure: +/// `CrateGraph`. `CrateGraph` is lower-level: it knows only about the crates, +/// while this knows about `Pacakges` & `Targets`: purely cargo-related +/// concepts. #[derive(Debug, Clone)] pub struct CargoWorkspace { packages: Vec, targets: Vec, } -#[derive(Clone, Copy, Debug, Serialize)] +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] pub struct Package(usize); -#[derive(Clone, Copy, Debug, Serialize)] +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] pub struct Target(usize); #[derive(Debug, Clone)] @@ -62,6 +68,9 @@ impl Package { pub fn is_member(self, ws: &CargoWorkspace) -> bool { ws.pkg(self).is_member } + pub fn dependencies<'a>(self, ws: &'a CargoWorkspace) -> impl Iterator + 'a { + ws.pkg(self).dependencies.iter().cloned() + } } impl Target { diff --git a/crates/ra_lsp_server/src/server_world.rs b/crates/ra_lsp_server/src/server_world.rs index c3f89ad5f..f2d602dc7 100644 --- a/crates/ra_lsp_server/src/server_world.rs +++ b/crates/ra_lsp_server/src/server_world.rs @@ -13,7 +13,7 @@ use failure::{bail, format_err}; use crate::{ path_map::{PathMap, Root}, - project_model::CargoWorkspace, + project_model::{CargoWorkspace, TargetKind}, vfs::{FileEvent, FileEventKind}, Result, }; @@ -142,17 +142,34 @@ impl ServerWorldState { } pub fn set_workspaces(&mut self, ws: Vec) { let mut crate_graph = CrateGraph::default(); - ws.iter() - .flat_map(|ws| { - ws.packages() - .flat_map(move |pkg| pkg.targets(ws)) - .map(move |tgt| tgt.root(ws)) - }) - .for_each(|root| { - if let Some(file_id) = self.path_map.get_id(root) { - crate_graph.add_crate_root(file_id); + let mut pkg_to_lib_crate = FxHashMap::default(); + let mut pkg_crates = FxHashMap::default(); + for ws in ws.iter() { + for pkg in ws.packages() { + for tgt in pkg.targets(ws) { + let root = tgt.root(ws); + if let Some(file_id) = self.path_map.get_id(root) { + let crate_id = crate_graph.add_crate_root(file_id); + if tgt.kind(ws) == TargetKind::Lib { + pkg_to_lib_crate.insert(pkg, crate_id); + } + pkg_crates + .entry(pkg) + .or_insert_with(Vec::new) + .push(crate_id); + } + } + } + for pkg in ws.packages() { + for dep in pkg.dependencies(ws) { + if let Some(&to) = pkg_to_lib_crate.get(&dep) { + for &from in pkg_crates.get(&pkg).into_iter().flatten() { + crate_graph.add_dep(from, to); + } + } } - }); + } + } self.workspaces = Arc::new(ws); let mut change = AnalysisChange::new(); change.set_crate_graph(crate_graph); -- cgit v1.2.3 From 961cae7e53a05625f3e010076673ca083479b481 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 9 Dec 2018 01:02:53 +0300 Subject: thread info about dep names --- crates/ra_lsp_server/src/project_model.rs | 19 +++++++++++++++---- crates/ra_lsp_server/src/server_world.rs | 4 ++-- 2 files changed, 17 insertions(+), 6 deletions(-) (limited to 'crates/ra_lsp_server') diff --git a/crates/ra_lsp_server/src/project_model.rs b/crates/ra_lsp_server/src/project_model.rs index 5da71b9f5..cb91ada90 100644 --- a/crates/ra_lsp_server/src/project_model.rs +++ b/crates/ra_lsp_server/src/project_model.rs @@ -34,7 +34,13 @@ struct PackageData { manifest: PathBuf, targets: Vec, is_member: bool, - dependencies: Vec, + dependencies: Vec, +} + +#[derive(Debug, Clone)] +pub struct PackageDependency { + pub pkg: Package, + pub name: SmolStr, } #[derive(Debug, Clone)] @@ -68,8 +74,11 @@ impl Package { pub fn is_member(self, ws: &CargoWorkspace) -> bool { ws.pkg(self).is_member } - pub fn dependencies<'a>(self, ws: &'a CargoWorkspace) -> impl Iterator + 'a { - ws.pkg(self).dependencies.iter().cloned() + pub fn dependencies<'a>( + self, + ws: &'a CargoWorkspace, + ) -> impl Iterator + 'a { + ws.pkg(self).dependencies.iter() } } @@ -135,7 +144,9 @@ impl CargoWorkspace { let source = pkg_by_id[&node.id]; for id in node.dependencies { let target = pkg_by_id[&id]; - packages[source.0].dependencies.push(target); + let name: SmolStr = packages[target.0].name.replace('-', "_").into(); + let dep = PackageDependency { name, pkg: target }; + packages[source.0].dependencies.push(dep); } } diff --git a/crates/ra_lsp_server/src/server_world.rs b/crates/ra_lsp_server/src/server_world.rs index f2d602dc7..ab4c2c8aa 100644 --- a/crates/ra_lsp_server/src/server_world.rs +++ b/crates/ra_lsp_server/src/server_world.rs @@ -162,9 +162,9 @@ impl ServerWorldState { } for pkg in ws.packages() { for dep in pkg.dependencies(ws) { - if let Some(&to) = pkg_to_lib_crate.get(&dep) { + if let Some(&to) = pkg_to_lib_crate.get(&dep.pkg) { for &from in pkg_crates.get(&pkg).into_iter().flatten() { - crate_graph.add_dep(from, to); + crate_graph.add_dep(from, dep.name.clone(), to); } } } -- cgit v1.2.3