From 516fe293a8146044b6398b8da0b4da43874a2cf9 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 19 Mar 2020 17:53:31 +0100 Subject: More direct CargoWorkspace --- crates/ra_project_model/src/cargo_workspace.rs | 105 ++++++++++--------------- crates/ra_project_model/src/lib.rs | 40 +++++----- 2 files changed, 61 insertions(+), 84 deletions(-) (limited to 'crates/ra_project_model/src') diff --git a/crates/ra_project_model/src/cargo_workspace.rs b/crates/ra_project_model/src/cargo_workspace.rs index 10ecfa951..43dbd096a 100644 --- a/crates/ra_project_model/src/cargo_workspace.rs +++ b/crates/ra_project_model/src/cargo_workspace.rs @@ -1,6 +1,9 @@ //! FIXME: write short doc here -use std::path::{Path, PathBuf}; +use std::{ + ops, + path::{Path, PathBuf}, +}; use anyhow::{Context, Result}; use cargo_metadata::{CargoOpt, Message, MetadataCommand, PackageId}; @@ -24,6 +27,20 @@ pub struct CargoWorkspace { workspace_root: PathBuf, } +impl ops::Index for CargoWorkspace { + type Output = PackageData; + fn index(&self, index: Package) -> &PackageData { + &self.packages[index] + } +} + +impl ops::Index for CargoWorkspace { + type Output = TargetData; + fn index(&self, index: Target) -> &TargetData { + &self.targets[index] + } +} + #[derive(Deserialize, Clone, Debug, PartialEq, Eq)] #[serde(rename_all = "camelCase", default)] pub struct CargoFeatures { @@ -61,15 +78,15 @@ pub struct Target(RawId); impl_arena_id!(Target); #[derive(Debug, Clone)] -struct PackageData { - name: String, - manifest: PathBuf, - targets: Vec, - is_member: bool, - dependencies: Vec, - edition: Edition, - features: Vec, - out_dir: Option, +pub struct PackageData { + pub name: String, + pub manifest: PathBuf, + pub targets: Vec, + pub is_member: bool, + pub dependencies: Vec, + pub edition: Edition, + pub features: Vec, + pub out_dir: Option, } #[derive(Debug, Clone)] @@ -79,12 +96,12 @@ pub struct PackageDependency { } #[derive(Debug, Clone)] -struct TargetData { - pkg: Package, - name: String, - root: PathBuf, - kind: TargetKind, - is_proc_macro: bool, +pub struct TargetData { + pub package: Package, + pub name: String, + pub root: PathBuf, + pub kind: TargetKind, + pub is_proc_macro: bool, } #[derive(Debug, Clone, Copy, PartialEq, Eq)] @@ -115,52 +132,9 @@ impl TargetKind { } } -impl Package { - pub fn name(self, ws: &CargoWorkspace) -> &str { - ws.packages[self].name.as_str() - } - pub fn root(self, ws: &CargoWorkspace) -> &Path { - ws.packages[self].manifest.parent().unwrap() - } - pub fn edition(self, ws: &CargoWorkspace) -> Edition { - ws.packages[self].edition - } - pub fn features(self, ws: &CargoWorkspace) -> &[String] { - &ws.packages[self].features - } - pub fn targets<'a>(self, ws: &'a CargoWorkspace) -> impl Iterator + 'a { - ws.packages[self].targets.iter().cloned() - } - #[allow(unused)] - pub fn is_member(self, ws: &CargoWorkspace) -> bool { - ws.packages[self].is_member - } - pub fn dependencies<'a>( - self, - ws: &'a CargoWorkspace, - ) -> impl Iterator + 'a { - ws.packages[self].dependencies.iter() - } - pub fn out_dir(self, ws: &CargoWorkspace) -> Option<&Path> { - ws.packages[self].out_dir.as_ref().map(PathBuf::as_path) - } -} - -impl Target { - pub fn package(self, ws: &CargoWorkspace) -> Package { - ws.targets[self].pkg - } - pub fn name(self, ws: &CargoWorkspace) -> &str { - ws.targets[self].name.as_str() - } - pub fn root(self, ws: &CargoWorkspace) -> &Path { - ws.targets[self].root.as_path() - } - pub fn kind(self, ws: &CargoWorkspace) -> TargetKind { - ws.targets[self].kind - } - pub fn is_proc_macro(self, ws: &CargoWorkspace) -> bool { - ws.targets[self].is_proc_macro +impl PackageData { + pub fn root(&self) -> &Path { + self.manifest.parent().unwrap() } } @@ -219,7 +193,7 @@ impl CargoWorkspace { for meta_tgt in meta_pkg.targets { let is_proc_macro = meta_tgt.kind.as_slice() == ["proc-macro"]; let tgt = targets.alloc(TargetData { - pkg, + package: pkg, name: meta_tgt.name, root: meta_tgt.src_path.clone(), kind: TargetKind::new(meta_tgt.kind.as_slice()), @@ -265,7 +239,10 @@ impl CargoWorkspace { } pub fn target_by_root(&self, root: &Path) -> Option { - self.packages().filter_map(|pkg| pkg.targets(self).find(|it| it.root(self) == root)).next() + self.packages() + .filter_map(|pkg| self[pkg].targets.iter().find(|&&it| self[it].root == root)) + .next() + .copied() } pub fn workspace_root(&self) -> &Path { diff --git a/crates/ra_project_model/src/lib.rs b/crates/ra_project_model/src/lib.rs index 081b1fec2..3c294e065 100644 --- a/crates/ra_project_model/src/lib.rs +++ b/crates/ra_project_model/src/lib.rs @@ -138,8 +138,8 @@ impl ProjectWorkspace { ProjectWorkspace::Cargo { cargo, sysroot } => { let mut roots = Vec::with_capacity(cargo.packages().len() + sysroot.crates().len()); for pkg in cargo.packages() { - let root = pkg.root(&cargo).to_path_buf(); - let member = pkg.is_member(&cargo); + let root = cargo[pkg].root().to_path_buf(); + let member = cargo[pkg].is_member; roots.push(PackageRoot::new(root, member)); } for krate in sysroot.crates() { @@ -164,7 +164,7 @@ impl ProjectWorkspace { ProjectWorkspace::Cargo { cargo, sysroot: _sysroot } => { let mut out_dirs = Vec::with_capacity(cargo.packages().len()); for pkg in cargo.packages() { - if let Some(out_dir) = pkg.out_dir(&cargo) { + if let Some(out_dir) = &cargo[pkg].out_dir { out_dirs.push(out_dir.to_path_buf()); } } @@ -309,18 +309,18 @@ impl ProjectWorkspace { // Next, create crates for each package, target pair for pkg in cargo.packages() { let mut lib_tgt = None; - for tgt in pkg.targets(&cargo) { - let root = tgt.root(&cargo); + for &tgt in cargo[pkg].targets.iter() { + let root = cargo[tgt].root.as_path(); if let Some(file_id) = load(root) { - let edition = pkg.edition(&cargo); + let edition = cargo[pkg].edition; let cfg_options = { let mut opts = default_cfg_options.clone(); - opts.insert_features(pkg.features(&cargo).iter().map(Into::into)); + opts.insert_features(cargo[pkg].features.iter().map(Into::into)); opts }; let mut env = Env::default(); let mut extern_source = ExternSource::default(); - if let Some(out_dir) = pkg.out_dir(cargo) { + if let Some(out_dir) = &cargo[pkg].out_dir { // FIXME: We probably mangle non UTF-8 paths here, figure out a better solution env.set("OUT_DIR", out_dir.to_string_lossy().to_string()); if let Some(&extern_source_id) = extern_source_roots.get(out_dir) { @@ -330,16 +330,16 @@ impl ProjectWorkspace { let crate_id = crate_graph.add_crate_root( file_id, edition, - Some(CrateName::normalize_dashes(pkg.name(&cargo))), + Some(CrateName::normalize_dashes(&cargo[pkg].name)), cfg_options, env, extern_source, ); - if tgt.kind(&cargo) == TargetKind::Lib { + if cargo[tgt].kind == TargetKind::Lib { lib_tgt = Some(crate_id); pkg_to_lib_crate.insert(pkg, crate_id); } - if tgt.is_proc_macro(&cargo) { + if cargo[tgt].is_proc_macro { if let Some(proc_macro) = libproc_macro { if crate_graph .add_dep( @@ -351,7 +351,7 @@ impl ProjectWorkspace { { log::error!( "cyclic dependency on proc_macro for {}", - pkg.name(&cargo) + &cargo[pkg].name ) } } @@ -371,7 +371,7 @@ impl ProjectWorkspace { // For root projects with dashes in their name, // cargo metadata does not do any normalization, // so we do it ourselves currently - CrateName::normalize_dashes(pkg.name(&cargo)), + CrateName::normalize_dashes(&cargo[pkg].name), to, ) .is_err() @@ -379,7 +379,7 @@ impl ProjectWorkspace { { log::error!( "cyclic dependency between targets of {}", - pkg.name(&cargo) + &cargo[pkg].name ) } } @@ -391,7 +391,7 @@ impl ProjectWorkspace { .add_dep(from, CrateName::new("core").unwrap(), core) .is_err() { - log::error!("cyclic dependency on core for {}", pkg.name(&cargo)) + log::error!("cyclic dependency on core for {}", &cargo[pkg].name) } } if let Some(alloc) = liballoc { @@ -399,7 +399,7 @@ impl ProjectWorkspace { .add_dep(from, CrateName::new("alloc").unwrap(), alloc) .is_err() { - log::error!("cyclic dependency on alloc for {}", pkg.name(&cargo)) + log::error!("cyclic dependency on alloc for {}", &cargo[pkg].name) } } if let Some(std) = libstd { @@ -407,7 +407,7 @@ impl ProjectWorkspace { .add_dep(from, CrateName::new("std").unwrap(), std) .is_err() { - log::error!("cyclic dependency on std for {}", pkg.name(&cargo)) + log::error!("cyclic dependency on std for {}", &cargo[pkg].name) } } } @@ -416,7 +416,7 @@ impl ProjectWorkspace { // Now add a dep edge from all targets of upstream to the lib // target of downstream. for pkg in cargo.packages() { - for dep in pkg.dependencies(&cargo) { + for dep in cargo[pkg].dependencies.iter() { if let Some(&to) = pkg_to_lib_crate.get(&dep.pkg) { for &from in pkg_crates.get(&pkg).into_iter().flatten() { if crate_graph @@ -425,8 +425,8 @@ impl ProjectWorkspace { { log::error!( "cyclic dependency {} -> {}", - pkg.name(&cargo), - dep.pkg.name(&cargo) + &cargo[pkg].name, + &cargo[dep.pkg].name ) } } -- cgit v1.2.3