aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide/src/runnables.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_ide/src/runnables.rs')
-rw-r--r--crates/ra_ide/src/runnables.rs261
1 files changed, 233 insertions, 28 deletions
diff --git a/crates/ra_ide/src/runnables.rs b/crates/ra_ide/src/runnables.rs
index 6e7e47199..f32ce0d22 100644
--- a/crates/ra_ide/src/runnables.rs
+++ b/crates/ra_ide/src/runnables.rs
@@ -1,21 +1,19 @@
1//! FIXME: write short doc here 1use std::fmt;
2 2
3use hir::{AsAssocItem, Attrs, HirFileId, InFile, Semantics}; 3use hir::{AsAssocItem, Attrs, HirFileId, InFile, Semantics};
4use itertools::Itertools; 4use itertools::Itertools;
5use ra_cfg::CfgExpr;
5use ra_ide_db::RootDatabase; 6use ra_ide_db::RootDatabase;
6use ra_syntax::{ 7use ra_syntax::{
7 ast::{self, AstNode, AttrsOwner, ModuleItemOwner, NameOwner}, 8 ast::{self, AstNode, AttrsOwner, DocCommentsOwner, ModuleItemOwner, NameOwner},
8 match_ast, SyntaxNode, TextRange, 9 match_ast, SyntaxNode,
9}; 10};
10 11
11use crate::FileId; 12use crate::{display::ToNav, FileId, NavigationTarget};
12use ast::DocCommentsOwner;
13use ra_cfg::CfgExpr;
14use std::fmt::Display;
15 13
16#[derive(Debug)] 14#[derive(Debug)]
17pub struct Runnable { 15pub struct Runnable {
18 pub range: TextRange, 16 pub nav: NavigationTarget,
19 pub kind: RunnableKind, 17 pub kind: RunnableKind,
20 pub cfg_exprs: Vec<CfgExpr>, 18 pub cfg_exprs: Vec<CfgExpr>,
21} 19}
@@ -26,8 +24,8 @@ pub enum TestId {
26 Path(String), 24 Path(String),
27} 25}
28 26
29impl Display for TestId { 27impl fmt::Display for TestId {
30 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 28 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
31 match self { 29 match self {
32 TestId::Name(name) => write!(f, "{}", name), 30 TestId::Name(name) => write!(f, "{}", name),
33 TestId::Path(path) => write!(f, "{}", path), 31 TestId::Path(path) => write!(f, "{}", path),
@@ -44,6 +42,17 @@ pub enum RunnableKind {
44 Bin, 42 Bin,
45} 43}
46 44
45// Feature: Run
46//
47// Shows a popup suggesting to run a test/benchmark/binary **at the current cursor
48// location**. Super useful for repeatedly running just a single test. Do bind this
49// to a shortcut!
50//
51// |===
52// | Editor | Action Name
53//
54// | VS Code | **Rust Analyzer: Run**
55// |===
47pub(crate) fn runnables(db: &RootDatabase, file_id: FileId) -> Vec<Runnable> { 56pub(crate) fn runnables(db: &RootDatabase, file_id: FileId) -> Vec<Runnable> {
48 let sema = Semantics::new(db); 57 let sema = Semantics::new(db);
49 let source_file = sema.parse(file_id); 58 let source_file = sema.parse(file_id);
@@ -122,7 +131,8 @@ fn runnable_fn(
122 let cfg_exprs = 131 let cfg_exprs =
123 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();
124 133
125 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 })
126} 136}
127 137
128#[derive(Debug)] 138#[derive(Debug)]
@@ -174,7 +184,6 @@ fn runnable_mod(
174 if !has_test_function { 184 if !has_test_function {
175 return None; 185 return None;
176 } 186 }
177 let range = module.syntax().text_range();
178 let module_def = sema.to_def(&module)?; 187 let module_def = sema.to_def(&module)?;
179 188
180 let path = module_def 189 let path = module_def
@@ -188,7 +197,8 @@ fn runnable_mod(
188 let cfg_exprs = 197 let cfg_exprs =
189 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();
190 199
191 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 })
192} 202}
193 203
194#[cfg(test)] 204#[cfg(test)]
@@ -218,12 +228,38 @@ mod tests {
218 @r###" 228 @r###"
219 [ 229 [
220 Runnable { 230 Runnable {
221 range: 1..21, 231 nav: NavigationTarget {
232 file_id: FileId(
233 1,
234 ),
235 full_range: 1..21,
236 name: "main",
237 kind: FN_DEF,
238 focus_range: Some(
239 12..16,
240 ),
241 container_name: None,
242 description: None,
243 docs: None,
244 },
222 kind: Bin, 245 kind: Bin,
223 cfg_exprs: [], 246 cfg_exprs: [],
224 }, 247 },
225 Runnable { 248 Runnable {
226 range: 22..46, 249 nav: NavigationTarget {
250 file_id: FileId(
251 1,
252 ),
253 full_range: 22..46,
254 name: "test_foo",
255 kind: FN_DEF,
256 focus_range: Some(
257 33..41,
258 ),
259 container_name: None,
260 description: None,
261 docs: None,
262 },
227 kind: Test { 263 kind: Test {
228 test_id: Path( 264 test_id: Path(
229 "test_foo", 265 "test_foo",
@@ -235,7 +271,20 @@ mod tests {
235 cfg_exprs: [], 271 cfg_exprs: [],
236 }, 272 },
237 Runnable { 273 Runnable {
238 range: 47..81, 274 nav: NavigationTarget {
275 file_id: FileId(
276 1,
277 ),
278 full_range: 47..81,
279 name: "test_foo",
280 kind: FN_DEF,
281 focus_range: Some(
282 68..76,
283 ),
284 container_name: None,
285 description: None,
286 docs: None,
287 },
239 kind: Test { 288 kind: Test {
240 test_id: Path( 289 test_id: Path(
241 "test_foo", 290 "test_foo",
@@ -270,12 +319,38 @@ mod tests {
270 @r###" 319 @r###"
271 [ 320 [
272 Runnable { 321 Runnable {
273 range: 1..21, 322 nav: NavigationTarget {
323 file_id: FileId(
324 1,
325 ),
326 full_range: 1..21,
327 name: "main",
328 kind: FN_DEF,
329 focus_range: Some(
330 12..16,
331 ),
332 container_name: None,
333 description: None,
334 docs: None,
335 },
274 kind: Bin, 336 kind: Bin,
275 cfg_exprs: [], 337 cfg_exprs: [],
276 }, 338 },
277 Runnable { 339 Runnable {
278 range: 22..64, 340 nav: NavigationTarget {
341 file_id: FileId(
342 1,
343 ),
344 full_range: 22..64,
345 name: "foo",
346 kind: FN_DEF,
347 focus_range: Some(
348 56..59,
349 ),
350 container_name: None,
351 description: None,
352 docs: None,
353 },
279 kind: DocTest { 354 kind: DocTest {
280 test_id: Path( 355 test_id: Path(
281 "foo", 356 "foo",
@@ -310,12 +385,38 @@ mod tests {
310 @r###" 385 @r###"
311 [ 386 [
312 Runnable { 387 Runnable {
313 range: 1..21, 388 nav: NavigationTarget {
389 file_id: FileId(
390 1,
391 ),
392 full_range: 1..21,
393 name: "main",
394 kind: FN_DEF,
395 focus_range: Some(
396 12..16,
397 ),
398 container_name: None,
399 description: None,
400 docs: None,
401 },
314 kind: Bin, 402 kind: Bin,
315 cfg_exprs: [], 403 cfg_exprs: [],
316 }, 404 },
317 Runnable { 405 Runnable {
318 range: 51..105, 406 nav: NavigationTarget {
407 file_id: FileId(
408 1,
409 ),
410 full_range: 51..105,
411 name: "foo",
412 kind: FN_DEF,
413 focus_range: Some(
414 97..100,
415 ),
416 container_name: None,
417 description: None,
418 docs: None,
419 },
319 kind: DocTest { 420 kind: DocTest {
320 test_id: Path( 421 test_id: Path(
321 "Data::foo", 422 "Data::foo",
@@ -345,14 +446,40 @@ mod tests {
345 @r###" 446 @r###"
346 [ 447 [
347 Runnable { 448 Runnable {
348 range: 1..59, 449 nav: NavigationTarget {
450 file_id: FileId(
451 1,
452 ),
453 full_range: 1..59,
454 name: "test_mod",
455 kind: MODULE,
456 focus_range: Some(
457 13..21,
458 ),
459 container_name: None,
460 description: None,
461 docs: None,
462 },
349 kind: TestMod { 463 kind: TestMod {
350 path: "test_mod", 464 path: "test_mod",
351 }, 465 },
352 cfg_exprs: [], 466 cfg_exprs: [],
353 }, 467 },
354 Runnable { 468 Runnable {
355 range: 28..57, 469 nav: NavigationTarget {
470 file_id: FileId(
471 1,
472 ),
473 full_range: 28..57,
474 name: "test_foo1",
475 kind: FN_DEF,
476 focus_range: Some(
477 43..52,
478 ),
479 container_name: None,
480 description: None,
481 docs: None,
482 },
356 kind: Test { 483 kind: Test {
357 test_id: Path( 484 test_id: Path(
358 "test_mod::test_foo1", 485 "test_mod::test_foo1",
@@ -387,14 +514,40 @@ mod tests {
387 @r###" 514 @r###"
388 [ 515 [
389 Runnable { 516 Runnable {
390 range: 23..85, 517 nav: NavigationTarget {
518 file_id: FileId(
519 1,
520 ),
521 full_range: 23..85,
522 name: "test_mod",
523 kind: MODULE,
524 focus_range: Some(
525 27..35,
526 ),
527 container_name: None,
528 description: None,
529 docs: None,
530 },
391 kind: TestMod { 531 kind: TestMod {
392 path: "foo::test_mod", 532 path: "foo::test_mod",
393 }, 533 },
394 cfg_exprs: [], 534 cfg_exprs: [],
395 }, 535 },
396 Runnable { 536 Runnable {
397 range: 46..79, 537 nav: NavigationTarget {
538 file_id: FileId(
539 1,
540 ),
541 full_range: 46..79,
542 name: "test_foo1",
543 kind: FN_DEF,
544 focus_range: Some(
545 65..74,
546 ),
547 container_name: None,
548 description: None,
549 docs: None,
550 },
398 kind: Test { 551 kind: Test {
399 test_id: Path( 552 test_id: Path(
400 "foo::test_mod::test_foo1", 553 "foo::test_mod::test_foo1",
@@ -431,14 +584,40 @@ mod tests {
431 @r###" 584 @r###"
432 [ 585 [
433 Runnable { 586 Runnable {
434 range: 41..115, 587 nav: NavigationTarget {
588 file_id: FileId(
589 1,
590 ),
591 full_range: 41..115,
592 name: "test_mod",
593 kind: MODULE,
594 focus_range: Some(
595 45..53,
596 ),
597 container_name: None,
598 description: None,
599 docs: None,
600 },
435 kind: TestMod { 601 kind: TestMod {
436 path: "foo::bar::test_mod", 602 path: "foo::bar::test_mod",
437 }, 603 },
438 cfg_exprs: [], 604 cfg_exprs: [],
439 }, 605 },
440 Runnable { 606 Runnable {
441 range: 68..105, 607 nav: NavigationTarget {
608 file_id: FileId(
609 1,
610 ),
611 full_range: 68..105,
612 name: "test_foo1",
613 kind: FN_DEF,
614 focus_range: Some(
615 91..100,
616 ),
617 container_name: None,
618 description: None,
619 docs: None,
620 },
442 kind: Test { 621 kind: Test {
443 test_id: Path( 622 test_id: Path(
444 "foo::bar::test_mod::test_foo1", 623 "foo::bar::test_mod::test_foo1",
@@ -470,7 +649,20 @@ mod tests {
470 @r###" 649 @r###"
471 [ 650 [
472 Runnable { 651 Runnable {
473 range: 1..58, 652 nav: NavigationTarget {
653 file_id: FileId(
654 1,
655 ),
656 full_range: 1..58,
657 name: "test_foo1",
658 kind: FN_DEF,
659 focus_range: Some(
660 44..53,
661 ),
662 container_name: None,
663 description: None,
664 docs: None,
665 },
474 kind: Test { 666 kind: Test {
475 test_id: Path( 667 test_id: Path(
476 "test_foo1", 668 "test_foo1",
@@ -507,7 +699,20 @@ mod tests {
507 @r###" 699 @r###"
508 [ 700 [
509 Runnable { 701 Runnable {
510 range: 1..80, 702 nav: NavigationTarget {
703 file_id: FileId(
704 1,
705 ),
706 full_range: 1..80,
707 name: "test_foo1",
708 kind: FN_DEF,
709 focus_range: Some(
710 66..75,
711 ),
712 container_name: None,
713 description: None,
714 docs: None,
715 },
511 kind: Test { 716 kind: Test {
512 test_id: Path( 717 test_id: Path(
513 "test_foo1", 718 "test_foo1",