From e98d8cd255ab5c2fee873a58af6c2c3ad561dab4 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 2 Sep 2018 16:36:03 +0300 Subject: nail down runnables --- crates/server/src/main_loop/handlers.rs | 76 ++++++++++++++++++++++++++++----- crates/server/src/project_model.rs | 4 +- crates/server/src/server_world.rs | 17 +++++++- 3 files changed, 83 insertions(+), 14 deletions(-) (limited to 'crates/server/src') diff --git a/crates/server/src/main_loop/handlers.rs b/crates/server/src/main_loop/handlers.rs index ab8b6f799..93d8bd9fe 100644 --- a/crates/server/src/main_loop/handlers.rs +++ b/crates/server/src/main_loop/handlers.rs @@ -16,6 +16,7 @@ use ::{ req::{self, Decoration}, Result, conv::{Conv, ConvWith, TryConvWith, MapConvWith, to_location}, server_world::ServerWorld, + project_model::TargetKind, }; pub fn handle_syntax_tree( @@ -233,6 +234,8 @@ pub fn handle_runnables( } } + let args = runnable_args(&world, file_id, &runnable.kind); + let r = req::Runnable { range: runnable.range.conv_with(&line_index), label: match &runnable.kind { @@ -242,17 +245,7 @@ pub fn handle_runnables( "run binary".to_string(), }, bin: "cargo".to_string(), - args: match runnable.kind { - RunnableKind::Test { name } => { - vec![ - "test".to_string(), - "--".to_string(), - name, - "--nocapture".to_string(), - ] - } - RunnableKind::Bin => vec!["run".to_string()] - }, + args, env: { let mut m = HashMap::new(); m.insert( @@ -265,6 +258,67 @@ pub fn handle_runnables( res.push(r); } return Ok(res); + + fn runnable_args(world: &ServerWorld, file_id: FileId, kind: &RunnableKind) -> Vec { + let spec = if let Some(&crate_id) = world.analysis().crate_for(file_id).first() { + let file_id = world.analysis().crate_root(crate_id); + let path = world.path_map.get_path(file_id); + world.workspaces.iter() + .filter_map(|ws| { + let tgt = ws.target_by_root(path)?; + Some((tgt.package(ws).name(ws).clone(), tgt.name(ws).clone(), tgt.kind(ws))) + }) + .next() + } else { + None + }; + let mut res = Vec::new(); + match kind { + RunnableKind::Test { name } => { + res.push("test".to_string()); + if let Some((pkg_name, tgt_name, tgt_kind)) = spec { + spec_args(pkg_name, tgt_name, tgt_kind, &mut res); + } + res.push("--".to_string()); + res.push(name.to_string()); + res.push("--nocapture".to_string()); + } + RunnableKind::Bin => { + res.push("run".to_string()); + if let Some((pkg_name, tgt_name, tgt_kind)) = spec { + spec_args(pkg_name, tgt_name, tgt_kind, &mut res); + } + } + } + res + } + + fn spec_args(pkg_name: &str, tgt_name: &str, tgt_kind: TargetKind, buf: &mut Vec) { + buf.push("--package".to_string()); + buf.push(pkg_name.to_string()); + match tgt_kind { + TargetKind::Bin => { + buf.push("--bin".to_string()); + buf.push(tgt_name.to_string()); + } + TargetKind::Test => { + buf.push("--test".to_string()); + buf.push(tgt_name.to_string()); + } + TargetKind::Bench => { + buf.push("--bench".to_string()); + buf.push(tgt_name.to_string()); + } + TargetKind::Example => { + buf.push("--example".to_string()); + buf.push(tgt_name.to_string()); + } + TargetKind::Lib => { + buf.push("--lib".to_string()); + } + TargetKind::Other => (), + } + } } pub fn handle_decorations( diff --git a/crates/server/src/project_model.rs b/crates/server/src/project_model.rs index 1c5954dad..12233f258 100644 --- a/crates/server/src/project_model.rs +++ b/crates/server/src/project_model.rs @@ -56,7 +56,7 @@ impl Package { } impl Target { - pub fn pkg(self, ws: &CargoWorkspace) -> Package { + pub fn package(self, ws: &CargoWorkspace) -> Package { ws.tgt(self).pkg } pub fn name(self, ws: &CargoWorkspace) -> &str { @@ -114,7 +114,7 @@ impl CargoWorkspace { pub fn ws_members<'a>(&'a self) -> impl Iterator + 'a { self.ws_members.iter().cloned() } - pub fn target_by_roo(&self, root: &Path) -> Option { + pub fn target_by_root(&self, root: &Path) -> Option { self.packages() .filter_map(|pkg| pkg.targets(self).find(|it| it.root(self) == root)) .next() diff --git a/crates/server/src/server_world.rs b/crates/server/src/server_world.rs index 4d5c50428..f78b56cf8 100644 --- a/crates/server/src/server_world.rs +++ b/crates/server/src/server_world.rs @@ -6,7 +6,7 @@ use std::{ }; use languageserver_types::Url; -use libanalysis::{FileId, AnalysisHost, Analysis}; +use libanalysis::{FileId, AnalysisHost, Analysis, CrateGraph, CrateId}; use { Result, @@ -95,7 +95,22 @@ impl ServerWorldState { Ok(file_id) } pub fn set_workspaces(&mut self, ws: Vec) { + let mut crate_roots = HashMap::new(); + 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) { + let crate_id = CrateId(crate_roots.len() as u32); + crate_roots.insert(crate_id, file_id); + } + }); + let crate_graph = CrateGraph { crate_roots }; self.workspaces = Arc::new(ws); + self.analysis_host.set_crate_graph(crate_graph); } pub fn snapshot(&self) -> ServerWorld { ServerWorld { -- cgit v1.2.3