From dc90e0b5a5d4f2255d6f0b82204f26cbaafbdd46 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 17 Jun 2020 17:51:46 +0200 Subject: Better encapsulate reverse-mapping of files to cargo targets We need to find a better way to do it... CrateGraph by itself is fine, CargoWorkspace as well, but the mapping between the two seems arbitrary... --- crates/rust-analyzer/src/cargo_target_spec.rs | 32 ++++++++++++--------------- crates/rust-analyzer/src/global_state.rs | 22 +++++++++++++----- 2 files changed, 30 insertions(+), 24 deletions(-) (limited to 'crates') diff --git a/crates/rust-analyzer/src/cargo_target_spec.rs b/crates/rust-analyzer/src/cargo_target_spec.rs index 44f856f6b..5c22dce0d 100644 --- a/crates/rust-analyzer/src/cargo_target_spec.rs +++ b/crates/rust-analyzer/src/cargo_target_spec.rs @@ -2,7 +2,7 @@ use ra_cfg::CfgExpr; use ra_ide::{FileId, RunnableKind, TestId}; -use ra_project_model::{self, ProjectWorkspace, TargetKind}; +use ra_project_model::{self, TargetKind}; use crate::{global_state::GlobalStateSnapshot, Result}; @@ -89,27 +89,23 @@ impl CargoTargetSpec { } pub(crate) fn for_file( - world: &GlobalStateSnapshot, + global_state_snapshot: &GlobalStateSnapshot, file_id: FileId, ) -> Result> { - let &crate_id = match world.analysis().crate_for(file_id)?.first() { - Some(crate_id) => crate_id, + let crate_id = match global_state_snapshot.analysis().crate_for(file_id)?.first() { + Some(crate_id) => *crate_id, None => return Ok(None), }; - let file_id = world.analysis().crate_root(crate_id)?; - let path = world.file_id_to_path(file_id); - let res = world.workspaces.iter().find_map(|ws| match ws { - ProjectWorkspace::Cargo { cargo, .. } => { - let tgt = cargo.target_by_root(&path)?; - Some(CargoTargetSpec { - package: cargo.package_flag(&cargo[cargo[tgt].package]), - target: cargo[tgt].name.clone(), - target_kind: cargo[tgt].kind, - }) - } - ProjectWorkspace::Json { .. } => None, - }); - Ok(res) + let (cargo_ws, target) = match global_state_snapshot.cargo_target_for_crate_root(crate_id) { + Some(it) => it, + None => return Ok(None), + }; + let res = CargoTargetSpec { + package: cargo_ws.package_flag(&cargo_ws[cargo_ws[target].package]), + target: cargo_ws[target].name.clone(), + target_kind: cargo_ws[target].kind, + }; + Ok(Some(res)) } pub(crate) fn push_to(self, buf: &mut Vec, kind: &RunnableKind) { diff --git a/crates/rust-analyzer/src/global_state.rs b/crates/rust-analyzer/src/global_state.rs index 73ca2a709..ef6c7d44d 100644 --- a/crates/rust-analyzer/src/global_state.rs +++ b/crates/rust-analyzer/src/global_state.rs @@ -15,7 +15,7 @@ use ra_flycheck::{Flycheck, FlycheckConfig}; use ra_ide::{ Analysis, AnalysisChange, AnalysisHost, CrateGraph, FileId, LibraryData, SourceRootId, }; -use ra_project_model::{ProcMacroClient, ProjectWorkspace}; +use ra_project_model::{CargoWorkspace, ProcMacroClient, ProjectWorkspace, Target}; use ra_vfs::{LineEndings, RootEntry, Vfs, VfsChange, VfsFile, VfsTask, Watch}; use relative_path::RelativePathBuf; use stdx::format_to; @@ -28,7 +28,7 @@ use crate::{ vfs_glob::{Glob, RustPackageFilterBuilder}, LspError, Result, }; -use ra_db::ExternSourceId; +use ra_db::{CrateId, ExternSourceId}; use rustc_hash::{FxHashMap, FxHashSet}; fn create_flycheck(workspaces: &[ProjectWorkspace], config: &FlycheckConfig) -> Option { @@ -290,10 +290,6 @@ impl GlobalStateSnapshot { file_id_to_url(&self.vfs.read(), id) } - pub fn file_id_to_path(&self, id: FileId) -> PathBuf { - self.vfs.read().file2path(VfsFile(id.0)) - } - pub fn file_line_endings(&self, id: FileId) -> LineEndings { self.vfs.read().file_line_endings(VfsFile(id.0)) } @@ -305,6 +301,20 @@ impl GlobalStateSnapshot { url_from_abs_path(&path) } + pub(crate) fn cargo_target_for_crate_root( + &self, + crate_id: CrateId, + ) -> Option<(&CargoWorkspace, Target)> { + let file_id = self.analysis().crate_root(crate_id).ok()?; + let path = self.vfs.read().file2path(VfsFile(file_id.0)); + self.workspaces.iter().find_map(|ws| match ws { + ProjectWorkspace::Cargo { cargo, .. } => { + cargo.target_by_root(&path).map(|it| (cargo, it)) + } + ProjectWorkspace::Json { .. } => None, + }) + } + pub fn status(&self) -> String { let mut buf = String::new(); if self.workspaces.is_empty() { -- cgit v1.2.3