diff options
author | Aleksey Kladov <[email protected]> | 2020-06-02 16:22:23 +0100 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2020-06-02 16:22:42 +0100 |
commit | 03039821195c9d9c4bbc1e4cbddb6378c43a6c52 (patch) | |
tree | 2fb425ca0ed235ae051d9ea0547ebf8664c3295d | |
parent | f137b3a4e626bdef165e0ad7c61c88c44797798e (diff) |
New runnables API
-rw-r--r-- | crates/ra_ide/src/display/navigation_target.rs | 66 | ||||
-rw-r--r-- | crates/ra_ide/src/runnables.rs | 25 | ||||
-rw-r--r-- | crates/rust-analyzer/src/lsp_ext.rs | 28 | ||||
-rw-r--r-- | crates/rust-analyzer/src/main_loop/handlers.rs | 41 | ||||
-rw-r--r-- | crates/rust-analyzer/src/to_proto.rs | 18 | ||||
-rw-r--r-- | editors/code/src/debug.ts | 12 | ||||
-rw-r--r-- | editors/code/src/lsp_ext.ts | 15 | ||||
-rw-r--r-- | editors/code/src/run.ts | 21 |
8 files changed, 108 insertions, 118 deletions
diff --git a/crates/ra_ide/src/display/navigation_target.rs b/crates/ra_ide/src/display/navigation_target.rs index 5da28edd2..c7bb1e69f 100644 --- a/crates/ra_ide/src/display/navigation_target.rs +++ b/crates/ra_ide/src/display/navigation_target.rs | |||
@@ -92,15 +92,16 @@ impl NavigationTarget { | |||
92 | let name = module.name(db).map(|it| it.to_string().into()).unwrap_or_default(); | 92 | let name = module.name(db).map(|it| it.to_string().into()).unwrap_or_default(); |
93 | if let Some(src) = module.declaration_source(db) { | 93 | if let Some(src) = module.declaration_source(db) { |
94 | let frange = original_range(db, src.as_ref().map(|it| it.syntax())); | 94 | let frange = original_range(db, src.as_ref().map(|it| it.syntax())); |
95 | return NavigationTarget::from_syntax( | 95 | let mut res = NavigationTarget::from_syntax( |
96 | frange.file_id, | 96 | frange.file_id, |
97 | name, | 97 | name, |
98 | None, | 98 | None, |
99 | frange.range, | 99 | frange.range, |
100 | src.value.syntax().kind(), | 100 | src.value.syntax().kind(), |
101 | src.value.doc_comment_text(), | ||
102 | src.value.short_label(), | ||
103 | ); | 101 | ); |
102 | res.docs = src.value.doc_comment_text(); | ||
103 | res.description = src.value.short_label(); | ||
104 | return res; | ||
104 | } | 105 | } |
105 | module.to_nav(db) | 106 | module.to_nav(db) |
106 | } | 107 | } |
@@ -130,11 +131,9 @@ impl NavigationTarget { | |||
130 | } | 131 | } |
131 | 132 | ||
132 | /// Allows `NavigationTarget` to be created from a `NameOwner` | 133 | /// Allows `NavigationTarget` to be created from a `NameOwner` |
133 | fn from_named( | 134 | pub(crate) fn from_named( |
134 | db: &RootDatabase, | 135 | db: &RootDatabase, |
135 | node: InFile<&dyn ast::NameOwner>, | 136 | node: InFile<&dyn ast::NameOwner>, |
136 | docs: Option<String>, | ||
137 | description: Option<String>, | ||
138 | ) -> NavigationTarget { | 137 | ) -> NavigationTarget { |
139 | //FIXME: use `_` instead of empty string | 138 | //FIXME: use `_` instead of empty string |
140 | let name = node.value.name().map(|it| it.text().clone()).unwrap_or_default(); | 139 | let name = node.value.name().map(|it| it.text().clone()).unwrap_or_default(); |
@@ -148,8 +147,6 @@ impl NavigationTarget { | |||
148 | focus_range, | 147 | focus_range, |
149 | frange.range, | 148 | frange.range, |
150 | node.value.syntax().kind(), | 149 | node.value.syntax().kind(), |
151 | docs, | ||
152 | description, | ||
153 | ) | 150 | ) |
154 | } | 151 | } |
155 | 152 | ||
@@ -159,8 +156,6 @@ impl NavigationTarget { | |||
159 | focus_range: Option<TextRange>, | 156 | focus_range: Option<TextRange>, |
160 | full_range: TextRange, | 157 | full_range: TextRange, |
161 | kind: SyntaxKind, | 158 | kind: SyntaxKind, |
162 | docs: Option<String>, | ||
163 | description: Option<String>, | ||
164 | ) -> NavigationTarget { | 159 | ) -> NavigationTarget { |
165 | NavigationTarget { | 160 | NavigationTarget { |
166 | file_id, | 161 | file_id, |
@@ -169,8 +164,8 @@ impl NavigationTarget { | |||
169 | full_range, | 164 | full_range, |
170 | focus_range, | 165 | focus_range, |
171 | container_name: None, | 166 | container_name: None, |
172 | description, | 167 | description: None, |
173 | docs, | 168 | docs: None, |
174 | } | 169 | } |
175 | } | 170 | } |
176 | } | 171 | } |
@@ -238,12 +233,11 @@ where | |||
238 | { | 233 | { |
239 | fn to_nav(&self, db: &RootDatabase) -> NavigationTarget { | 234 | fn to_nav(&self, db: &RootDatabase) -> NavigationTarget { |
240 | let src = self.source(db); | 235 | let src = self.source(db); |
241 | NavigationTarget::from_named( | 236 | let mut res = |
242 | db, | 237 | NavigationTarget::from_named(db, src.as_ref().map(|it| it as &dyn ast::NameOwner)); |
243 | src.as_ref().map(|it| it as &dyn ast::NameOwner), | 238 | res.docs = src.value.doc_comment_text(); |
244 | src.value.doc_comment_text(), | 239 | res.description = src.value.short_label(); |
245 | src.value.short_label(), | 240 | res |
246 | ) | ||
247 | } | 241 | } |
248 | } | 242 | } |
249 | 243 | ||
@@ -258,15 +252,7 @@ impl ToNav for hir::Module { | |||
258 | } | 252 | } |
259 | }; | 253 | }; |
260 | let frange = original_range(db, src.with_value(syntax)); | 254 | let frange = original_range(db, src.with_value(syntax)); |
261 | NavigationTarget::from_syntax( | 255 | NavigationTarget::from_syntax(frange.file_id, name, focus, frange.range, syntax.kind()) |
262 | frange.file_id, | ||
263 | name, | ||
264 | focus, | ||
265 | frange.range, | ||
266 | syntax.kind(), | ||
267 | None, | ||
268 | None, | ||
269 | ) | ||
270 | } | 256 | } |
271 | } | 257 | } |
272 | 258 | ||
@@ -285,8 +271,6 @@ impl ToNav for hir::ImplDef { | |||
285 | None, | 271 | None, |
286 | frange.range, | 272 | frange.range, |
287 | src.value.syntax().kind(), | 273 | src.value.syntax().kind(), |
288 | None, | ||
289 | None, | ||
290 | ) | 274 | ) |
291 | } | 275 | } |
292 | } | 276 | } |
@@ -296,12 +280,12 @@ impl ToNav for hir::Field { | |||
296 | let src = self.source(db); | 280 | let src = self.source(db); |
297 | 281 | ||
298 | match &src.value { | 282 | match &src.value { |
299 | FieldSource::Named(it) => NavigationTarget::from_named( | 283 | FieldSource::Named(it) => { |
300 | db, | 284 | let mut res = NavigationTarget::from_named(db, src.with_value(it)); |
301 | src.with_value(it), | 285 | res.docs = it.doc_comment_text(); |
302 | it.doc_comment_text(), | 286 | res.description = it.short_label(); |
303 | it.short_label(), | 287 | res |
304 | ), | 288 | } |
305 | FieldSource::Pos(it) => { | 289 | FieldSource::Pos(it) => { |
306 | let frange = original_range(db, src.with_value(it.syntax())); | 290 | let frange = original_range(db, src.with_value(it.syntax())); |
307 | NavigationTarget::from_syntax( | 291 | NavigationTarget::from_syntax( |
@@ -310,8 +294,6 @@ impl ToNav for hir::Field { | |||
310 | None, | 294 | None, |
311 | frange.range, | 295 | frange.range, |
312 | it.syntax().kind(), | 296 | it.syntax().kind(), |
313 | None, | ||
314 | None, | ||
315 | ) | 297 | ) |
316 | } | 298 | } |
317 | } | 299 | } |
@@ -322,12 +304,10 @@ impl ToNav for hir::MacroDef { | |||
322 | fn to_nav(&self, db: &RootDatabase) -> NavigationTarget { | 304 | fn to_nav(&self, db: &RootDatabase) -> NavigationTarget { |
323 | let src = self.source(db); | 305 | let src = self.source(db); |
324 | log::debug!("nav target {:#?}", src.value.syntax()); | 306 | log::debug!("nav target {:#?}", src.value.syntax()); |
325 | NavigationTarget::from_named( | 307 | let mut res = |
326 | db, | 308 | NavigationTarget::from_named(db, src.as_ref().map(|it| it as &dyn ast::NameOwner)); |
327 | src.as_ref().map(|it| it as &dyn ast::NameOwner), | 309 | res.docs = src.value.doc_comment_text(); |
328 | src.value.doc_comment_text(), | 310 | res |
329 | None, | ||
330 | ) | ||
331 | } | 311 | } |
332 | } | 312 | } |
333 | 313 | ||
diff --git a/crates/ra_ide/src/runnables.rs b/crates/ra_ide/src/runnables.rs index 286d45eee..9239ca61b 100644 --- a/crates/ra_ide/src/runnables.rs +++ b/crates/ra_ide/src/runnables.rs | |||
@@ -1,19 +1,19 @@ | |||
1 | use std::fmt; | ||
2 | |||
1 | use hir::{AsAssocItem, Attrs, HirFileId, InFile, Semantics}; | 3 | use hir::{AsAssocItem, Attrs, HirFileId, InFile, Semantics}; |
2 | use itertools::Itertools; | 4 | use itertools::Itertools; |
5 | use ra_cfg::CfgExpr; | ||
3 | use ra_ide_db::RootDatabase; | 6 | use ra_ide_db::RootDatabase; |
4 | use ra_syntax::{ | 7 | use ra_syntax::{ |
5 | ast::{self, AstNode, AttrsOwner, ModuleItemOwner, NameOwner}, | 8 | ast::{self, AstNode, AttrsOwner, DocCommentsOwner, ModuleItemOwner, NameOwner}, |
6 | match_ast, SyntaxNode, TextRange, | 9 | match_ast, SyntaxNode, |
7 | }; | 10 | }; |
8 | 11 | ||
9 | use crate::FileId; | 12 | use crate::{display::ToNav, FileId, NavigationTarget}; |
10 | use ast::DocCommentsOwner; | ||
11 | use ra_cfg::CfgExpr; | ||
12 | use std::fmt::Display; | ||
13 | 13 | ||
14 | #[derive(Debug)] | 14 | #[derive(Debug)] |
15 | pub struct Runnable { | 15 | pub struct Runnable { |
16 | pub range: TextRange, | 16 | pub nav: NavigationTarget, |
17 | pub kind: RunnableKind, | 17 | pub kind: RunnableKind, |
18 | pub cfg_exprs: Vec<CfgExpr>, | 18 | pub cfg_exprs: Vec<CfgExpr>, |
19 | } | 19 | } |
@@ -24,8 +24,8 @@ pub enum TestId { | |||
24 | Path(String), | 24 | Path(String), |
25 | } | 25 | } |
26 | 26 | ||
27 | impl Display for TestId { | 27 | impl fmt::Display for TestId { |
28 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | 28 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
29 | match self { | 29 | match self { |
30 | TestId::Name(name) => write!(f, "{}", name), | 30 | TestId::Name(name) => write!(f, "{}", name), |
31 | TestId::Path(path) => write!(f, "{}", path), | 31 | TestId::Path(path) => write!(f, "{}", path), |
@@ -131,7 +131,8 @@ fn runnable_fn( | |||
131 | let cfg_exprs = | 131 | let cfg_exprs = |
132 | attrs.by_key("cfg").tt_values().map(|subtree| ra_cfg::parse_cfg(subtree)).collect(); | 132 | attrs.by_key("cfg").tt_values().map(|subtree| ra_cfg::parse_cfg(subtree)).collect(); |
133 | 133 | ||
134 | Some(Runnable { range: fn_def.syntax().text_range(), kind, cfg_exprs }) | 134 | let nav = NavigationTarget::from_named(sema.db, InFile::new(file_id.into(), &fn_def)); |
135 | Some(Runnable { nav, kind, cfg_exprs }) | ||
135 | } | 136 | } |
136 | 137 | ||
137 | #[derive(Debug)] | 138 | #[derive(Debug)] |
@@ -183,7 +184,6 @@ fn runnable_mod( | |||
183 | if !has_test_function { | 184 | if !has_test_function { |
184 | return None; | 185 | return None; |
185 | } | 186 | } |
186 | let range = module.syntax().text_range(); | ||
187 | let module_def = sema.to_def(&module)?; | 187 | let module_def = sema.to_def(&module)?; |
188 | 188 | ||
189 | let path = module_def | 189 | let path = module_def |
@@ -197,7 +197,8 @@ fn runnable_mod( | |||
197 | let cfg_exprs = | 197 | let cfg_exprs = |
198 | attrs.by_key("cfg").tt_values().map(|subtree| ra_cfg::parse_cfg(subtree)).collect(); | 198 | attrs.by_key("cfg").tt_values().map(|subtree| ra_cfg::parse_cfg(subtree)).collect(); |
199 | 199 | ||
200 | Some(Runnable { range, kind: RunnableKind::TestMod { path }, cfg_exprs }) | 200 | let nav = module_def.to_nav(sema.db); |
201 | Some(Runnable { nav, kind: RunnableKind::TestMod { path }, cfg_exprs }) | ||
201 | } | 202 | } |
202 | 203 | ||
203 | #[cfg(test)] | 204 | #[cfg(test)] |
diff --git a/crates/rust-analyzer/src/lsp_ext.rs b/crates/rust-analyzer/src/lsp_ext.rs index 173c23b9e..9381f75d3 100644 --- a/crates/rust-analyzer/src/lsp_ext.rs +++ b/crates/rust-analyzer/src/lsp_ext.rs | |||
@@ -4,7 +4,6 @@ use std::{collections::HashMap, path::PathBuf}; | |||
4 | 4 | ||
5 | use lsp_types::request::Request; | 5 | use lsp_types::request::Request; |
6 | use lsp_types::{Position, Range, TextDocumentIdentifier}; | 6 | use lsp_types::{Position, Range, TextDocumentIdentifier}; |
7 | use rustc_hash::FxHashMap; | ||
8 | use serde::{Deserialize, Serialize}; | 7 | use serde::{Deserialize, Serialize}; |
9 | 8 | ||
10 | pub enum AnalyzerStatus {} | 9 | pub enum AnalyzerStatus {} |
@@ -121,25 +120,30 @@ pub struct RunnablesParams { | |||
121 | pub position: Option<Position>, | 120 | pub position: Option<Position>, |
122 | } | 121 | } |
123 | 122 | ||
124 | // Must strictly correspond to the executable name | 123 | #[derive(Deserialize, Serialize, Debug)] |
124 | #[serde(rename_all = "camelCase")] | ||
125 | pub struct Runnable { | ||
126 | pub label: String, | ||
127 | #[serde(skip_serializing_if = "Option::is_none")] | ||
128 | pub location: Option<lsp_types::LocationLink>, | ||
129 | pub kind: RunnableKind, | ||
130 | pub args: CargoRunnable, | ||
131 | } | ||
132 | |||
125 | #[derive(Serialize, Deserialize, Debug)] | 133 | #[derive(Serialize, Deserialize, Debug)] |
126 | #[serde(rename_all = "lowercase")] | 134 | #[serde(rename_all = "lowercase")] |
127 | pub enum RunnableKind { | 135 | pub enum RunnableKind { |
128 | Cargo, | 136 | Cargo, |
129 | Rustc, | ||
130 | Rustup, | ||
131 | } | 137 | } |
132 | 138 | ||
133 | #[derive(Deserialize, Serialize, Debug)] | 139 | #[derive(Deserialize, Serialize, Debug)] |
134 | #[serde(rename_all = "camelCase")] | 140 | #[serde(rename_all = "camelCase")] |
135 | pub struct Runnable { | 141 | pub struct CargoRunnable { |
136 | pub range: Range, | 142 | pub workspace_root: Option<PathBuf>, |
137 | pub label: String, | 143 | // command, --package and --lib stuff |
138 | pub kind: RunnableKind, | 144 | pub cargo_args: Vec<String>, |
139 | pub args: Vec<String>, | 145 | // stuff after -- |
140 | pub extra_args: Vec<String>, | 146 | pub executable_args: Vec<String>, |
141 | pub env: FxHashMap<String, String>, | ||
142 | pub cwd: Option<PathBuf>, | ||
143 | } | 147 | } |
144 | 148 | ||
145 | pub enum InlayHints {} | 149 | pub enum InlayHints {} |
diff --git a/crates/rust-analyzer/src/main_loop/handlers.rs b/crates/rust-analyzer/src/main_loop/handlers.rs index 410c654ab..7fd691764 100644 --- a/crates/rust-analyzer/src/main_loop/handlers.rs +++ b/crates/rust-analyzer/src/main_loop/handlers.rs | |||
@@ -23,7 +23,6 @@ use ra_ide::{ | |||
23 | use ra_prof::profile; | 23 | use ra_prof::profile; |
24 | use ra_project_model::TargetKind; | 24 | use ra_project_model::TargetKind; |
25 | use ra_syntax::{AstNode, SyntaxKind, TextRange, TextSize}; | 25 | use ra_syntax::{AstNode, SyntaxKind, TextRange, TextSize}; |
26 | use rustc_hash::FxHashMap; | ||
27 | use serde::{Deserialize, Serialize}; | 26 | use serde::{Deserialize, Serialize}; |
28 | use serde_json::to_value; | 27 | use serde_json::to_value; |
29 | use stdx::format_to; | 28 | use stdx::format_to; |
@@ -401,7 +400,7 @@ pub fn handle_runnables( | |||
401 | let cargo_spec = CargoTargetSpec::for_file(&world, file_id)?; | 400 | let cargo_spec = CargoTargetSpec::for_file(&world, file_id)?; |
402 | for runnable in world.analysis().runnables(file_id)? { | 401 | for runnable in world.analysis().runnables(file_id)? { |
403 | if let Some(offset) = offset { | 402 | if let Some(offset) = offset { |
404 | if !runnable.range.contains_inclusive(offset) { | 403 | if !runnable.nav.full_range().contains_inclusive(offset) { |
405 | continue; | 404 | continue; |
406 | } | 405 | } |
407 | } | 406 | } |
@@ -422,25 +421,31 @@ pub fn handle_runnables( | |||
422 | Some(spec) => { | 421 | Some(spec) => { |
423 | for &cmd in ["check", "test"].iter() { | 422 | for &cmd in ["check", "test"].iter() { |
424 | res.push(lsp_ext::Runnable { | 423 | res.push(lsp_ext::Runnable { |
425 | range: Default::default(), | ||
426 | label: format!("cargo {} -p {}", cmd, spec.package), | 424 | label: format!("cargo {} -p {}", cmd, spec.package), |
425 | location: None, | ||
427 | kind: lsp_ext::RunnableKind::Cargo, | 426 | kind: lsp_ext::RunnableKind::Cargo, |
428 | args: vec![cmd.to_string(), "--package".to_string(), spec.package.clone()], | 427 | args: lsp_ext::CargoRunnable { |
429 | extra_args: Vec::new(), | 428 | workspace_root: workspace_root.map(|root| root.to_owned()), |
430 | env: FxHashMap::default(), | 429 | cargo_args: vec![ |
431 | cwd: workspace_root.map(|root| root.to_owned()), | 430 | cmd.to_string(), |
431 | "--package".to_string(), | ||
432 | spec.package.clone(), | ||
433 | ], | ||
434 | executable_args: Vec::new(), | ||
435 | }, | ||
432 | }) | 436 | }) |
433 | } | 437 | } |
434 | } | 438 | } |
435 | None => { | 439 | None => { |
436 | res.push(lsp_ext::Runnable { | 440 | res.push(lsp_ext::Runnable { |
437 | range: Default::default(), | ||
438 | label: "cargo check --workspace".to_string(), | 441 | label: "cargo check --workspace".to_string(), |
442 | location: None, | ||
439 | kind: lsp_ext::RunnableKind::Cargo, | 443 | kind: lsp_ext::RunnableKind::Cargo, |
440 | args: vec!["check".to_string(), "--workspace".to_string()], | 444 | args: lsp_ext::CargoRunnable { |
441 | extra_args: Vec::new(), | 445 | workspace_root: workspace_root.map(|root| root.to_owned()), |
442 | env: FxHashMap::default(), | 446 | cargo_args: vec!["check".to_string(), "--workspace".to_string()], |
443 | cwd: workspace_root.map(|root| root.to_owned()), | 447 | executable_args: Vec::new(), |
448 | }, | ||
444 | }); | 449 | }); |
445 | } | 450 | } |
446 | } | 451 | } |
@@ -782,10 +787,11 @@ pub fn handle_code_lens( | |||
782 | } | 787 | } |
783 | }; | 788 | }; |
784 | 789 | ||
785 | let mut r = to_proto::runnable(&world, file_id, runnable)?; | 790 | let range = to_proto::range(&line_index, runnable.nav.range()); |
791 | let r = to_proto::runnable(&world, file_id, runnable)?; | ||
786 | if world.config.lens.run { | 792 | if world.config.lens.run { |
787 | let lens = CodeLens { | 793 | let lens = CodeLens { |
788 | range: r.range, | 794 | range, |
789 | command: Some(Command { | 795 | command: Some(Command { |
790 | title: run_title.to_string(), | 796 | title: run_title.to_string(), |
791 | command: "rust-analyzer.runSingle".into(), | 797 | command: "rust-analyzer.runSingle".into(), |
@@ -797,13 +803,8 @@ pub fn handle_code_lens( | |||
797 | } | 803 | } |
798 | 804 | ||
799 | if debugee && world.config.lens.debug { | 805 | if debugee && world.config.lens.debug { |
800 | if r.args[0] == "run" { | ||
801 | r.args[0] = "build".into(); | ||
802 | } else { | ||
803 | r.args.push("--no-run".into()); | ||
804 | } | ||
805 | let debug_lens = CodeLens { | 806 | let debug_lens = CodeLens { |
806 | range: r.range, | 807 | range, |
807 | command: Some(Command { | 808 | command: Some(Command { |
808 | title: "Debug".into(), | 809 | title: "Debug".into(), |
809 | command: "rust-analyzer.debugSingle".into(), | 810 | command: "rust-analyzer.debugSingle".into(), |
diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs index 66144fe24..85304aa87 100644 --- a/crates/rust-analyzer/src/to_proto.rs +++ b/crates/rust-analyzer/src/to_proto.rs | |||
@@ -8,7 +8,6 @@ use ra_ide::{ | |||
8 | }; | 8 | }; |
9 | use ra_syntax::{SyntaxKind, TextRange, TextSize}; | 9 | use ra_syntax::{SyntaxKind, TextRange, TextSize}; |
10 | use ra_vfs::LineEndings; | 10 | use ra_vfs::LineEndings; |
11 | use rustc_hash::FxHashMap; | ||
12 | 11 | ||
13 | use crate::{ | 12 | use crate::{ |
14 | cargo_target_spec::CargoTargetSpec, lsp_ext, semantic_tokens, world::WorldSnapshot, Result, | 13 | cargo_target_spec::CargoTargetSpec, lsp_ext, semantic_tokens, world::WorldSnapshot, Result, |
@@ -638,9 +637,8 @@ pub(crate) fn runnable( | |||
638 | ) -> Result<lsp_ext::Runnable> { | 637 | ) -> Result<lsp_ext::Runnable> { |
639 | let spec = CargoTargetSpec::for_file(world, file_id)?; | 638 | let spec = CargoTargetSpec::for_file(world, file_id)?; |
640 | let target = spec.as_ref().map(|s| s.target.clone()); | 639 | let target = spec.as_ref().map(|s| s.target.clone()); |
641 | let (args, extra_args) = | 640 | let (cargo_args, executable_args) = |
642 | CargoTargetSpec::runnable_args(spec, &runnable.kind, &runnable.cfg_exprs)?; | 641 | CargoTargetSpec::runnable_args(spec, &runnable.kind, &runnable.cfg_exprs)?; |
643 | let line_index = world.analysis().file_line_index(file_id)?; | ||
644 | let label = match &runnable.kind { | 642 | let label = match &runnable.kind { |
645 | RunnableKind::Test { test_id, .. } => format!("test {}", test_id), | 643 | RunnableKind::Test { test_id, .. } => format!("test {}", test_id), |
646 | RunnableKind::TestMod { path } => format!("test-mod {}", path), | 644 | RunnableKind::TestMod { path } => format!("test-mod {}", path), |
@@ -650,18 +648,16 @@ pub(crate) fn runnable( | |||
650 | target.map_or_else(|| "run binary".to_string(), |t| format!("run {}", t)) | 648 | target.map_or_else(|| "run binary".to_string(), |t| format!("run {}", t)) |
651 | } | 649 | } |
652 | }; | 650 | }; |
651 | let location = location_link(world, None, runnable.nav)?; | ||
653 | 652 | ||
654 | Ok(lsp_ext::Runnable { | 653 | Ok(lsp_ext::Runnable { |
655 | range: range(&line_index, runnable.range), | ||
656 | label, | 654 | label, |
655 | location: Some(location), | ||
657 | kind: lsp_ext::RunnableKind::Cargo, | 656 | kind: lsp_ext::RunnableKind::Cargo, |
658 | args, | 657 | args: lsp_ext::CargoRunnable { |
659 | extra_args, | 658 | workspace_root: world.workspace_root_for(file_id).map(|root| root.to_owned()), |
660 | env: { | 659 | cargo_args, |
661 | let mut m = FxHashMap::default(); | 660 | executable_args, |
662 | m.insert("RUST_BACKTRACE".to_string(), "short".to_string()); | ||
663 | m | ||
664 | }, | 661 | }, |
665 | cwd: world.workspace_root_for(file_id).map(|root| root.to_owned()), | ||
666 | }) | 662 | }) |
667 | } | 663 | } |
diff --git a/editors/code/src/debug.ts b/editors/code/src/debug.ts index 1e421d407..a0c9b3ab2 100644 --- a/editors/code/src/debug.ts +++ b/editors/code/src/debug.ts | |||
@@ -114,8 +114,8 @@ async function getDebugConfiguration(ctx: Ctx, runnable: ra.Runnable): Promise<v | |||
114 | } | 114 | } |
115 | 115 | ||
116 | async function getDebugExecutable(runnable: ra.Runnable): Promise<string> { | 116 | async function getDebugExecutable(runnable: ra.Runnable): Promise<string> { |
117 | const cargo = new Cargo(runnable.cwd || '.', debugOutput); | 117 | const cargo = new Cargo(runnable.args.workspaceRoot || '.', debugOutput); |
118 | const executable = await cargo.executableFromArgs(runnable.args); | 118 | const executable = await cargo.executableFromArgs(runnable.args.cargoArgs); |
119 | 119 | ||
120 | // if we are here, there were no compilation errors. | 120 | // if we are here, there were no compilation errors. |
121 | return executable; | 121 | return executable; |
@@ -127,8 +127,8 @@ function getLldbDebugConfig(runnable: ra.Runnable, executable: string, sourceFil | |||
127 | request: "launch", | 127 | request: "launch", |
128 | name: runnable.label, | 128 | name: runnable.label, |
129 | program: executable, | 129 | program: executable, |
130 | args: runnable.extraArgs, | 130 | args: runnable.args.executableArgs, |
131 | cwd: runnable.cwd, | 131 | cwd: runnable.args.workspaceRoot, |
132 | sourceMap: sourceFileMap, | 132 | sourceMap: sourceFileMap, |
133 | sourceLanguages: ["rust"] | 133 | sourceLanguages: ["rust"] |
134 | }; | 134 | }; |
@@ -140,8 +140,8 @@ function getCppvsDebugConfig(runnable: ra.Runnable, executable: string, sourceFi | |||
140 | request: "launch", | 140 | request: "launch", |
141 | name: runnable.label, | 141 | name: runnable.label, |
142 | program: executable, | 142 | program: executable, |
143 | args: runnable.extraArgs, | 143 | args: runnable.args.executableArgs, |
144 | cwd: runnable.cwd, | 144 | cwd: runnable.args.workspaceRoot, |
145 | sourceFileMap: sourceFileMap, | 145 | sourceFileMap: sourceFileMap, |
146 | }; | 146 | }; |
147 | } | 147 | } |
diff --git a/editors/code/src/lsp_ext.ts b/editors/code/src/lsp_ext.ts index 3e0b60699..73d573678 100644 --- a/editors/code/src/lsp_ext.ts +++ b/editors/code/src/lsp_ext.ts | |||
@@ -46,16 +46,15 @@ export interface RunnablesParams { | |||
46 | position: lc.Position | null; | 46 | position: lc.Position | null; |
47 | } | 47 | } |
48 | 48 | ||
49 | export type RunnableKind = "cargo" | "rustc" | "rustup"; | ||
50 | |||
51 | export interface Runnable { | 49 | export interface Runnable { |
52 | range: lc.Range; | ||
53 | label: string; | 50 | label: string; |
54 | kind: RunnableKind; | 51 | location?: lc.LocationLink; |
55 | args: string[]; | 52 | kind: "cargo"; |
56 | extraArgs: string[]; | 53 | args: { |
57 | env: { [key: string]: string }; | 54 | workspaceRoot?: string; |
58 | cwd: string | null; | 55 | cargoArgs: string[]; |
56 | executableArgs: string[]; | ||
57 | }; | ||
59 | } | 58 | } |
60 | export const runnables = new lc.RequestType<RunnablesParams, Runnable[], void>("rust-analyzer/runnables"); | 59 | export const runnables = new lc.RequestType<RunnablesParams, Runnable[], void>("rust-analyzer/runnables"); |
61 | 60 | ||
diff --git a/editors/code/src/run.ts b/editors/code/src/run.ts index 5fc4f8e41..5c790741f 100644 --- a/editors/code/src/run.ts +++ b/editors/code/src/run.ts | |||
@@ -103,18 +103,27 @@ interface CargoTaskDefinition extends vscode.TaskDefinition { | |||
103 | env?: { [key: string]: string }; | 103 | env?: { [key: string]: string }; |
104 | } | 104 | } |
105 | 105 | ||
106 | export function createTask(spec: ra.Runnable): vscode.Task { | 106 | export function createTask(runnable: ra.Runnable): vscode.Task { |
107 | const TASK_SOURCE = 'Rust'; | 107 | const TASK_SOURCE = 'Rust'; |
108 | |||
109 | let command; | ||
110 | switch (runnable.kind) { | ||
111 | case "cargo": command = toolchain.getPathForExecutable("cargo"); | ||
112 | } | ||
113 | const args = runnable.args.cargoArgs; | ||
114 | if (runnable.args.executableArgs.length > 0) { | ||
115 | args.push('--', ...runnable.args.executableArgs); | ||
116 | } | ||
108 | const definition: CargoTaskDefinition = { | 117 | const definition: CargoTaskDefinition = { |
109 | type: 'cargo', | 118 | type: 'cargo', |
110 | label: spec.label, | 119 | label: runnable.label, |
111 | command: toolchain.getPathForExecutable(spec.kind), | 120 | command, |
112 | args: spec.extraArgs ? [...spec.args, '--', ...spec.extraArgs] : spec.args, | 121 | args, |
113 | env: Object.assign({}, process.env, spec.env), | 122 | env: Object.assign({}, process.env as { [key: string]: string }, { "RUST_BACKTRACE": "short" }), |
114 | }; | 123 | }; |
115 | 124 | ||
116 | const execOption: vscode.ShellExecutionOptions = { | 125 | const execOption: vscode.ShellExecutionOptions = { |
117 | cwd: spec.cwd || '.', | 126 | cwd: runnable.args.workspaceRoot || '.', |
118 | env: definition.env, | 127 | env: definition.env, |
119 | }; | 128 | }; |
120 | const exec = new vscode.ShellExecution( | 129 | const exec = new vscode.ShellExecution( |